Commit 6752479a authored by Jan Kadlec's avatar Jan Kadlec

Moved TTL checks into semantic checks.

- RR insertion function now returns zone RRSet.
- Removed reduntant zone contents / node API functions
- Cleanup.
parent 1b1a9709
......@@ -68,31 +68,6 @@ static inline void knot_node_flags_clear(knot_node_t *node, uint8_t flag)
node->flags &= ~flag;
}
/*----------------------------------------------------------------------------*/
/*!
* \brief Logs a warning if merging RRs with different TTLs.
*
* \param ttl_first TTL of the first RR in the RRSet.
* \param ttl_new TTL to be inserted.
* \param rr RRSet we're adding into.
* \param zname Zone name for logging.
*/
static void ttl_check(uint32_t ttl_first, uint32_t ttl_new,
knot_rrset_t *rr, const knot_dname_t *zname)
{
if (rr->type != KNOT_RRTYPE_RRSIG && (ttl_first != ttl_new) && zname) {
char *zstr = knot_dname_to_str(zname);
char *rrstr = knot_dname_to_str(rr->owner);
char typestr[32];
knot_rrtype_to_string(rr->type, typestr, 32);
log_zone_warning("Zone %s: Record %s, type %s: "
"Inserting different TTL into RRSet.\n",
zstr, rrstr, typestr);
free(zstr);
free(rrstr);
}
}
/*----------------------------------------------------------------------------*/
/* API functions */
/*----------------------------------------------------------------------------*/
......@@ -158,7 +133,7 @@ int knot_node_add_rrset_replace(knot_node_t *node, knot_rrset_t *rrset)
}
int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset,
const knot_dname_t *zname)
knot_rrset_t **out_rrset)
  • This is odd, can you explain the api change? Is the out_rrset added to solve some special case? I thought the whole node/rrset is checked at once a/o it is checked on rr insertion.

  • Without this, I wouldn't know which pointer to use for RRSet semantic checks. I could get the RRSet from zone node, but this seems better: you insert something into zone, and if the zone decides to destroy it, you get a valid pointer to work with.

  • Okay, I don't like the API much, too much side-effecty to me, but I'm okay with that explanation

Please register or sign in to reply
{
if (node == NULL) {
return KNOT_EINVAL;
......@@ -166,8 +141,9 @@ int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset,
for (uint16_t i = 0; i < node->rrset_count; ++i) {
if (node->rrset_tree[i]->type == rrset->type) {
ttl_check(knot_rrset_rr_ttl(node->rrset_tree[i], 0),
knot_rrset_rr_ttl(rrset, 0), rrset, zname);
if (out_rrset) {
*out_rrset = node->rrset_tree[i];
}
int merged, deleted_rrs;
int ret = knot_rrset_merge_sort(node->rrset_tree[i],
rrset, &merged,
......@@ -183,6 +159,9 @@ int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset,
}
// New RRSet (with one RR)
if (out_rrset) {
*out_rrset = rrset;
}
return knot_node_add_rrset_no_merge(node, rrset);
}
......
......@@ -123,13 +123,13 @@ knot_node_t *knot_node_new(const knot_dname_t *owner, knot_node_t *parent,
*
* \param node Node to add the RRSet to.
* \param rrset RRSet to add.
* \param zname Zone owner for error logging.
* \param rrset Stores destination RRSet in case of merge.
*
* \retval KNOT_EOK on success.
* \retval KNOT_ERROR if the RRSet could not be inserted.
*/
int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset,
const knot_dname_t *zname);
knot_rrset_t **out_rrset);
int knot_node_add_rrset_replace(knot_node_t *node, knot_rrset_t *rrset);
......
......@@ -39,6 +39,7 @@ static char *error_messages[(-ZC_ERR_UNKNOWN) + 1] = {
[-ZC_ERR_MISSING_SOA] = "SOA record missing in zone!",
[-ZC_ERR_MISSING_NS_DEL_POINT] = "NS record missing in zone apex or in "
"delegation point!",
[-ZC_ERR_TTL_MISMATCH] = "RRSet TTLs mismatched!",
[-ZC_ERR_RRSIG_RDATA_TYPE_COVERED] =
"RRSIG: Type covered RDATA field is wrong!",
......@@ -248,6 +249,47 @@ void err_handler_log_all(err_handler_t *handler)
}
}
/* TODO: optimize */
static bool rrset_ttls_equal(const knot_rrset_t *rrset)
{
uint16_t rr_count = knot_rrset_rr_count(rrset);
if (rr_count == 0) {
return true;
}
uint32_t prev_ttl = knot_rrset_rr_ttl(rrset, 0);
for (uint16_t i = 1; i < rr_count; ++i) {
uint32_t cur_ttl = knot_rrset_rr_ttl(rrset, i);
if (cur_ttl != prev_ttl) {
return false;
}
prev_ttl = cur_ttl;
}
return true;
}
/*!
* \brief Logs a warning if merging RRs with different TTLs.
*
* \param ttl_first TTL of the first RR in the RRSet.
* \param ttl_new TTL to be inserted.
* \param rr RRSet we're adding into.
* \param zname Zone name for logging.
*/
static void rrset_ttl_check(err_handler_t *handler,
const knot_rrset_t *rr, const knot_node_t *n)
{
if (rr->type != KNOT_RRTYPE_RRSIG && !rrset_ttls_equal(rr)) {
/* Prepare additional info string. */
char info_str[64] = { '\0' };
char type_str[16] = { '\0' };
knot_rrtype_to_string(rr->type, type_str, sizeof(type_str));
snprintf(info_str, sizeof(info_str), "Record type: %s.", type_str);
err_handler_handle_error(handler, n, ZC_ERR_TTL_MISMATCH, info_str);
}
}
/*!
* \brief Check whether DNSKEY rdata are valid.
*
......@@ -594,8 +636,6 @@ static int rdata_nsec_to_type_array(const knot_rrset_t *rrset, size_t pos,
return KNOT_EOK;
}
/* should write error, not return values !!! */
/*!
* \brief Semantic check - check node's NSEC node.
*
......@@ -694,7 +734,6 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone,
next_dname_size,
apex->owner);
if (next_dname == NULL) {
log_zone_warning("Could not create new dname!\n");
return KNOT_ERROR;
}
......@@ -721,13 +760,12 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone,
/* test for each type's presence */
type = array[j];
if (type == KNOT_RRTYPE_RRSIG) {
continue;
continue;
}
if (knot_node_rrset(node,
type) == NULL) {
if (knot_node_rrset(node, type) == NULL) {
err_handler_handle_error(handler, node,
ZC_ERR_NSEC3_RDATA_BITMAP,
ZC_ERR_NSEC3_RDATA_BITMAP,
NULL);
}
}
......@@ -907,6 +945,18 @@ int sem_check_node_plain(const knot_zone_contents_t *zone,
}
}
int sem_check_rrset(const knot_node_t *node,
const knot_rrset_t *rrset,
err_handler_t *handler)
{
if (node == NULL || rrset == NULL || handler == NULL) {
return KNOT_EINVAL;
}
rrset_ttl_check(handler, rrset, node);
return KNOT_EOK;
}
/*!
* \brief Run semantic checks for node with DNSSEC-related types.
*
......
......@@ -45,8 +45,9 @@ enum zonechecks_errors {
ZC_ERR_MISSING_SOA,
ZC_ERR_MISSING_NS_DEL_POINT,
ZC_ERR_TTL_MISMATCH,
ZC_ERR_GENERIC_GENERAL_ERROR, /* isn't there a better name? */
ZC_ERR_GENERIC_GENERAL_ERROR, /* Generic error delimiter. */
ZC_ERR_RRSIG_RDATA_TYPE_COVERED,
ZC_ERR_RRSIG_RDATA_TTL,
......@@ -61,7 +62,7 @@ enum zonechecks_errors {
ZC_ERR_RRSIG_CLASS,
ZC_ERR_RRSIG_TTL,
ZC_ERR_RRSIG_GENERAL_ERROR,
ZC_ERR_RRSIG_GENERAL_ERROR, /* RRSIG error delimiter. */
ZC_ERR_NO_NSEC,
ZC_ERR_NSEC_RDATA_BITMAP,
......@@ -69,7 +70,7 @@ enum zonechecks_errors {
ZC_ERR_NSEC_RDATA_CHAIN,
ZC_ERR_NSEC_RDATA_CHAIN_NOT_CYCLIC,
ZC_ERR_NSEC_GENERAL_ERROR,
ZC_ERR_NSEC_GENERAL_ERROR, /* NSEC error delimiter. */
ZC_ERR_NSEC3_UNSECURED_DELEGATION,
ZC_ERR_NSEC3_NOT_FOUND,
......@@ -79,7 +80,7 @@ enum zonechecks_errors {
ZC_ERR_NSEC3_RDATA_BITMAP,
ZC_ERR_NSEC3_EXTRA_RECORD,
ZC_ERR_NSEC3_GENERAL_ERROR,
ZC_ERR_NSEC3_GENERAL_ERROR, /* NSEC3 error delimiter. */
ZC_ERR_CNAME_EXTRA_RECORDS,
ZC_ERR_DNAME_CHILDREN,
......@@ -89,12 +90,12 @@ enum zonechecks_errors {
ZC_ERR_CNAME_WILDCARD_SELF,
ZC_ERR_DNAME_WILDCARD_SELF,
ZC_ERR_CNAME_GENERAL_ERROR,
ZC_ERR_CNAME_GENERAL_ERROR, /* CNAME/DNAME error delimiter. */
ZC_ERR_GLUE_NODE,
ZC_ERR_GLUE_RECORD,
ZC_ERR_GLUE_GENERAL_ERROR,
ZC_ERR_GLUE_GENERAL_ERROR, /* GLUE error delimiter. */
};
/*!
......@@ -206,12 +207,36 @@ int zone_do_sem_checks(knot_zone_contents_t *zone, int check_level,
err_handler_t *handler, knot_node_t *first_nsec3_node,
knot_node_t *last_nsec3_node);
/*!
* \brief Does a non-DNSSEC semantic node check. Logs errors via error handler.
*
* \param zone Zone containing the node.
* \param node Node to be tested.
* \param handler Error handler.
* \param only_mandatory Mandatory/optional switch.
* \param fatal_error Fatal error out param.
*
* \return KNOT_E*
*/
int sem_check_node_plain(const knot_zone_contents_t *zone,
const knot_node_t *node,
err_handler_t *handler,
bool only_mandatory,
bool *fatal_error);
/*!
* \brief Checks RRSet for semantic errors. Logs errors via error handler.
*
* \param node Node containg the RRSet.
* \param rrset RRSet to be tested.
* \param handler Error handler.
*
* \return KNOT_E*
*/
int sem_check_rrset(const knot_node_t *node,
const knot_rrset_t *rrset,
err_handler_t *handler);
#endif // _KNOT_SEMANTIC_CHECK_H_
/*! @} */
......@@ -476,14 +476,6 @@ int knot_zone_contents_gen_is_new(const knot_zone_contents_t *contents)
/*----------------------------------------------------------------------------*/
int knot_zone_contents_gen_is_finished(const knot_zone_contents_t *contents)
{
return ((contents->flags & KNOT_ZONE_FLAGS_GEN_MASK)
== KNOT_ZONE_FLAGS_GEN_FIN);
}
/*----------------------------------------------------------------------------*/
void knot_zone_contents_set_gen_old(knot_zone_contents_t *contents)
{
contents->flags &= ~KNOT_ZONE_FLAGS_GEN_MASK;
......@@ -500,14 +492,6 @@ void knot_zone_contents_set_gen_new(knot_zone_contents_t *contents)
/*----------------------------------------------------------------------------*/
void knot_zone_contents_set_gen_new_finished(knot_zone_contents_t *contents)
{
contents->flags &= ~KNOT_ZONE_FLAGS_GEN_MASK;
contents->flags |= KNOT_ZONE_FLAGS_GEN_FIN;
}
/*----------------------------------------------------------------------------*/
uint16_t knot_zone_contents_class(const knot_zone_contents_t *contents)
{
if (contents == NULL || contents->apex == NULL
......@@ -649,9 +633,9 @@ int knot_zone_contents_create_node(knot_zone_contents_t *contents,
/*----------------------------------------------------------------------------*/
static int insert_rr(knot_zone_contents_t *z, knot_rrset_t *rr, knot_node_t **n,
bool nsec3)
knot_rrset_t **rrset, bool nsec3)
{
if (z == NULL || rr == NULL || n == NULL) {
if (z == NULL || rr == NULL || n == NULL || rrset == NULL) {
return KNOT_EINVAL;
}
......@@ -679,7 +663,7 @@ static int insert_rr(knot_zone_contents_t *z, knot_rrset_t *rr, knot_node_t **n,
}
}
return knot_node_add_rrset(*n, rr, z->apex->owner);
return knot_node_add_rrset(*n, rr, rrset);
}
static bool to_nsec3_tree(const knot_rrset_t *rr)
......@@ -688,9 +672,10 @@ static bool to_nsec3_tree(const knot_rrset_t *rr)
}
int knot_zone_contents_add_rr(knot_zone_contents_t *z,
knot_rrset_t *rr, knot_node_t **n)
knot_rrset_t *rr, knot_node_t **n,
knot_rrset_t **rrset)
{
return insert_rr(z, rr, n, to_nsec3_tree(rr));
return insert_rr(z, rr, n, rrset, to_nsec3_tree(rr));
}
int knot_zone_contents_add_rrset(knot_zone_contents_t *zone,
......@@ -728,7 +713,7 @@ dbg_zone_exec_detail(
/*! \todo REMOVE RRSET */
if (dupl == KNOT_RRSET_DUPL_MERGE) {
rc = knot_node_add_rrset(*node, rrset, zone->apex->owner);
rc = knot_node_add_rrset(*node, rrset, NULL);
} else {
rc = knot_node_add_rrset_no_merge(*node, rrset);
}
......@@ -782,52 +767,6 @@ int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone,
/*----------------------------------------------------------------------------*/
int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *zone,
knot_rrset_t *rrset,
knot_node_t **node,
knot_rrset_dupl_handling_t dupl)
{
if (zone == NULL || rrset == NULL || zone->apex == NULL
|| zone->apex->owner == NULL || node == NULL) {
return KNOT_EINVAL;
}
// check if the RRSet belongs to the zone
if (knot_dname_cmp(knot_rrset_owner(rrset),
zone->apex->owner) != 0
&& !knot_dname_is_sub(knot_rrset_owner(rrset),
zone->apex->owner)) {
return KNOT_EOUTOFZONE;
}
if ((*node) == NULL
&& (*node = knot_zone_contents_get_nsec3_node(
zone, knot_rrset_owner(rrset))) == NULL) {
return KNOT_ENONODE;
}
assert(*node != NULL);
int rc;
/*! \todo REMOVE RRSET */
if (dupl == KNOT_RRSET_DUPL_MERGE) {
rc = knot_node_add_rrset(*node, rrset, zone->apex->owner);
} else {
rc = knot_node_add_rrset_no_merge(*node, rrset);
}
if (rc < 0) {
return rc;
}
int ret = rc;
dbg_zone_detail("NSEC3 OK\n");
return ret;
}
/*----------------------------------------------------------------------------*/
int knot_zone_contents_remove_node(knot_zone_contents_t *contents,
const knot_dname_t *owner)
{
......
......@@ -88,11 +88,9 @@ knot_zone_contents_t *knot_zone_contents_new(const knot_dname_t *apex_name);
int knot_zone_contents_gen_is_old(const knot_zone_contents_t *contents);
int knot_zone_contents_gen_is_new(const knot_zone_contents_t *contents);
int knot_zone_contents_gen_is_finished(const knot_zone_contents_t *contents);
void knot_zone_contents_set_gen_old(knot_zone_contents_t *contents);
void knot_zone_contents_set_gen_new(knot_zone_contents_t *contents);
void knot_zone_contents_set_gen_new_finished(knot_zone_contents_t *contents);
uint16_t knot_zone_contents_class(const knot_zone_contents_t *contents);
......@@ -131,7 +129,8 @@ int knot_zone_contents_create_node(knot_zone_contents_t *contents,
knot_node_t **node);
int knot_zone_contents_add_rr(knot_zone_contents_t *z,
knot_rrset_t *rr, knot_node_t **n);
knot_rrset_t *rr, knot_node_t **n,
knot_rrset_t **rrset);
/*!
* \brief Adds a RRSet to the given zone.
......@@ -159,11 +158,6 @@ int knot_zone_contents_add_rrset(knot_zone_contents_t *contents,
knot_rrset_t *rrset, knot_node_t **node,
knot_rrset_dupl_handling_t dupl);
int knot_zone_contents_add_rrsigs(knot_zone_contents_t *contents,
knot_rrset_t *rrsigs,
knot_rrset_t **rrset, knot_node_t **node,
knot_rrset_dupl_handling_t dupl);
/*!
* \brief Adds a node holding NSEC3 records to the given zone.
*
......@@ -183,11 +177,6 @@ int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *contents,
knot_node_t *node, int create_parents,
uint8_t flags);
int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *contents,
knot_rrset_t *rrset,
knot_node_t **node,
knot_rrset_dupl_handling_t dupl);
int knot_zone_contents_remove_node(knot_zone_contents_t *contents,
const knot_dname_t *owner);
......
......@@ -98,7 +98,8 @@ int zcreator_step(zcreator_t *zc, knot_rrset_t *rr)
// Search for node or create a new one
n = NULL;
}
int ret = knot_zone_contents_add_rr(zc->z, rr, &n);
knot_rrset_t *zone_rrset = NULL;
int ret = knot_zone_contents_add_rr(zc->z, rr, &n, &zone_rrset);
if (ret < 0) {
if (!handle_err(zc, rr, ret)) {
// Fatal error
......@@ -111,11 +112,17 @@ int zcreator_step(zcreator_t *zc, knot_rrset_t *rr)
knot_rrset_deep_free(&rr, true, NULL);
}
assert(n);
assert(zone_rrset);
zc->last_node = n;
// Do RRSet and node semantic checks
bool sem_fatal_error = false;
err_handler_t err_handler;
err_handler_init(&err_handler);
ret = sem_check_rrset(n, zone_rrset, &err_handler);
if (ret != KNOT_EOK) {
return ret;
}
ret = sem_check_node_plain(zc->z, n,
&err_handler, true,
&sem_fatal_error);
......
......@@ -2006,7 +2006,7 @@ int knot_rrset_txt_dump(const knot_rrset_t *rrset,
// Loop over rdata in rrset.
uint16_t rr_count = knot_rrset_rr_count(rrset);
for (uint16_t i = 0; i < knot_rrset_rr_count(rrset); i++) {
for (uint16_t i = 0; i < rr_count; i++) {
// Dump rdata owner, class, ttl and type.
ret = knot_rrset_txt_dump_header(rrset,
knot_rrset_rr_ttl(rrset, i),
......
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