Commit 93aba8bc authored by Jan Kadlec's avatar Jan Kadlec

new_node: Bugfixes, storing old and new data in zone_t.

parent ee397755
......@@ -279,7 +279,7 @@ static int zones_process_update_auth(struct query_data *qdata)
sec_chs = knot_changesets_create();
sec_ch = knot_changesets_create_changeset(sec_chs);
if (sec_chs == NULL || sec_ch == NULL) {
xfrin_rollback_update(old_contents, &new_contents);
xfrin_rollback_update(zone, old_contents, &new_contents);
knot_changesets_free(&chgsets);
free(msg);
return KNOT_ENOMEM;
......@@ -311,7 +311,7 @@ static int zones_process_update_auth(struct query_data *qdata)
if (ret != KNOT_EOK) {
log_zone_error("%s: Failed to sign incoming update (%s)"
"\n", msg, knot_strerror(ret));
xfrin_rollback_update(old_contents, &new_contents);
xfrin_rollback_update(zone, old_contents, &new_contents);
knot_changesets_free(&chgsets);
knot_changesets_free(&sec_chs);
free(msg);
......@@ -326,7 +326,7 @@ static int zones_process_update_auth(struct query_data *qdata)
if (ret != KNOT_EOK) {
log_zone_error("%s: Failed to save new entry to journal (%s)\n",
msg, knot_strerror(ret));
xfrin_rollback_update(old_contents, &new_contents);
xfrin_rollback_update(zone, old_contents, &new_contents);
zones_free_merged_changesets(chgsets, sec_chs);
free(msg);
return ret;
......@@ -335,7 +335,7 @@ static int zones_process_update_auth(struct query_data *qdata)
bool new_signatures = !knot_changeset_is_empty(sec_ch);
// Apply DNSSEC changeset
if (new_signatures) {
ret = xfrin_apply_changesets_dnssec_ddns(old_contents,
ret = xfrin_apply_changesets_dnssec_ddns(zone, old_contents,
new_contents,
sec_chs,
chgsets);
......@@ -363,7 +363,7 @@ static int zones_process_update_auth(struct query_data *qdata)
if (ret != KNOT_EOK) {
zones_store_changesets_rollback(transaction);
zones_free_merged_changesets(chgsets, sec_chs);
xfrin_rollback_update(old_contents, &new_contents);
xfrin_rollback_update(zone, old_contents, &new_contents);
free(msg);
return ret;
}
......@@ -375,7 +375,7 @@ static int zones_process_update_auth(struct query_data *qdata)
if (ret != KNOT_EOK) {
log_zone_error("%s: Failed to commit new journal entry "
"(%s).\n", msg, knot_strerror(ret));
xfrin_rollback_update(old_contents, &new_contents);
xfrin_rollback_update(zone, old_contents, &new_contents);
zones_free_merged_changesets(chgsets, sec_chs);
free(msg);
return ret;
......@@ -391,7 +391,7 @@ static int zones_process_update_auth(struct query_data *qdata)
log_zone_error("%s: Failed to replace current zone (%s)\n",
msg, knot_strerror(ret));
// Cleanup old and new contents
xfrin_rollback_update(old_contents, &new_contents);
xfrin_rollback_update(zone, old_contents, &new_contents);
/* Free changesets, but not the data. */
zones_free_merged_changesets(chgsets, sec_chs);
......@@ -401,7 +401,7 @@ static int zones_process_update_auth(struct query_data *qdata)
}
// Cleanup.
xfrin_cleanup_successful_update(old_contents);
xfrin_cleanup_successful_update(zone);
// Free changesets, but not the data.
zones_free_merged_changesets(chgsets, sec_chs);
......
......@@ -1478,7 +1478,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
/* Commit transaction. */
ret = zones_store_changesets_commit(transaction);
if (ret != KNOT_EOK) {
xfrin_rollback_update(zone->contents, new_contents);
xfrin_rollback_update(zone, zone->contents, new_contents);
log_zone_error("%s Failed to commit stored changesets.\n", msgpref);
knot_changesets_free(&chs);
return ret;
......@@ -1494,14 +1494,14 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
if (switch_ret != KNOT_EOK) {
log_zone_error("%s Failed to replace current zone.\n", msgpref);
// Cleanup old and new contents
xfrin_rollback_update(zone->contents, new_contents);
xfrin_rollback_update(zone, zone->contents, new_contents);
/* Free changesets, but not the data. */
knot_changesets_free(&chs);
return KNOT_ERROR;
}
xfrin_cleanup_successful_update(zone->contents);
xfrin_cleanup_successful_update(zone);
/* Free changesets, but not the data. */
knot_changesets_free(&chs);
......@@ -1924,7 +1924,7 @@ int zones_journal_apply(zone_t *zone)
XFR_TYPE_IIN);
rcu_read_lock();
if (apply_ret == KNOT_EOK) {
xfrin_cleanup_successful_update(NULL);
xfrin_cleanup_successful_update(zone);
} else {
log_zone_error("Failed to apply "
"changesets to '%s' - Switch failed: "
......@@ -1933,7 +1933,8 @@ int zones_journal_apply(zone_t *zone)
ret = KNOT_ERROR;
// Cleanup old and new contents
xfrin_rollback_update(zone->contents,
xfrin_rollback_update(zone,
zone->contents,
&contents);
}
}
......@@ -2015,7 +2016,8 @@ static int diff_after_load(zone_t *zone, zone_t *old_zone,
if (*diff_chs != NULL) {
assert(!zones_changesets_empty(*diff_chs));
/* Apply DNSSEC changeset to the new zone. */
ret = xfrin_apply_changesets_directly(zone->contents,
ret = xfrin_apply_changesets_directly(zone,
zone->contents,
*diff_chs);
if (ret == KNOT_EOK) {
......@@ -2033,7 +2035,7 @@ static int diff_after_load(zone_t *zone, zone_t *old_zone,
return ret;
}
xfrin_cleanup_successful_update(NULL);
xfrin_cleanup_successful_update(zone);
knot_changesets_free(diff_chs);
assert(zone->conf->build_diffs);
}
......@@ -2103,7 +2105,7 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone,
if (zone_changed) {
assert(!old_zone ||
old_zone->contents != zone->contents);
ret = xfrin_apply_changesets_directly(zone->contents,
ret = xfrin_apply_changesets_directly(zone, zone->contents,
diff_chs);
if (ret == KNOT_EOK) {
ret = xfrin_finalize_updated_zone(
......@@ -2127,7 +2129,7 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone,
return ret;
}
xfrin_cleanup_successful_update(NULL);
xfrin_cleanup_successful_update(zone);
}
/* Commit transaction. */
......@@ -2156,7 +2158,7 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone,
"switching zone (%s).\n",
zone->conf->name, knot_strerror(ret));
// Cleanup old and new contents
xfrin_rollback_update(zone->contents, &new_contents);
xfrin_rollback_update(zone, zone->contents, &new_contents);
return ret;
}
......
......@@ -433,7 +433,7 @@ static bool skip_record_addition(knot_changeset_t *changeset,
knot_rrset_t *rr)
{
knot_rr_ln_t *rr_node = NULL;
WALK_LIST(rr_node, changeset->remove) {
WALK_LIST(rr_node, changeset->add) {
knot_rrset_t *rrset = rr_node->rr;
if (should_replace(rr, rrset)) {
knot_rrset_free(&rrset, NULL);
......@@ -795,6 +795,11 @@ static int knot_ddns_process_rr(const knot_rrset_t *rr,
}
}
/*
* Check if the record is SOA. If yes, check the SERIAL.
* If this record should cause the SOA to be replaced in the
* zone, use it as the ending SOA.
*/
static bool skip_soa(const knot_rrset_t *rr, int64_t sn)
{
if (rr->type == KNOT_RRTYPE_SOA
......@@ -828,19 +833,11 @@ int knot_ddns_process_update(knot_zone_contents_t *zone,
return KNOT_EINVAL;
}
int ret = KNOT_EOK;
/* Copy base SOA RR. */
knot_rrset_t *soa_begin = knot_node_create_rrset(knot_zone_contents_apex(zone),
knot_rrset_t *soa_begin = knot_node_create_rrset(zone->apex,
KNOT_RRTYPE_SOA);
knot_rrset_t *soa_end = NULL;
if (ret == KNOT_EOK) {
knot_changeset_add_soa(changeset, soa_begin,
KNOT_CHANGESET_REMOVE);
} else {
*rcode = KNOT_RCODE_SERVFAIL;
return ret;
}
knot_changeset_add_soa(changeset, soa_begin, KNOT_CHANGESET_REMOVE);
/* Current SERIAL */
int64_t sn = knot_rrs_soa_serial(&soa_begin->rrs);
......@@ -852,48 +849,39 @@ int knot_ddns_process_update(knot_zone_contents_t *zone,
assert(sn_new != KNOT_EINVAL);
} else {
*rcode = KNOT_RCODE_SERVFAIL;
return ret;
return KNOT_EINVAL;
}
/* Process all RRs the Authority (Update) section. */
const knot_rrset_t *rr = NULL;
dbg_ddns("Processing UPDATE section.\n");
size_t apex_ns_removals = 0;
const knot_pktsection_t *authority = knot_pkt_section(query, KNOT_AUTHORITY);
for (int i = 0; i < authority->count; ++i) {
rr = &authority->rr[i];
for (uint16_t i = 0; i < authority->count; ++i) {
const knot_rrset_t *rr = &authority->rr[i];
/* Check if the entry is correct. */
ret = knot_ddns_check_update(rr, query, rcode);
int ret = knot_ddns_check_update(rr, query, rcode);
if (ret != KNOT_EOK) {
return ret;
}
/* Check if the record is SOA. If yes, check the SERIAL.
* If this record should cause the SOA to be replaced in the
* zone, use it as the ending SOA.
*
* Also handle cases where there are multiple SOAs to be added
* in the same UPDATE. The one with the largest SERIAL should
* be used.
*/
1 == 1; // multiple SOAs test
if (skip_soa(rr, sn)) {
continue;
}
dbg_ddns_verb("Processing RR %p...\n", rr);
ret = knot_ddns_process_rr(rr, zone, changeset, &apex_ns_removals);
if (ret != KNOT_EOK) {
*rcode = ret_to_rcode(ret);
return ret;
}
// we need the RR copy, that's why this code is here
if (rr->type == KNOT_RRTYPE_SOA) {
// Using new SOA that came in the update
if (soa_end == NULL) {
knot_rrset_free(&soa_end, NULL);
}
int64_t sn_rr = knot_rrs_soa_serial(&rr->rrs);
assert(knot_serial_compare(sn_rr, sn) > 0);
sn_new = sn_rr;
......@@ -904,23 +892,20 @@ int knot_ddns_process_update(knot_zone_contents_t *zone,
}
}
/* Ending SOA (not in the UPDATE) */
if (soa_end == NULL) {
// If the changeset is empty, do not process anything further
// No SOA in the update, create according to current policy
if (knot_changeset_is_empty(changeset)) {
// No change, no new SOA
return KNOT_EOK;
}
/* If not set, create new SOA. */
ret = knot_rrset_copy(soa_begin, &soa_end, NULL);
if (ret != KNOT_EOK) {
*rcode = ret_to_rcode(ret);
return ret;
soa_end = knot_rrset_cpy(soa_begin, NULL);
if (soa_end == NULL) {
*rcode = KNOT_RCODE_SERVFAIL;
return KNOT_ENOMEM;
}
knot_rrs_soa_serial_set(&soa_end->rrs, sn_new);
}
ret = knot_ddns_final_soa_to_chgset(soa_end, changeset);
return ret;
return knot_ddns_final_soa_to_chgset(soa_end, changeset);
}
......@@ -628,7 +628,7 @@ void xfrin_zone_contents_free(knot_zone_contents_t **contents)
/*----------------------------------------------------------------------------*/
void xfrin_cleanup_successful_update(knot_zone_contents_t *zone)
void xfrin_cleanup_successful_update(zone_t *zone)
{
if (zone == NULL) {
return;
......@@ -636,6 +636,8 @@ void xfrin_cleanup_successful_update(knot_zone_contents_t *zone)
rrs_list_clear(&zone->old_data, NULL);
ptrlist_free(&zone->new_data, NULL);
init_list(&zone->new_data);
init_list(&zone->old_data);
}
/*----------------------------------------------------------------------------*/
......@@ -729,11 +731,14 @@ static void xfrin_cleanup_failed_update(knot_zone_contents_t *old_contents,
/*----------------------------------------------------------------------------*/
void xfrin_rollback_update(knot_zone_contents_t *old_contents,
void xfrin_rollback_update(zone_t *zone,
knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents)
{
rrs_list_clear(&old_contents->new_data, NULL);
ptrlist_free(&old_contents->old_data, NULL);
rrs_list_clear(&zone->new_data, NULL);
ptrlist_free(&zone->old_data, NULL);
init_list(&zone->new_data);
init_list(&zone->old_data);
xfrin_cleanup_failed_update(old_contents, new_contents);
}
......@@ -937,8 +942,6 @@ static int xfrin_apply_changeset(list_t *old_rrs, list_t *new_rrs,
return KNOT_ERROR;
}
init_list(new_rrs);
init_list(old_rrs);
int ret = xfrin_apply_remove(contents, chset, old_rrs, new_rrs);
if (ret != KNOT_EOK) {
return ret;
......@@ -1160,7 +1163,8 @@ int xfrin_finalize_updated_zone(knot_zone_contents_t *contents_copy,
/*----------------------------------------------------------------------------*/
int xfrin_apply_changesets_directly(knot_zone_contents_t *contents,
int xfrin_apply_changesets_directly(zone_t *zone,
knot_zone_contents_t *contents,
knot_changesets_t *chsets)
{
if (contents == NULL || chsets == NULL) {
......@@ -1169,8 +1173,8 @@ int xfrin_apply_changesets_directly(knot_zone_contents_t *contents,
knot_changeset_t *set = NULL;
WALK_LIST(set, chsets->sets) {
int ret = xfrin_apply_changeset(&contents->old_data,
&contents->new_data,
int ret = xfrin_apply_changeset(&zone->old_data,
&zone->new_data,
contents, set);
if (ret != KNOT_EOK) {
return ret;
......@@ -1183,12 +1187,13 @@ int xfrin_apply_changesets_directly(knot_zone_contents_t *contents,
/*----------------------------------------------------------------------------*/
/* Post-DDNS application, no need to shallow copy. */
int xfrin_apply_changesets_dnssec_ddns(knot_zone_contents_t *z_old,
int xfrin_apply_changesets_dnssec_ddns(zone_t *zone,
knot_zone_contents_t *z_old,
knot_zone_contents_t *z_new,
knot_changesets_t *sec_chsets,
knot_changesets_t *chsets)
{
if (z_old == NULL || z_new == NULL ||
if (zone == NULL || z_old == NULL || z_new == NULL ||
sec_chsets == NULL || chsets == NULL) {
return KNOT_EINVAL;
}
......@@ -1197,10 +1202,10 @@ int xfrin_apply_changesets_dnssec_ddns(knot_zone_contents_t *z_old,
knot_zone_contents_set_gen_old(z_new);
/* Apply changes. */
int ret = xfrin_apply_changesets_directly(z_new,
int ret = xfrin_apply_changesets_directly(zone, z_new,
sec_chsets);
if (ret != KNOT_EOK) {
xfrin_rollback_update(z_old, &z_new);
xfrin_rollback_update(zone, z_old, &z_new);
dbg_xfrin("Failed to apply changesets to zone: "
"%s\n", knot_strerror(ret));
return ret;
......@@ -1211,7 +1216,7 @@ int xfrin_apply_changesets_dnssec_ddns(knot_zone_contents_t *z_old,
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to finalize updated zone: %s\n",
knot_strerror(ret));
xfrin_rollback_update(z_old, &z_new);
xfrin_rollback_update(zone, z_old, &z_new);
return ret;
}
......@@ -1254,12 +1259,12 @@ int xfrin_apply_changesets(zone_t *zone,
old_contents->apex, contents_copy->apex);
knot_changeset_t *set = NULL;
WALK_LIST(set, chsets->sets) {
ret = xfrin_apply_changeset(&zone->contents->old_data,
&zone->contents->new_data,
ret = xfrin_apply_changeset(&zone->old_data,
&zone->new_data,
contents_copy, set);
if (ret != KNOT_EOK) {
xfrin_rollback_update(old_contents,
&contents_copy);
xfrin_rollback_update(zone, old_contents,
&contents_copy);
dbg_xfrin("Failed to apply changesets to zone: "
"%s\n", knot_strerror(ret));
return ret;
......@@ -1276,7 +1281,7 @@ int xfrin_apply_changesets(zone_t *zone,
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to finalize updated zone: %s\n",
knot_strerror(ret));
xfrin_rollback_update(old_contents, &contents_copy);
xfrin_rollback_update(zone, old_contents, &contents_copy);
return ret;
}
......
......@@ -165,7 +165,7 @@ int xfrin_apply_changesets(zone_t *zone,
* by the UPDATE-processing function. It uses new and old zones from this
* operation.
*/
int xfrin_apply_changesets_dnssec_ddns(knot_zone_contents_t *z_old,
int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, knot_zone_contents_t *z_old,
knot_zone_contents_t *z_new,
knot_changesets_t *sec_chsets,
knot_changesets_t *chsets);
......@@ -183,7 +183,7 @@ int xfrin_apply_changesets_dnssec_ddns(knot_zone_contents_t *z_old,
* \retval KNOT_EINVAL if given one of the arguments is NULL.
* \return Other error code if the application went wrong.
*/
int xfrin_apply_changesets_directly(knot_zone_contents_t *contents,
int xfrin_apply_changesets_directly(zone_t *zone, knot_zone_contents_t *contents,
knot_changesets_t *chsets);
int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents,
......@@ -202,7 +202,7 @@ int xfrin_switch_zone(zone_t *zone,
knot_zone_contents_t *new_contents,
int transfer_type);
void xfrin_rollback_update(knot_zone_contents_t *old_contents,
void xfrin_rollback_update(zone_t *zone, knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents);
int xfrin_copy_rrset(knot_node_t *node, uint16_t type,
......@@ -215,7 +215,7 @@ int xfrin_replace_rrset_in_node(knot_node_t *node,
knot_zone_contents_t *contents);
void xfrin_zone_contents_free(knot_zone_contents_t **contents);
void xfrin_cleanup_successful_update(knot_zone_contents_t *zone);
void xfrin_cleanup_successful_update(zone_t *zone);
#endif /* _KNOTXFR_IN_H_ */
......
......@@ -70,8 +70,6 @@ typedef struct knot_zone_contents_t {
* - 0xx - ANY queries enabled
*/
uint8_t flags;
list_t old_data;
list_t new_data;
} knot_zone_contents_t;
/*!< \brief Helper linked list list for CNAME loop checking */
......
......@@ -212,6 +212,9 @@ zone_t* zone_new(conf_zone_t *conf)
}
}
init_list(&zone->old_data);
init_list(&zone->new_data);
return zone;
}
......
......@@ -95,6 +95,8 @@ typedef struct zone_t {
/*! \brief Zone IXFR history. */
journal_t *ixfr_db;
event_t *ixfr_dbsync; /*!< Syncing IXFR db to zonefile. */
list_t old_data;
list_t new_data;
} zone_t;
/*----------------------------------------------------------------------------*/
......
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