Commit bca98b71 authored by Jan Kadlec's avatar Jan Kadlec

changeset: Removed all redundant RRSet copies.

parent c04a4b93
......@@ -28,23 +28,19 @@
/*!
* \brief Create NSEC RR set.
*
* \param from Node that should contain the new RRSet
* \param to Node that should be pointed to from 'from'
* \param rrset RRSet to be initialized.
* \param from Node that should contain the new RRSet.
* \param to Node that should be pointed to from 'from'.
* \param ttl Record TTL (SOA's minimum TTL).
*
* \return NSEC RR set, NULL on error.
*/
static knot_rrset_t *create_nsec_rrset(const zone_node_t *from,
const zone_node_t *to,
uint32_t ttl)
static int create_nsec_rrset(knot_rrset_t *rrset, const zone_node_t *from,
const zone_node_t *to, uint32_t ttl)
{
assert(from);
assert(to);
knot_rrset_t *rrset = knot_rrset_new(from->owner, KNOT_RRTYPE_NSEC,
KNOT_CLASS_IN, NULL);
if (!rrset) {
return NULL;
}
knot_rrset_init(rrset, from->owner, KNOT_RRTYPE_NSEC, KNOT_CLASS_IN);
// Create bitmap
bitmap_t rr_types = { 0 };
......@@ -65,13 +61,7 @@ static knot_rrset_t *create_nsec_rrset(const zone_node_t *from,
memcpy(rdata, to->owner, next_owner_size);
bitmap_write(&rr_types, rdata + next_owner_size);
int ret = knot_rrset_add_rdata(rrset, rdata, rdata_size, ttl, NULL);
if (ret != KNOT_EOK) {
knot_rrset_free(&rrset, NULL);
return NULL;
}
return rrset;
return knot_rrset_add_rdata(rrset, rdata, rdata_size, ttl, NULL);
}
/*!
......@@ -97,7 +87,7 @@ static int connect_nsec_nodes(zone_node_t *a, zone_node_t *b,
return NSEC_NODE_SKIP;
}
int ret = 0;
int ret = KNOT_EOK;
/*!
* If the node has no other RRSets than NSEC (and possibly RRSIGs),
......@@ -114,19 +104,20 @@ static int connect_nsec_nodes(zone_node_t *a, zone_node_t *b,
}
// create new NSEC
knot_rrset_t *new_nsec = create_nsec_rrset(a, b, data->ttl);
if (!new_nsec) {
knot_rrset_t new_nsec;
ret = create_nsec_rrset(&new_nsec, a, b, data->ttl);
if (ret != KNOT_EOK) {
dbg_dnssec_detail("Failed to create new NSEC.\n");
return KNOT_ENOMEM;
return ret;
}
knot_rrset_t old_nsec = node_rrset(a, KNOT_RRTYPE_NSEC);
if (!knot_rrset_empty(&old_nsec)) {
if (knot_rrset_equal(new_nsec, &old_nsec,
if (knot_rrset_equal(&new_nsec, &old_nsec,
KNOT_RRSET_COMPARE_WHOLE)) {
// current NSEC is valid, do nothing
dbg_dnssec_detail("NSECs equal.\n");
knot_rrset_free(&new_nsec, NULL);
knot_rdataset_clear(&new_nsec.rrs, NULL);
return KNOT_EOK;
}
......@@ -135,14 +126,16 @@ static int connect_nsec_nodes(zone_node_t *a, zone_node_t *b,
a->flags |= NODE_FLAGS_REMOVED_NSEC;
ret = knot_nsec_changeset_remove(a, data->changeset);
if (ret != KNOT_EOK) {
knot_rrset_free(&new_nsec, NULL);
knot_rdataset_clear(&new_nsec.rrs, NULL);
return ret;
}
}
dbg_dnssec_detail("Adding new NSEC to changeset.\n");
// Add new NSEC to the changeset (no matter if old was removed)
return changeset_add_rrset(data->changeset, new_nsec);
ret = changeset_add_rrset(data->changeset, &new_nsec);
knot_rdataset_clear(&new_nsec.rrs, NULL);
return ret;
}
/* - API - iterations ------------------------------------------------------- */
......@@ -212,38 +205,33 @@ int knot_nsec_changeset_remove(const zone_node_t *n,
int result = KNOT_EOK;
knot_rrset_t *nsec = node_create_rrset(n, KNOT_RRTYPE_NSEC);
if (nsec == NULL) {
nsec = node_create_rrset(n, KNOT_RRTYPE_NSEC3);
knot_rrset_t nsec = node_rrset(n, KNOT_RRTYPE_NSEC);
if (knot_rrset_empty(&nsec)) {
nsec = node_rrset(n, KNOT_RRTYPE_NSEC3);
}
if (nsec) {
if (!knot_rrset_empty(&nsec)) {
// update changeset
result = changeset_rem_rrset(changeset, nsec);
result = changeset_rem_rrset(changeset, &nsec);
if (result != KNOT_EOK) {
knot_rrset_free(&nsec, NULL);
return result;
}
}
knot_rrset_t rrsigs = node_rrset(n, KNOT_RRTYPE_RRSIG);
if (!knot_rrset_empty(&rrsigs)) {
knot_rrset_t *synth_rrsigs = knot_rrset_new(n->owner,
KNOT_RRTYPE_RRSIG,
KNOT_CLASS_IN,
NULL);
if (synth_rrsigs == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_t synth_rrsigs;
knot_rrset_init(&synth_rrsigs, n->owner, KNOT_RRTYPE_RRSIG,
KNOT_CLASS_IN);
result = knot_synth_rrsig(KNOT_RRTYPE_NSEC, &rrsigs.rrs,
&synth_rrsigs->rrs, NULL);
&synth_rrsigs.rrs, NULL);
if (result == KNOT_ENOENT) {
// Try removing NSEC3 RRSIGs
result = knot_synth_rrsig(KNOT_RRTYPE_NSEC3, &rrsigs.rrs,
&synth_rrsigs->rrs, NULL);
&synth_rrsigs.rrs, NULL);
}
if (result != KNOT_EOK) {
knot_rrset_free(&synth_rrsigs, NULL);
knot_rdataset_clear(&synth_rrsigs.rrs, NULL);
if (result != KNOT_ENOENT) {
return result;
}
......@@ -251,14 +239,11 @@ int knot_nsec_changeset_remove(const zone_node_t *n,
}
// store RRSIG
result = changeset_rem_rrset(changeset, synth_rrsigs);
if (result != KNOT_EOK) {
knot_rrset_free(&synth_rrsigs, NULL);
return result;
}
result = changeset_rem_rrset(changeset, &synth_rrsigs);
knot_rdataset_clear(&synth_rrsigs.rrs, NULL);
}
return KNOT_EOK;
return result;
}
/*!
......
......@@ -224,7 +224,8 @@ static int remove_expired_rrsigs(const knot_rrset_t *covered,
assert(rrsigs->type == KNOT_RRTYPE_RRSIG);
knot_rrset_t *to_remove = NULL;
knot_rrset_t to_remove;
knot_rrset_init_empty(&to_remove);
int result = KNOT_EOK;
knot_rrset_t synth_rrsig;
......@@ -259,30 +260,23 @@ static int remove_expired_rrsigs(const knot_rrset_t *covered,
}
}
if (to_remove == NULL) {
if (knot_rrset_empty(&to_remove)) {
to_remove = create_empty_rrsigs_for(&synth_rrsig);
if (to_remove == NULL) {
result = KNOT_ENOMEM;
break;
}
}
knot_rdata_t *rr_rem = knot_rdataset_at(&synth_rrsig.rrs, i);
result = knot_rdataset_add(&to_remove->rrs, rr_rem, NULL);
result = knot_rdataset_add(&to_remove.rrs, rr_rem, NULL);
if (result != KNOT_EOK) {
break;
}
}
if (to_remove != NULL && result == KNOT_EOK) {
result = changeset_rem_rrset(changeset, to_remove);
}
if (to_remove != NULL && result != KNOT_EOK) {
knot_rrset_free(&to_remove, NULL);
if (!knot_rrset_empty(&to_remove) && result == KNOT_EOK) {
result = changeset_rem_rrset(changeset, &to_remove);
}
knot_rdataset_clear(&synth_rrsig.rrs, NULL);
knot_rdataset_clear(&to_remove.rrs, NULL);
return result;
}
......@@ -309,7 +303,8 @@ static int add_missing_rrsigs(const knot_rrset_t *covered,
assert(changeset);
int result = KNOT_EOK;
knot_rrset_t *to_add = NULL;
knot_rrset_t to_add;
knot_rrset_init_empty(&to_add);
node_t *node = NULL;
WALK_LIST(node, zone_keys->list) {
......@@ -323,27 +318,22 @@ static int add_missing_rrsigs(const knot_rrset_t *covered,
continue;
}
if (to_add == NULL) {
if (knot_rrset_empty(&to_add)) {
to_add = create_empty_rrsigs_for(covered);
if (to_add == NULL) {
return KNOT_ENOMEM;
}
}
result = knot_sign_rrset(to_add, covered, &key->dnssec_key,
result = knot_sign_rrset(&to_add, covered, &key->dnssec_key,
key->context, policy);
if (result != KNOT_EOK) {
break;
}
}
if (to_add != NULL && result == KNOT_EOK) {
result = changeset_add_rrset(changeset, to_add);
if (!knot_rrset_empty(&to_add) && result == KNOT_EOK) {
result = changeset_add_rrset(changeset, &to_add);
}
if (to_add != NULL && result != KNOT_EOK) {
knot_rrset_free(&to_add, NULL);
}
knot_rdataset_clear(&to_add.rrs, NULL);
return result;
}
......@@ -362,24 +352,19 @@ static int remove_rrset_rrsigs(const knot_dname_t *owner, uint16_t type,
{
assert(owner);
assert(changeset);
knot_rrset_t *synth_rrsig =
knot_rrset_new(owner, KNOT_RRTYPE_RRSIG, KNOT_CLASS_IN, NULL);
if (synth_rrsig == NULL) {
return KNOT_ENOMEM;
}
int ret = knot_synth_rrsig(type, &rrsigs->rrs, &synth_rrsig->rrs, NULL);
knot_rrset_t synth_rrsig;
knot_rrset_init(&synth_rrsig, (knot_dname_t *)owner,
KNOT_RRTYPE_RRSIG, KNOT_CLASS_IN);
int ret = knot_synth_rrsig(type, &rrsigs->rrs, &synth_rrsig.rrs, NULL);
if (ret != KNOT_EOK) {
knot_rrset_free(&synth_rrsig, NULL);
if (ret != KNOT_ENOENT) {
return ret;
}
return KNOT_EOK;
}
ret = changeset_rem_rrset(changeset, synth_rrsig);
if (ret != KNOT_EOK) {
knot_rrset_free(&synth_rrsig, NULL);
}
ret = changeset_rem_rrset(changeset, &synth_rrsig);
knot_rdataset_clear(&synth_rrsig.rrs, NULL);
return ret;
}
......@@ -462,22 +447,17 @@ static int remove_standalone_rrsigs(const zone_node_t *node,
for (uint16_t i = 0; i < rrsigs_rdata_count; ++i) {
uint16_t type_covered = knot_rrsig_type_covered(&rrsigs->rrs, i);
if (!node_rrtype_exists(node, type_covered)) {
knot_rrset_t *to_remove = knot_rrset_new(rrsigs->owner,
rrsigs->type,
rrsigs->rclass,
NULL);
if (to_remove == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_t to_remove;
knot_rrset_init(&to_remove, rrsigs->owner, rrsigs->type,
rrsigs->rclass);
knot_rdata_t *rr_rem = knot_rdataset_at(&rrsigs->rrs, i);
int ret = knot_rdataset_add(&to_remove->rrs, rr_rem, NULL);
int ret = knot_rdataset_add(&to_remove.rrs, rr_rem, NULL);
if (ret != KNOT_EOK) {
knot_rrset_free(&to_remove, NULL);
return ret;
}
ret = changeset_rem_rrset(changeset, to_remove);
ret = changeset_rem_rrset(changeset, &to_remove);
knot_rdataset_clear(&to_remove.rrs, NULL);
if (ret != KNOT_EOK) {
knot_rrset_free(&to_remove, NULL);
return ret;
}
}
......@@ -686,7 +666,7 @@ static int rrset_add_zone_key(knot_rrset_t *rrset,
const knot_binary_t *key_rdata = &zone_key->dnssec_key.dnskey_rdata;
return knot_rrset_add_rdata(rrset, key_rdata->data, key_rdata->size, ttl,
NULL);
NULL);
}
/*!
......@@ -715,15 +695,16 @@ static int remove_invalid_dnskeys(const knot_rrset_t *soa,
}
assert(dnskeys->type == KNOT_RRTYPE_DNSKEY);
knot_rrset_t *to_remove = NULL;
knot_rrset_t to_remove;
knot_rrset_init(&to_remove, dnskeys->owner, dnskeys->type,
dnskeys->rclass);
int result = KNOT_EOK;
const knot_rdata_t *dnskeys_data = knot_rdataset_at(&dnskeys->rrs, 0);
const knot_rdata_t *soa_data = knot_rdataset_at(&soa->rrs, 0);
if (knot_rdata_ttl(dnskeys_data) != knot_rdata_ttl(soa_data)) {
dbg_dnssec_detail("removing DNSKEYs (SOA TTL differs)\n");
to_remove = knot_rrset_copy(dnskeys, NULL);
result = to_remove ? KNOT_EOK : KNOT_ENOMEM;
result = knot_rdataset_copy(&to_remove.rrs, &dnskeys->rrs, NULL);
goto done;
}
......@@ -748,19 +729,8 @@ static int remove_invalid_dnskeys(const knot_rrset_t *soa,
dbg_dnssec_detail("removing DNSKEY with tag %d\n", keytag);
if (to_remove == NULL) {
to_remove = knot_rrset_new(dnskeys->owner,
dnskeys->type,
dnskeys->rclass,
NULL);
if (to_remove == NULL) {
result = KNOT_ENOMEM;
break;
}
}
knot_rdata_t *to_rem = knot_rdataset_at(&dnskeys->rrs, i);
result = knot_rdataset_add(&to_remove->rrs, to_rem, NULL);
result = knot_rdataset_add(&to_remove.rrs, to_rem, NULL);
if (result != KNOT_EOK) {
break;
}
......@@ -768,13 +738,11 @@ static int remove_invalid_dnskeys(const knot_rrset_t *soa,
done:
if (to_remove != NULL && result == KNOT_EOK) {
result = changeset_rem_rrset(changeset, to_remove);
if (!knot_rrset_empty(&to_remove) && result == KNOT_EOK) {
result = changeset_rem_rrset(changeset, &to_remove);
}
if (to_remove != NULL && result != KNOT_EOK) {
knot_rrset_free(&to_remove, NULL);
}
knot_rdataset_clear(&to_remove.rrs, NULL);
return result;
}
......@@ -786,11 +754,12 @@ done:
*
* \return Empty DNSKEY RR set.
*/
static knot_rrset_t *create_dnskey_rrset_from_soa(const knot_rrset_t *soa)
static knot_rrset_t create_dnskey_rrset_from_soa(const knot_rrset_t *soa)
{
assert(soa);
return knot_rrset_new(soa->owner, KNOT_RRTYPE_DNSKEY, soa->rclass, NULL);
knot_rrset_t rrset;
knot_rrset_init(&rrset, soa->owner, KNOT_RRTYPE_DNSKEY, soa->rclass);
return rrset;
}
/*!
......@@ -814,7 +783,8 @@ static int add_missing_dnskeys(const knot_rrset_t *soa,
assert(zone_keys);
assert(changeset);
knot_rrset_t *to_add = NULL;
knot_rrset_t to_add;
knot_rrset_init_empty(&to_add);
int result = KNOT_EOK;
const knot_rdata_t *dnskeys_data = knot_rdataset_at(&dnskeys->rrs, 0);
const knot_rdata_t *soa_data = knot_rdataset_at(&soa->rrs, 0);
......@@ -835,26 +805,21 @@ static int add_missing_dnskeys(const knot_rrset_t *soa,
dbg_dnssec_detail("adding DNSKEY with tag %d\n",
key->dnssec_key.keytag);
if (to_add == NULL) {
if (knot_rrset_empty(&to_add)) {
to_add = create_dnskey_rrset_from_soa(soa);
if (to_add == NULL) {
return KNOT_ENOMEM;
}
}
result = rrset_add_zone_key(to_add, key, knot_rdata_ttl(soa_data));
result = rrset_add_zone_key(&to_add, key, knot_rdata_ttl(soa_data));
if (result != KNOT_EOK) {
break;
}
}
if (to_add != NULL && result == KNOT_EOK) {
result = changeset_add_rrset(changeset, to_add);
if (!knot_rrset_empty(&to_add) && result == KNOT_EOK) {
result = changeset_add_rrset(changeset, &to_add);
}
if (to_add != NULL && result != KNOT_EOK) {
knot_rrset_free(&to_add, NULL);
}
knot_rdataset_clear(&to_add.rrs, NULL);
return result;
}
......@@ -885,10 +850,7 @@ static int update_dnskeys_rrsigs(const knot_rrset_t *dnskeys,
// We know how the DNSKEYs in zone should look like after applying
// the changeset. RRSIGs can be then built easily.
knot_rrset_t *new_dnskeys = create_dnskey_rrset_from_soa(soa);
if (!new_dnskeys) {
return KNOT_ENOMEM;
}
knot_rrset_t new_dnskeys = create_dnskey_rrset_from_soa(soa);
// add unknown keys from zone
uint16_t dnskeys_rdata_count = dnskeys->rrs.rr_count;
......@@ -902,7 +864,7 @@ static int update_dnskeys_rrsigs(const knot_rrset_t *dnskeys,
}
knot_rdata_t *to_add = knot_rdataset_at(&dnskeys->rrs, i);
result = knot_rdataset_add(&new_dnskeys->rrs, to_add, NULL);
result = knot_rdataset_add(&new_dnskeys.rrs, to_add, NULL);
if (result != KNOT_EOK) {
goto fail;
}
......@@ -917,14 +879,14 @@ static int update_dnskeys_rrsigs(const knot_rrset_t *dnskeys,
}
const knot_rdata_t *soa_data = knot_rdataset_at(&soa->rrs, 0);
result = rrset_add_zone_key(new_dnskeys, key,
result = rrset_add_zone_key(&new_dnskeys, key,
knot_rdata_ttl(soa_data));
if (result != KNOT_EOK) {
goto fail;
}
}
result = add_missing_rrsigs(new_dnskeys, NULL, zone_keys, policy,
result = add_missing_rrsigs(&new_dnskeys, NULL, zone_keys, policy,
changeset);
if (result != KNOT_EOK) {
goto fail;
......@@ -937,7 +899,7 @@ static int update_dnskeys_rrsigs(const knot_rrset_t *dnskeys,
fail:
knot_rrset_free(&new_dnskeys, NULL);
knot_rdataset_clear(&new_dnskeys.rrs, NULL);
return result;
}
......
......@@ -940,8 +940,6 @@ bool journal_exists(const char *path)
static int changesets_unpack(changeset_t *chs)
{
knot_rrset_t *rrset = NULL;
/* Read changeset flags. */
if (chs->data == NULL) {
return KNOT_EMALF;
......@@ -950,20 +948,24 @@ static int changesets_unpack(changeset_t *chs)
/* Read initial changeset RRSet - SOA. */
uint8_t *stream = chs->data + (chs->size - remaining);
knot_rrset_t rrset;
int ret = rrset_deserialize(stream, &remaining, &rrset);
if (ret != KNOT_EOK) {
return KNOT_EMALF;
}
assert(rrset->type == KNOT_RRTYPE_SOA);
chs->soa_from = rrset;
assert(rrset.type == KNOT_RRTYPE_SOA);
chs->soa_from = knot_rrset_copy(&rrset, NULL);
if (chs->soa_from == NULL) {
return KNOT_ENOMEM;
}
/* Read remaining RRSets */
bool in_remove_section = true;
while (remaining > 0) {
/* Parse next RRSet. */
rrset = 0;
knot_rrset_init_empty(&rrset);
stream = chs->data + (chs->size - remaining);
ret = rrset_deserialize(stream, &remaining, &rrset);
if (ret != KNOT_EOK) {
......@@ -971,23 +973,25 @@ static int changesets_unpack(changeset_t *chs)
}
/* Check for next SOA. */
if (rrset->type == KNOT_RRTYPE_SOA) {
if (rrset.type == KNOT_RRTYPE_SOA) {
/* Move to ADD section if in REMOVE. */
if (in_remove_section) {
chs->soa_to = rrset;
chs->soa_to = knot_rrset_copy(&rrset, NULL);
if (chs->soa_to == NULL) {
return KNOT_ENOMEM;
}
in_remove_section = false;
} else {
/* Final SOA. */
knot_rrset_free(&rrset, NULL);
break;
}
} else {
/* Remove RRSets. */
if (in_remove_section) {
ret = changeset_rem_rrset(chs, rrset);
ret = changeset_rem_rrset(chs, &rrset);
} else {
/* Add RRSets. */
ret = changeset_add_rrset(chs, rrset);
ret = changeset_add_rrset(chs, &rrset);
}
}
}
......
......@@ -136,7 +136,7 @@ int rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream, size_t *size)
}
int rrset_deserialize(const uint8_t *stream, size_t *stream_size,
knot_rrset_t **rrset)
knot_rrset_t *rrset)
{
if (sizeof(uint64_t) > *stream_size) {
return KNOT_ESPACE;
......@@ -166,11 +166,7 @@ int rrset_deserialize(const uint8_t *stream, size_t *stream_size,
offset += sizeof(uint16_t);
/* Create new RRSet. */
*rrset = knot_rrset_new(owner, type, rclass, NULL);
knot_dname_free(&owner, NULL);
if (*rrset == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_init(rrset, owner, type, rclass);
/* Read RRs. */
for (uint16_t i = 0; i < rdata_count; i++) {
......@@ -181,9 +177,9 @@ int rrset_deserialize(const uint8_t *stream, size_t *stream_size,
uint32_t rdata_size = 0;
memcpy(&rdata_size, stream + offset, sizeof(uint32_t));
offset += sizeof(uint32_t);
int ret = deserialize_rr((*rrset), stream + offset, rdata_size);
int ret = deserialize_rr(rrset, stream + offset, rdata_size);
if (ret != KNOT_EOK) {
knot_rrset_free(rrset, NULL);
knot_rrset_clear(rrset, NULL);
return ret;
}
offset += rdata_size;
......
......@@ -61,5 +61,5 @@ int rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream, size_t *size);
* \return KNOT_E*
*/
int rrset_deserialize(const uint8_t *stream, size_t *stream_size,
knot_rrset_t **rrset);
knot_rrset_t *rrset);
......@@ -135,7 +135,7 @@ static bool rr_exists(const knot_rrset_t *in, const knot_rrset_t *ref,
static int knot_zone_diff_rdata_return_changes(const knot_rrset_t *rrset1,
const knot_rrset_t *rrset2,
knot_rrset_t **changes)
knot_rrset_t *changes)
{
if (rrset1 == NULL || rrset2 == NULL) {
dbg_zonediff("zone_diff: diff_rdata: NULL arguments. (%p) (%p).\n",
......@@ -150,15 +150,9 @@ static int knot_zone_diff_rdata_return_changes(const knot_rrset_t *rrset1,
* After the list has been traversed, we have a list of
* changed/removed rdatas. This has awful computation time.
*/
/* Create fake RRSet, it will be easier to handle. */
*changes = knot_rrset_new(rrset1->owner, rrset1->type,
rrset1->rclass, NULL);
if (*changes == NULL) {
dbg_zonediff("zone_diff: diff_rdata: "
"Could not create RRSet with changes.\n");
return KNOT_ENOMEM;
}
/* Create fake RRSet, it will be easier to handle. */
knot_rrset_init(changes, rrset1->owner, rrset1->type, rrset1->rclass);
const rdata_descriptor_t *desc = get_rdata_descriptor(rrset1->type);
assert(desc);
......@@ -171,9 +165,9 @@ static int knot_zone_diff_rdata_return_changes(const knot_rrset_t *rrset1,
* index 'i' into 'changes' RRSet.
*/
knot_rdata_t *add_rr = knot_rdataset_at(&rrset1->rrs, i);
int ret = knot_rdataset_add(&(*changes)->rrs, add_rr, NULL);
int ret = knot_rdataset_add(&changes->rrs, add_rr, NULL);