Commit 4842d4da authored by Jan Kadlec's avatar Jan Kadlec

new_node: Store additionals into node.

parent 42c5e78f
......@@ -154,7 +154,6 @@ static int put_rrsig(const knot_dname_t *sig_owner, uint16_t type,
static int put_answer(knot_pkt_t *pkt, uint16_t type, struct query_data *qdata)
{
const knot_rrset_t *rrset = NULL;
knot_rrset_t **rrsets = knot_node_rrsets(qdata->node);
/* Wildcard expansion or exact match, either way RRSet owner is
* is QNAME. We can fake name synthesis by setting compression hint to
......@@ -168,7 +167,8 @@ static int put_answer(knot_pkt_t *pkt, uint16_t type, struct query_data *qdata)
int ret = KNOT_EOK;
switch (type) {
case KNOT_RRTYPE_ANY: /* Append all RRSets. */
case KNOT_RRTYPE_ANY: /* Append all RRSets. */ {
knot_rrset_t **rrsets = knot_node_rrsets(qdata->node);
/* If ANY not allowed, set TC bit. */
if ((qdata->param->proc_flags & NS_QUERY_LIMIT_ANY) &&
(qdata->zone->conf->disable_any)) {
......@@ -180,10 +180,13 @@ static int put_answer(knot_pkt_t *pkt, uint16_t type, struct query_data *qdata)
for (unsigned i = 0; i < knot_node_rrset_count(qdata->node); ++i) {
ret = ns_put_rr(pkt, rrsets[i], NULL, compr_hint, 0, qdata);
if (ret != KNOT_EOK) {
knot_node_free_rrset_array(qdata->node, rrsets);
break;
}
}
knot_node_free_rrset_array(qdata->node, rrsets);
break;
}
default: /* Single RRSet of given type. */
rrset = knot_node_get_rrset(qdata->node, type);
if (rrset) {
......@@ -193,7 +196,6 @@ static int put_answer(knot_pkt_t *pkt, uint16_t type, struct query_data *qdata)
break;
}
knot_node_free_rrset_array(qdata->node, rrsets);
return ret;
}
......@@ -292,11 +294,12 @@ static int put_additional(knot_pkt_t *pkt, const knot_rrset_t *rr,
for (uint16_t i = 0; i < rr_rdata_count; i++) {
hint = knot_pkt_compr_hint(info, COMPR_HINT_RDATA + i);
node = rr->additional[i];
/* No additional node for this record. */
if (node == NULL) {
continue;
}
const knot_rrset_t *rrsigs = knot_node_rrset(node, KNOT_RRTYPE_RRSIG);
for (int k = 0; k < ar_type_count; ++k) {
additional = knot_node_rrset(node, ar_type_list[k]);
......@@ -666,6 +669,13 @@ int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
return KNOT_EMALF;
}
// Copy all RRs for now TODO
int ret = knot_rrset_copy(rr, (knot_rrset_t **)&rr, &pkt->mm);
if (ret != KNOT_EOK) {
return KNOT_ENOMEM;
}
flags |= KNOT_PF_FREE;
/* Wildcard expansion applies only for answers. */
bool expand = false;
if (pkt->current == KNOT_ANSWER) {
......@@ -676,12 +686,13 @@ int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
/* If we already have compressed name on the wire and compression hint,
* we can just insert RRSet and fake synthesis by using compression
* hint. */
int ret = KNOT_EOK;
// int ret = KNOT_EOK;
if (compr_hint == COMPR_HINT_NONE && expand) {
ret = knot_rrset_copy(rr, (knot_rrset_t **)&rr, &pkt->mm);
if (ret != KNOT_EOK) {
return KNOT_ENOMEM;
}
// TODO workaround for rrset compatibility
// ret = knot_rrset_copy(rr, (knot_rrset_t **)&rr, &pkt->mm);
// if (ret != KNOT_EOK) {
// return KNOT_ENOMEM;
// }
knot_rrset_set_owner((knot_rrset_t *)rr, qdata->name);
flags |= KNOT_PF_FREE;
......
......@@ -197,9 +197,10 @@ static void log_zone_load_info(const zone_t *zone, const char *zone_name,
int64_t serial = 0;
if (zone->contents && zone->contents->apex) {
const knot_rrset_t *soa;
soa = knot_node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA);
knot_rrset_t *soa;
soa = knot_node_get_rrset(zone->contents->apex, KNOT_RRTYPE_SOA);
serial = knot_rdata_soa_serial(soa);
knot_rrset_free(&soa, NULL);
}
log_zone_info("Zone '%s' %s (serial %" PRId64 ")\n", zone_name, action, serial);
......
......@@ -88,6 +88,7 @@ static uint32_t zones_soa_timer(zone_t *zone, uint32_t (*rr_func)(const knot_rrs
soa_rrs = knot_node_rrset(zc->apex, KNOT_RRTYPE_SOA);
assert(soa_rrs != NULL);
ret = rr_func(soa_rrs);
knot_rrset_free(&soa_rrs, NULL);
rcu_read_unlock();
......@@ -1879,6 +1880,7 @@ int zones_journal_apply(zone_t *zone)
soa_rrs = knot_node_rrset(contents->apex, KNOT_RRTYPE_SOA);
assert(soa_rrs != NULL);
int64_t serial_ret = knot_rdata_soa_serial(soa_rrs);
knot_rrset_free(&soa_rrs, NULL);
if (serial_ret < 0) {
rcu_read_unlock();
return KNOT_EINVAL;
......
......@@ -383,8 +383,7 @@ int knot_ddns_check_zone(const knot_zone_contents_t *zone,
}
// check zone CLASS
if (knot_zone_contents_class(zone) !=
knot_pkt_qclass(query)) {
if (knot_pkt_qclass(query) != KNOT_CLASS_IN) {
*rcode = KNOT_RCODE_NOTAUTH;
return KNOT_ENOZONE;
}
......@@ -1581,7 +1580,7 @@ static int knot_ddns_process_rr(const knot_rrset_t *rr,
/* 2) Decide what to do. */
int ret = KNOT_EOK;
if (knot_rrset_class(rr) == knot_zone_contents_class(zone)) {
if (knot_rrset_class(rr) == KNOT_CLASS_IN) {
ret = knot_ddns_process_add(rr, &node, zone, changeset,
changes, rr_copy);
} else if (node == NULL) {
......
......@@ -69,14 +69,31 @@ static inline void knot_node_flags_clear(knot_node_t *node, uint8_t flag)
node->flags &= ~flag;
}
void rr_data_clear(struct rr_data *data, mm_ctx_t *mm)
{
knot_rrs_clear(&data->rrs, mm);
mm_free(mm, data->additional);
}
int rr_data_from(const knot_rrset_t *rrset, struct rr_data *data, mm_ctx_t *mm)
{
int ret = knot_rrs_copy(&data->rrs, &rrset->rrs, mm);
if (ret != KNOT_EOK) {
free(data);
return ret;
}
data->type = rrset->type;
if (rrset->additional) {
data->additional = mm_alloc(mm, data->rrs.rr_count * sizeof(void *));
if (data->additional == NULL) {
ERR_ALLOC_FAILED;
knot_rrs_clear(&data->rrs, mm);
return ret;
}
memcpy(data->additional, rrset->additional,
data->rrs.rr_count * sizeof(void *));
} else {
data->additional = NULL;
}
return KNOT_EOK;
}
......@@ -88,7 +105,7 @@ static knot_rrset_t *rrset_from_rr_data(const knot_node_t *n, size_t pos,
if (dname_copy == NULL) {
return NULL;
}
knot_rrset_t *rrset = knot_rrset_new(n->owner, data.type, KNOT_CLASS_IN, mm);
knot_rrset_t *rrset = knot_rrset_new(dname_copy, data.type, KNOT_CLASS_IN, mm);
if (rrset == NULL) {
knot_dname_free(&dname_copy);
return NULL;
......@@ -99,6 +116,16 @@ static knot_rrset_t *rrset_from_rr_data(const knot_node_t *n, size_t pos,
knot_rrset_free(&rrset, mm);
return NULL;
}
if (data.additional) {
size_t alloc_size = data.rrs.rr_count * sizeof(knot_node_t *);
rrset->additional = mm_alloc(mm, alloc_size);
if (rrset->additional == NULL) {
knot_rrset_free(&rrset, mm);
return NULL;
}
memcpy(rrset->additional, data.additional, alloc_size);
}
return rrset;
}
......@@ -195,8 +222,8 @@ int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset,
knot_rrset_free(&node_rrset, NULL);
return ret;
} else {
knot_rrs_clear(&node->rrs[i].rrs, NULL);
knot_rrs_copy(&node->rrs[i].rrs, &rrset->rrs, NULL);
rr_data_clear(&node->rrs[i], NULL);
rr_data_from(node_rrset, &node->rrs[i], NULL);
knot_rrset_free(&node_rrset, NULL);
if (merged || deleted_rrs) {
return 1;
......@@ -728,10 +755,12 @@ bool knot_node_rrtype_is_signed(const knot_node_t *node, uint16_t type)
const uint16_t type_covered =
knot_rdata_rrsig_type_covered(rrsigs, i);
if (type_covered == type) {
knot_rrset_free(&rrsigs, NULL);
return true;
}
}
knot_rrset_free(&rrsigs, NULL);
return false;
}
......
......@@ -37,10 +37,7 @@
/*----------------------------------------------------------------------------*/
struct rr_data {
uint16_t type;
knot_rrs_t rrs;
};
struct rr_data;
/*!
* \brief Structure representing one node in a domain name tree, i.e. one domain
......@@ -94,6 +91,12 @@ struct knot_node {
typedef struct knot_node knot_node_t;
struct rr_data {
uint16_t type;
knot_rrs_t rrs;
knot_node_t **additional;
};
/*----------------------------------------------------------------------------*/
/*! \brief Flags used to mark nodes with some property. */
typedef enum {
......
......@@ -152,33 +152,33 @@ static int knot_zone_contents_nsec3_name(const knot_zone_contents_t *zone,
}
/*! \brief Link pointers to additional nodes for this RRSet. */
static int discover_additionals(knot_rrset_t *rr, knot_zone_contents_t *zone)
static int discover_additionals(struct rr_data *rr_data,
knot_zone_contents_t *zone,
knot_node_t ***additional)
{
const knot_node_t *node = NULL, *encloser = NULL, *prev = NULL;
const knot_dname_t *dname = NULL;
/* Free old additional nodes. */
if (rr->additional != NULL) {
free(rr->additional);
}
const knot_rrs_t *rrs = &rr_data->rrs;
/* Create new additional nodes. */
uint16_t rdcount = knot_rrset_rr_count(rr);
rr->additional = malloc(rdcount * sizeof(knot_node_t*));
if (rr->additional == NULL) {
uint16_t rdcount = rrs->rr_count;
*additional = malloc(rdcount * sizeof(knot_node_t *));
if (*additional == NULL) {
ERR_ALLOC_FAILED;
return KNOT_ENOMEM;
}
for (uint16_t i = 0; i < rdcount; i++) {
/* Try to find node for the dname in the RDATA. */
dname = knot_rdata_name(rr, i);
// TODO wrapper RRSET, remove
knot_rrset_t rrset = {.rrs = *rrs, .type = rr_data->type};
dname = knot_rdata_name(&rrset, i);
knot_zone_contents_find_dname(zone, dname, &node, &encloser, &prev);
if (node == NULL && encloser && encloser->wildcard_child) {
node = encloser->wildcard_child;
}
rr->additional[i] = (knot_node_t *)node;
(*additional)[i] = (knot_node_t *)node;
}
return KNOT_EOK;
......@@ -213,7 +213,7 @@ static int adjust_pointers(knot_node_t **tnode, void *data)
|| knot_node_is_non_auth(knot_node_parent(node)))
) {
knot_node_set_non_auth(node);
} else if (knot_node_rrset(node, KNOT_RRTYPE_NS) != NULL
} else if (knot_node_rrtype_exists(node, KNOT_RRTYPE_NS)
&& node != args->zone->apex) {
knot_node_set_deleg_point(node);
} else {
......@@ -326,25 +326,25 @@ static int adjust_additional(knot_node_t **tnode, void *data)
assert(data != NULL);
assert(tnode != NULL);
// TODO store elsewhere
return KNOT_EOK;
// int ret = KNOT_EOK;
// knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data;
// knot_node_t *node = *tnode;
// knot_rrset_t **rrset = knot_node_rrsets(node);
int ret = KNOT_EOK;
knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data;
knot_node_t *node = *tnode;
/* Lookup additional records for specific nodes. */
// for(uint16_t i = 0; i < node->rrset_count; ++i) {
// if (rrset_additional_needed(rrset[i]->type)) {
// ret = discover_additionals(rrset[i], args->zone);
// if (ret != KNOT_EOK) {
// break;
// }
// }
// }
for(uint16_t i = 0; i < node->rrset_count; ++i) {
struct rr_data *rr_data = &node->rrs[i];
if (rrset_additional_needed(rr_data->type)) {
knot_node_t **additional = NULL;
ret = discover_additionals(rr_data, args->zone,
&additional);
if (ret != KNOT_EOK) {
break;
}
rr_data->additional = additional;
}
}
// return ret;
return ret;
}
/*----------------------------------------------------------------------------*/
......@@ -494,19 +494,6 @@ void knot_zone_contents_set_gen_new(knot_zone_contents_t *contents)
/*----------------------------------------------------------------------------*/
uint16_t knot_zone_contents_class(const knot_zone_contents_t *contents)
{
if (contents == NULL || contents->apex == NULL
|| knot_node_rrset(contents->apex, KNOT_RRTYPE_SOA) == NULL) {
return KNOT_EINVAL;
}
return knot_rrset_class(knot_node_rrset(contents->apex,
KNOT_RRTYPE_SOA));
}
/*----------------------------------------------------------------------------*/
int knot_zone_contents_add_node(knot_zone_contents_t *zone,
knot_node_t *node, int create_parents,
uint8_t flags)
......@@ -1263,6 +1250,7 @@ int knot_zone_contents_adjust_full(knot_zone_contents_t *zone,
if (zone == NULL) {
return KNOT_EINVAL;
}
int result = knot_zone_contents_load_nsec3param(zone);
if (result != KNOT_EOK) {
......@@ -1328,12 +1316,14 @@ int knot_zone_contents_load_nsec3param(knot_zone_contents_t *zone)
if (r != KNOT_EOK) {
dbg_zone("Failed to load NSEC3PARAM (%s).\n",
knot_strerror(r));
knot_rrset_free(&rrset, NULL);
return r;
}
} else {
memset(&zone->nsec3_params, 0, sizeof(knot_nsec3_params_t));
}
knot_rrset_free(&rrset, NULL);
return KNOT_EOK;
}
......@@ -1491,7 +1481,9 @@ uint32_t knot_zone_serial(const knot_zone_contents_t *zone)
if (!zone) return 0;
const knot_rrset_t *soa = NULL;
soa = knot_node_rrset(knot_zone_contents_apex(zone), KNOT_RRTYPE_SOA);
return knot_rdata_soa_serial(soa);
uint32_t serial = knot_rdata_soa_serial(soa);
knot_rrset_free(&soa, NULL);
return serial;
}
bool knot_zone_contents_is_signed(const knot_zone_contents_t *zone)
......
......@@ -92,8 +92,6 @@ int knot_zone_contents_gen_is_new(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);
uint16_t knot_zone_contents_class(const knot_zone_contents_t *contents);
/*!
* \brief Adds a node to the given zone.
*
......
......@@ -82,7 +82,7 @@ int zcreator_step(zcreator_t *zc, knot_rrset_t *rr)
assert(zc && rr);
if (rr->type == KNOT_RRTYPE_SOA &&
knot_node_rrset(zc->z->apex, KNOT_RRTYPE_SOA)) {
knot_node_rrtype_exists(zc->z->apex, KNOT_RRTYPE_SOA)) {
// Ignore extra SOA
knot_rrset_free(&rr, NULL);
return KNOT_EOK;
......@@ -103,6 +103,8 @@ int zcreator_step(zcreator_t *zc, knot_rrset_t *rr)
} else if (ret > 0) {
knot_rrset_free(&rr, NULL);
}
// TODO: free everytime for now
knot_rrset_free(&rr, NULL);
assert(node);
// assert(zone_rrset);
......@@ -258,7 +260,7 @@ knot_zone_contents_t *zonefile_load(zloader_t *loader)
goto fail;
}
if (knot_node_rrset(loader->creator->z->apex, KNOT_RRTYPE_SOA) == NULL) {
if (!knot_node_rrtype_exists(loader->creator->z->apex, KNOT_RRTYPE_SOA)) {
log_zone_error("%s: no SOA record in the zone file.\n",
loader->source);
goto fail;
......
......@@ -873,7 +873,19 @@ int knot_rrset_copy(const knot_rrset_t *from, knot_rrset_t **to, mm_ctx_t *mm)
return ret;
}
(*to)->additional = NULL; /* Never copy. */
if (from->additional) {
const size_t alloc_size =
knot_rrset_rr_count(from) * sizeof(void *);
(*to)->additional = mm_alloc(mm, alloc_size);
if ((*to)->additional == NULL) {
ERR_ALLOC_FAILED;
knot_rrset_free(to, mm);
return KNOT_ENOMEM;
}
memcpy((*to)->additional, from->additional, alloc_size);
} else {
(*to)->additional = NULL;
}
return KNOT_EOK;
}
......
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