Commit 52b02e68 authored by Lubos Slovak's avatar Lubos Slovak

Fixed IXFR/in of signed zone + other small fixes.

- When RRSet for RRSIGs was not found, the previous RRSet was
  used.
- Removed CNAME loop check from zone contents adjusting into
  separate function.
- Fixed some warnings.

fixes #1578
parent f5e76ff0
......@@ -1402,7 +1402,7 @@ static inline int ns_referral(const knot_node_t *node,
/*! \todo Check return value? */
knot_response_add_rrset_authority(
resp, nsec, 1, 1, 0, 1);
if ((nsec = knot_rrset_rrsigs(nsec)) != NULL) {
if ((nsec = knot_rrset_get_rrsigs(nsec)) != NULL) {
knot_response_add_rrset_authority(
resp, nsec, 1, 1, 0, 1);
}
......@@ -3255,7 +3255,16 @@ int knot_ns_process_axfrin(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr)
}
dbg_ns("ns_process_axfrin: adjusting zone.\n");
knot_zone_contents_adjust(zone);
rc = knot_zone_contents_adjust(zone);
if (rc != KNOT_EOK) {
return rc;
}
dbg_ns("ns_process_axfrin: checking loops.\n");
rc = knot_zone_contents_check_loops(zone);
if (rc != KNOT_EOK) {
return rc;
}
// save the zone contents to the xfr->data
xfr->data = zone;
......
......@@ -668,6 +668,7 @@ void knot_rrset_deep_free(knot_rrset_t **rrset, int free_owner,
tmp_rdata = next_rdata;
}
// printf("test: %p\n", tmp_rdata->next->next);
assert(tmp_rdata == NULL
|| tmp_rdata->next == (*rrset)->rdata);
......
......@@ -1990,6 +1990,15 @@ static int xfrin_apply_add_rrsig(xfrin_changes_t *changes,
knot_rr_type_t type = knot_rdata_rrsig_type_covered(
knot_rrset_rdata(add));
dbg_xfrin_exec(
char *name = knot_dname_to_str(knot_node_owner(add));
char *typestr = knot_rrtype_to_string(type);
dbg_xfrin("Adding RRSIG: Owner %s, type covered %s.\n",
name, typestr);
free(name);
free(typestr);
);
if (!*rrset
|| knot_dname_compare(knot_rrset_owner(*rrset),
knot_node_owner(node)) != 0
......@@ -1999,6 +2008,8 @@ static int xfrin_apply_add_rrsig(xfrin_changes_t *changes,
ret = xfrin_copy_rrset(node, type, rrset, changes);
if (ret < 0) {
return ret;
} else if (ret != KNOT_EOK) {
*rrset = NULL;
}
} else {
// we should have the right RRSIG RRSet in *rrset
......@@ -2010,6 +2021,7 @@ static int xfrin_apply_add_rrsig(xfrin_changes_t *changes,
if (*rrset == NULL) {
dbg_xfrin("RRSet to be added not found in zone.\n");
dbg_xfrin("Creating new RRSet for RRSIG.\n");
// create a new RRSet to add the RRSIGs into
*rrset = knot_rrset_new(knot_node_get_owner(node), type,
knot_rrset_class(add),
......@@ -2053,6 +2065,7 @@ dbg_xfrin_exec(
if (knot_rrset_rrsigs(*rrset) == NULL) {
dbg_xfrin("Adding new RRSIGs to RRSet.\n");
ret = knot_zone_contents_add_rrsigs(contents, add, rrset, &node,
KNOT_RRSET_DUPL_SKIP, 1);
......@@ -2079,9 +2092,11 @@ dbg_xfrin_exec(
knot_rrset_set_rrsigs(*rrset, rrsig);
// merge the changeset RRSet to the copy
dbg_xfrin("Merging RRSIG to the one in the RRSet.\n");
ret = knot_rrset_merge((void **)&rrsig, (void **)&add);
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to merge changeset RRSet to copy.\n");
dbg_xfrin("Failed to merge changeset RRSIG to copy: %s"
".\n", knot_strerror(ret));
return KNOT_ERROR;
}
......@@ -3060,6 +3075,14 @@ int xfrin_apply_changesets(knot_zone_t *zone,
}
assert(knot_zone_contents_apex(contents_copy) != NULL);
dbg_xfrin("Checking zone for CNAME loops.\n");
ret = knot_zone_contents_check_loops(contents_copy);
if (ret != KNOT_EOK) {
dbg_xfrin("CNAME loop check failed: %s\n", knot_strerror(ret));
xfrin_rollback_update2(old_contents, contents_copy, &changes);
return ret;
}
dbg_xfrin("Switching zone contents.\n");
dbg_xfrin_verb("Old contents apex: %p, new apex: %p\n",
old_contents->apex, contents_copy->apex);
......
......@@ -489,7 +489,7 @@ void knot_node_set_owner(knot_node_t *node, knot_dname_t* owner)
/*----------------------------------------------------------------------------*/
const knot_node_t *knot_node_wildcard_child(const knot_node_t *node)
knot_node_t *knot_node_get_wildcard_child(const knot_node_t *node)
{
if (node == NULL) {
return NULL;
......@@ -509,6 +509,13 @@ void knot_node_set_wildcard_child(knot_node_t *node,
/*----------------------------------------------------------------------------*/
const knot_node_t *knot_node_wildcard_child(const knot_node_t *node)
{
return knot_node_get_wildcard_child(node);
}
/*----------------------------------------------------------------------------*/
//const knot_node_t *knot_node_current(const knot_node_t *node)
//{
// if (node == NULL || node->zone == NULL
......
......@@ -339,6 +339,8 @@ const knot_node_t *knot_node_wildcard_child(const knot_node_t *node);
void knot_node_set_wildcard_child(knot_node_t *node,
knot_node_t *wildcard_child);
knot_node_t *knot_node_get_wildcard_child(const knot_node_t *node);
//const knot_node_t *knot_node_current(const knot_node_t *node);
//knot_node_t *knot_node_get_current(knot_node_t *node);
......
......@@ -835,7 +835,7 @@ typedef struct cname_chain {
/*----------------------------------------------------------------------------*/
int cname_chain_add(cname_chain_t **last, const knot_node_t *node)
static int cname_chain_add(cname_chain_t **last, const knot_node_t *node)
{
assert(last != NULL);
......@@ -857,7 +857,7 @@ int cname_chain_add(cname_chain_t **last, const knot_node_t *node)
/*----------------------------------------------------------------------------*/
int cname_chain_contains(cname_chain_t *chain, const knot_node_t *node)
static int cname_chain_contains(cname_chain_t *chain, const knot_node_t *node)
{
cname_chain_t *act = chain;
while (act != NULL) {
......@@ -872,7 +872,7 @@ int cname_chain_contains(cname_chain_t *chain, const knot_node_t *node)
/*----------------------------------------------------------------------------*/
void cname_chain_free(cname_chain_t *chain)
static void cname_chain_free(cname_chain_t *chain)
{
cname_chain_t *act = chain;
......@@ -885,6 +885,13 @@ void cname_chain_free(cname_chain_t *chain)
/*----------------------------------------------------------------------------*/
typedef struct loop_check_data {
knot_zone_contents_t *zone;
int err;
} loop_check_data_t;
/*----------------------------------------------------------------------------*/
static void knot_zone_contents_check_loops_in_tree(knot_zone_tree_node_t *tnode,
void *data)
{
......@@ -892,7 +899,7 @@ static void knot_zone_contents_check_loops_in_tree(knot_zone_tree_node_t *tnode,
assert(tnode->node != NULL);
assert(data != NULL);
knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data;
loop_check_data_t *args = (loop_check_data_t *)data;
knot_node_t *node = tnode->node;
assert(args->zone != NULL);
......@@ -923,7 +930,7 @@ static void knot_zone_contents_check_loops_in_tree(knot_zone_tree_node_t *tnode,
const knot_dname_t *next_name = knot_rdata_cname_name(
knot_rrset_rdata(cname));
assert(next_name != NULL);
const knot_node_t *next_node = knot_dname_node(next_name);
const knot_node_t *next_node = knot_dname_get_node(next_name);
if (next_node == NULL) {
// try to find the name in the zone
const knot_node_t *ce = NULL;
......@@ -953,7 +960,7 @@ static void knot_zone_contents_check_loops_in_tree(knot_zone_tree_node_t *tnode,
// try to find wildcard child
assert(knot_dname_is_subdomain(next_name,
knot_node_owner(ce)));
next_node = knot_node_wildcard_child(ce);
next_node = knot_node_get_wildcard_child(ce);
}
assert(next_node == NULL || knot_dname_compare(
......@@ -2207,20 +2214,6 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone)
dbg_zone("Done.\n");
/*
* In second walkthrough check CNAME loops, including wildcards.
*/
adjust_arg.err = KNOT_EOK;
dbg_zone("Checking CNAME and wildcard loops.\n");
knot_zone_tree_forward_apply_inorder(zone->nodes,
knot_zone_contents_check_loops_in_tree,
(void *)&adjust_arg);
if (adjust_arg.err != KNOT_EOK) {
dbg_zone("Found CNAME loop in data. Aborting transfer.\n");
return adjust_arg.err;
}
adjust_arg.first_node = NULL;
adjust_arg.previous_node = NULL;
......@@ -2248,6 +2241,35 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone)
/*----------------------------------------------------------------------------*/
int knot_zone_contents_check_loops(knot_zone_contents_t *zone)
{
if (zone == NULL) {
return KNOT_EBADARG;
}
dbg_zone("Checking CNAME and wildcard loops.\n");
loop_check_data_t data;
data.err = KNOT_EOK;
data.zone = zone;
assert(zone->nodes != NULL);
knot_zone_tree_forward_apply_inorder(zone->nodes,
knot_zone_contents_check_loops_in_tree,
(void *)&data);
if (data.err != KNOT_EOK) {
dbg_zone("Found CNAME loop in data. Aborting transfer.\n");
return data.err;
}
dbg_zone("Done\n");
return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/
int knot_zone_contents_adjust_old(knot_zone_contents_t *zone)
{
if (zone == NULL) {
......
......@@ -363,6 +363,8 @@ knot_node_t *knot_zone_contents_get_apex(
*/
int knot_zone_contents_adjust(knot_zone_contents_t *contents);
int knot_zone_contents_check_loops(knot_zone_contents_t *zone);
/*!
* \brief Parses the NSEC3PARAM record stored in the zone.
*
......
......@@ -609,6 +609,7 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
parser->errors++;
}
/*! \todo Check return value. */
knot_zone_contents_adjust(contents);
dbg_zp("rdata adjusted\n");
......
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