diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c index 73b6648a6341756bb94d4fecaac2de2fbfcf3a88..95a2b318cf0050ea17b5da5131ec2caeaa009e13 100644 --- a/src/libknot/nameserver/name-server.c +++ b/src/libknot/nameserver/name-server.c @@ -941,8 +941,8 @@ static int ns_put_authority_soa(const knot_zone_contents_t *zone, static knot_dname_t *ns_next_closer(const knot_dname_t *closest_encloser, const knot_dname_t *name) { - int ce_labels = knot_dname_wire_labels(closest_encloser->name, NULL); - int qname_labels = knot_dname_wire_labels(name->name, NULL); + int ce_labels = knot_dname_wire_labels(closest_encloser, NULL); + int qname_labels = knot_dname_wire_labels(name, NULL); assert(ce_labels < qname_labels); @@ -2020,9 +2020,9 @@ static int ns_dname_is_too_long(const knot_rrset_t *rrset, const knot_dname_t *qname) { // TODO: add function for getting DNAME target - if (knot_dname_wire_labels(qname->name, NULL) - - knot_dname_wire_labels(knot_rrset_owner(rrset)->name, NULL) - + knot_dname_wire_labels(knot_rrset_rdata_dname_target(rrset)->name, NULL) + if (knot_dname_wire_labels(qname, NULL) + - knot_dname_wire_labels(knot_rrset_owner(rrset), NULL) + + knot_dname_wire_labels(knot_rrset_rdata_dname_target(rrset), NULL) > KNOT_MAX_DNAME_LENGTH) { return 1; } else { diff --git a/src/libknot/packet/packet.c b/src/libknot/packet/packet.c index 1b7d1d06650adec6bbadc4b46d5d5fa3df3c69f4..6e1cbbb9801961e727aef7849e9731d51bba4b32 100644 --- a/src/libknot/packet/packet.c +++ b/src/libknot/packet/packet.c @@ -281,12 +281,12 @@ dbg_packet_exec_detail( ); if (knot_rrset_equal((*rrsets)[i], rrset, - KNOT_RRSET_COMPARE_HEADER)) { + KNOT_RRSET_COMPARE_HEADER)) { /*! \todo Test this!!! */ // no duplicate checking here, the packet should // look exactly as it came from wire - int rc = knot_rrset_merge( - ((knot_rrset_t *)(*rrsets)[i]), rrset); + int rc = + knot_rrset_merge((knot_rrset_t *)(*rrsets)[i], rrset); if (rc != KNOT_EOK) { return rc; } diff --git a/src/libknot/packet/response.c b/src/libknot/packet/response.c index 422454ecf8d6edc4893cae6ad3f30cae3b0a066b..a5fa9173112c161ae17ecbec0a8f7c99c57406d0 100644 --- a/src/libknot/packet/response.c +++ b/src/libknot/packet/response.c @@ -74,13 +74,14 @@ int knot_response_compress_dname(const knot_dname_t *dname, knot_compr_t *compr, } /* Do not compress small dnames. */ - uint8_t *name = dname->name; + const uint8_t *name = dname; unsigned name_labels = knot_dname_wire_labels(name, NULL); - if (dname->size <= 2) { - if (dname->size > max) - return KNOT_ESPACE; - memcpy(dst, name, dname->size); - return dname->size; + uint8_t dname_size = knot_dname_wire_size(name, NULL); + if (dname_size <= 2) { + if (dname_size > max) + return KNOT_ESPACE; + memcpy(dst, name, dname_size); + return dname_size; } /* Align and compare name and pointer in the compression table. */ @@ -89,7 +90,7 @@ int knot_response_compress_dname(const knot_dname_t *dname, knot_compr_t *compr, unsigned match_id = 0; knot_compr_ptr_t match = { 0, 0 }; for (; i < COMPR_MAXLEN && compr->table[i].off > 0; ++i) { - const uint8_t *sample = dname->name; + const uint8_t *sample = dname; const uint8_t *ref = compr->wire + compr->table[i].off; lbcount = knot_dname_align(&sample, name_labels, &ref, compr->table[i].lbcount, diff --git a/src/libknot/rrset.c b/src/libknot/rrset.c index 4d02455d357cc121823633f0edabb9370e978786..b22982974b9035bedd659c50c41b02584ccdf5b1 100644 --- a/src/libknot/rrset.c +++ b/src/libknot/rrset.c @@ -25,16 +25,13 @@ #include "common.h" #include "common/mempattern.h" #include "rrset.h" +#include "libknot/rrset-dump.h" #include "common/descriptor.h" #include "util/debug.h" #include "util/utils.h" #include "packet/response.h" #include "util/wire.h" -/*----------------------------------------------------------------------------*/ -/* Non-API functions */ -/*----------------------------------------------------------------------------*/ - static int rrset_retain_dnames_in_rr(knot_dname_t **dname, void *data) { UNUSED(data); @@ -787,9 +784,6 @@ int knot_rrset_remove_rdata_pos(knot_rrset_t *rrset, size_t pos) * Handle RDATA indices. All indices larger than the removed one * have to be adjusted. Last index will be changed later. */ - /* [code-review] The upper bound should be rdata_count - 2, it - * has not yet been adjusted. - */ for (uint16_t i = pos; i < rrset->rdata_count - 1; ++i) { rrset->rdata_indices[i] = rrset->rdata_indices[i + 1] - removed_size; } @@ -811,10 +805,6 @@ int knot_rrset_remove_rdata_pos(knot_rrset_t *rrset, size_t pos) return KNOT_EOK; } -/*----------------------------------------------------------------------------*/ -/* API functions */ -/*----------------------------------------------------------------------------*/ - uint32_t rrset_rdata_size_total(const knot_rrset_t *rrset) { if (rrset == NULL || rrset->rdata_indices == NULL || @@ -822,7 +812,7 @@ uint32_t rrset_rdata_size_total(const knot_rrset_t *rrset) return 0; } - /* Last index denotes end of all RRs. */ + // Last index denotes end of all RRs. return (rrset->rdata_indices[rrset->rdata_count - 1]); } @@ -835,7 +825,7 @@ knot_rrset_t *knot_rrset_new(knot_dname_t *owner, uint16_t type, ret->rdata_count = 0; ret->rdata_indices = NULL; - /* Retain reference to owner. */ + // Retain reference to owner. knot_dname_retain(owner); ret->owner = owner; @@ -860,6 +850,76 @@ int knot_rrset_add_rdata(knot_rrset_t *rrset, return KNOT_EOK; } +static uint8_t* knot_rrset_create_rdata_at_pos(knot_rrset_t *rrset, + size_t pos, uint16_t size) +{ + if (rrset == NULL || size == 0 || pos > rrset->rdata_count) { + return NULL; + } + if (pos == rrset->rdata_count) { + return knot_rrset_create_rdata(rrset, size); + } + + uint32_t total_size = rrset_rdata_size_total(rrset); + + // Realloc actual data. + void *tmp = realloc(rrset->rdata, total_size + size); + if (tmp) { + rrset->rdata = tmp; + } else { + ERR_ALLOC_FAILED; + return NULL; + } + + /* + * Move already existing data to from position we want to add to. + * But only if we don't want to add new item after last item. + */ + uint8_t *old_pointer = rrset_rdata_pointer(rrset, pos); + assert(old_pointer); + memmove(old_pointer + size, old_pointer, + rrset_rdata_size_total(rrset) - rrset_rdata_offset(rrset, pos)); + + // Realloc indices. We will allocate exact size to save space. + tmp = realloc(rrset->rdata_indices, + (rrset->rdata_count + 1) * sizeof(uint32_t)); + if (tmp) { + rrset->rdata_indices = tmp; + } else { + ERR_ALLOC_FAILED; + return NULL; + } + // Move indices. + memmove(rrset->rdata_indices + pos + 1, rrset->rdata_indices + pos, + (rrset->rdata_count - pos) * sizeof(uint32_t)); + // Init new index + rrset->rdata_indices[pos] = pos ? rrset->rdata_indices[pos - 1] : 0; + ++rrset->rdata_count; + // Adjust all following items + for (uint16_t i = pos; i < rrset->rdata_count; ++i) { + rrset->rdata_indices[i] += size; + } + + // Return pointer from correct position (now contains bogus data). + return old_pointer; +} + +int knot_rrset_add_rdata_at_pos(knot_rrset_t *rrset, size_t pos, + const uint8_t *rdata, uint16_t size) +{ + if (rrset == NULL || rdata == NULL || size == 0) { + return KNOT_EINVAL; + } + + uint8_t *p = knot_rrset_create_rdata_at_pos(rrset, pos, size); + if (p == NULL) { + return KNOT_ERROR; + } + memcpy(p, rdata, size); + + return KNOT_EOK; +} + /*----------------------------------------------------------------------------*/ uint8_t* knot_rrset_create_rdata(knot_rrset_t *rrset, uint16_t size) @@ -871,8 +931,6 @@ uint8_t* knot_rrset_create_rdata(knot_rrset_t *rrset, uint16_t size) uint32_t total_size = rrset_rdata_size_total(rrset); /* Realloc indices. We will allocate exact size to save space. */ - /* TODO this sucks big time - allocation of length 1. */ - /* But another variable holding allocated count is out of question. What now?*/ rrset->rdata_indices = xrealloc(rrset->rdata_indices, (rrset->rdata_count + 1) * sizeof(uint32_t)); @@ -916,8 +974,6 @@ uint16_t rrset_rdata_item_size(const knot_rrset_t *rrset, return rrset->rdata_indices[pos] - rrset->rdata_indices[pos - 1]; } -/*----------------------------------------------------------------------------*/ - int knot_rrset_set_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs) { if (rrset == NULL) { @@ -928,8 +984,6 @@ int knot_rrset_set_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs) return KNOT_EOK; } -/*----------------------------------------------------------------------------*/ - int knot_rrset_add_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs, knot_rrset_dupl_handling_t dupl) { @@ -942,8 +996,8 @@ int knot_rrset_add_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs, if (rrset->rrsigs != NULL) { if (dupl == KNOT_RRSET_DUPL_MERGE) { int merged, deleted_rrs; - rc = knot_rrset_merge_no_dupl(rrset->rrsigs, rrsigs, - &merged, &deleted_rrs); + rc = knot_rrset_merge_sort(rrset->rrsigs, rrsigs, + &merged, &deleted_rrs); if (rc != KNOT_EOK) { return rc; } else if (merged || deleted_rrs) { @@ -966,22 +1020,16 @@ int knot_rrset_add_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs, return KNOT_EOK; } -/*----------------------------------------------------------------------------*/ - const knot_dname_t *knot_rrset_owner(const knot_rrset_t *rrset) { return rrset->owner; } -/*----------------------------------------------------------------------------*/ - knot_dname_t *knot_rrset_get_owner(const knot_rrset_t *rrset) { return rrset->owner; } -/*----------------------------------------------------------------------------*/ - void knot_rrset_set_owner(knot_rrset_t *rrset, knot_dname_t *owner) { if (rrset) { @@ -992,8 +1040,6 @@ void knot_rrset_set_owner(knot_rrset_t *rrset, knot_dname_t *owner) } } -/*----------------------------------------------------------------------------*/ - void knot_rrset_set_ttl(knot_rrset_t *rrset, uint32_t ttl) { if (rrset) { @@ -1001,36 +1047,26 @@ void knot_rrset_set_ttl(knot_rrset_t *rrset, uint32_t ttl) } } -/*----------------------------------------------------------------------------*/ - uint16_t knot_rrset_type(const knot_rrset_t *rrset) { return rrset->type; } -/*----------------------------------------------------------------------------*/ - uint16_t knot_rrset_class(const knot_rrset_t *rrset) { return rrset->rclass; } -/*----------------------------------------------------------------------------*/ - uint32_t knot_rrset_ttl(const knot_rrset_t *rrset) { return rrset->ttl; } -/*----------------------------------------------------------------------------*/ - uint8_t *knot_rrset_get_rdata(const knot_rrset_t *rrset, size_t rdata_pos) { return rrset_rdata_pointer(rrset, rdata_pos); } -/*----------------------------------------------------------------------------*/ - uint16_t knot_rrset_rdata_rr_count(const knot_rrset_t *rrset) { if (rrset != NULL) { @@ -1040,8 +1076,6 @@ uint16_t knot_rrset_rdata_rr_count(const knot_rrset_t *rrset) } } -/*----------------------------------------------------------------------------*/ - const knot_rrset_t *knot_rrset_rrsigs(const knot_rrset_t *rrset) { if (rrset == NULL) { @@ -1051,8 +1085,6 @@ const knot_rrset_t *knot_rrset_rrsigs(const knot_rrset_t *rrset) } } -/*----------------------------------------------------------------------------*/ - knot_rrset_t *knot_rrset_get_rrsigs(knot_rrset_t *rrset) { if (rrset == NULL) { @@ -1099,8 +1131,6 @@ int knot_rrset_rdata_equal(const knot_rrset_t *r1, const knot_rrset_t *r2) return 1; } -/*----------------------------------------------------------------------------*/ - int knot_rrset_to_wire(const knot_rrset_t *rrset, uint8_t *wire, size_t *size, size_t max_size, uint16_t *rr_count, void *data) { @@ -1138,8 +1168,6 @@ dbg_rrset_exec_detail( return KNOT_EOK; } -/*----------------------------------------------------------------------------*/ - int knot_rrset_rdata_from_wire_one(knot_rrset_t *rrset, const uint8_t *wire, size_t *pos, size_t total_size, size_t rdlength) @@ -1164,9 +1192,6 @@ int knot_rrset_rdata_from_wire_one(knot_rrset_t *rrset, } } - /* [code-review] Isn't this invalid? You cannot do static allocation - * with dynamic data (parameter, local variable). - */ uint8_t rdata_buffer[rdlength + extra_dname_size]; memset(rdata_buffer, 0, rdlength + extra_dname_size); dbg_rrset_detail("rr: parse_rdata_wire: Added %zu bytes to buffer to " @@ -1427,7 +1452,6 @@ void knot_rrset_free(knot_rrset_t **rrset) return; } - /*! \todo Shouldn't we always release owner reference? */ knot_dname_release((*rrset)->owner); free(*rrset); @@ -1487,123 +1511,119 @@ void knot_rrset_deep_free_no_sig(knot_rrset_t **rrset, int free_owner, *rrset = NULL; } -int knot_rrset_merge(knot_rrset_t *rrset1, const knot_rrset_t *rrset2) +static int knot_rrset_add_rr_n(knot_rrset_t *rrset, const knot_rrset_t *rr, + size_t pos) { - if (rrset1 == NULL || rrset2 == NULL) { + if (rrset == NULL || rr == NULL) { return KNOT_EINVAL; } - - /* Check, that we really merge RRSets? */ - if (rrset1->type != rrset2->type || - rrset1->rclass != rrset2->rclass || - (knot_dname_compare_non_canon(rrset1->owner, rrset2->owner) != 0)) { + if (!knot_rrset_equal(rrset, rr, KNOT_RRSET_COMPARE_HEADER)) { + // Adding to a different header return KNOT_EINVAL; } - /* Merging empty RRSets is OK. */ - if (rrset1->rdata_count == 0 && rrset2->rdata_count == 0) { - return KNOT_EOK; + uint8_t *new_rdata = + knot_rrset_create_rdata(rrset, + rrset_rdata_item_size(rr, pos)); + if (new_rdata == NULL) { + return KNOT_ERROR; } - /* Add all RDATAs from rrset2 to rrset1 (i.e. concatenate two arrays) */ - - /*! \note The following code should work for - * all the cases i.e. R1 or R2 are empty. - */ - - /* Reallocate actual RDATA array. */ - rrset1->rdata = xrealloc(rrset1->rdata, rrset_rdata_size_total(rrset1) + - rrset_rdata_size_total(rrset2)); - - /* The space is ready, copy the actual data. */ - memcpy(rrset1->rdata + rrset_rdata_size_total(rrset1), - rrset2->rdata, rrset_rdata_size_total(rrset2)); - - /* Indices have to be readjusted. But space has to be made first. */ - rrset1->rdata_indices = - xrealloc(rrset1->rdata_indices, - (rrset1->rdata_count + rrset2->rdata_count) * - sizeof(uint32_t)); - - uint32_t rrset1_total_size = rrset_rdata_size_total(rrset1); - uint32_t rrset2_total_size = rrset_rdata_size_total(rrset2); + memcpy(new_rdata, rrset_rdata_pointer(rr, pos), + rrset_rdata_item_size(rr, pos)); - /* - * Move the indices. Discard the last item in the first array, as it - * contains total length of the data, which is now different. - */ - memcpy(rrset1->rdata_indices + rrset1->rdata_count, - rrset2->rdata_indices, rrset2->rdata_count); + return KNOT_EOK; +} - /* Go through the second part of index array and adjust offsets. */ - for (uint16_t i = 0; i < rrset2->rdata_count - 1; i++) { - rrset1->rdata_indices[rrset1->rdata_count + i] += - rrset1_total_size; +int knot_rrset_merge(knot_rrset_t *rrset1, const knot_rrset_t *rrset2) +{ + for (uint16_t i = 0; i < rrset2->rdata_count; ++i) { + int ret = knot_rrset_add_rr_n(rrset1, rrset2, i); + if (ret != KNOT_EOK) { + return ret; + } } - rrset1->rdata_indices[rrset1->rdata_count + rrset2->rdata_count - 1] = - rrset1_total_size + rrset2_total_size; - - rrset1->rdata_count += rrset2->rdata_count; - return KNOT_EOK; } -int knot_rrset_merge_no_dupl(knot_rrset_t *rrset1, const knot_rrset_t *rrset2, - int *merged, int *deleted_rrs) +static int knot_rrset_add_rr_sort_n(knot_rrset_t *rrset, const knot_rrset_t *rr, + int *merged, int *deleted_rr, size_t pos) { - if (rrset1 == NULL || rrset2 == NULL) { - dbg_rrset("rrset: merge_no_dupl: NULL arguments."); + if (rrset == NULL || rr == NULL) { + dbg_rrset("rrset: add_rr_sort: NULL arguments."); return KNOT_EINVAL; } dbg_rrset_exec_detail( - char *name = knot_dname_to_str(rrset1->owner); - dbg_rrset_detail("rrset: merge_no_dupl: Merging %s.\n", name); + char *name = knot_dname_to_str(rrset->owner); + dbg_rrset_detail("rrset: add_rr_sort: Merging %s.\n", name); free(name); ); - if ((knot_dname_compare_non_canon(rrset1->owner, rrset2->owner) != 0) - || rrset1->rclass != rrset2->rclass - || rrset1->type != rrset2->type) { - dbg_rrset("rrset: merge_no_dupl: Trying to merge " + if ((knot_dname_compare_non_canon(rrset->owner, rr->owner) != 0) + || rrset->rclass != rr->rclass + || rrset->type != rr->type) { + dbg_rrset("rrset: add_rr_sort: Trying to merge " "different RRs.\n"); return KNOT_EINVAL; } - *deleted_rrs = 0; + *deleted_rr = 0; *merged = 0; - /* For each item in second RRSet, make sure it is not duplicated. */ - for (uint16_t i = 0; i < rrset2->rdata_count; i++) { - int duplicated = 0; - /* Compare with all RRs in the first RRSet. */ - for (uint16_t j = 0; j < rrset1->rdata_count && !duplicated; - j++) { - duplicated = !rrset_rdata_compare_one(rrset1, rrset2, - j, i); + int found = 0; + int duplicated = 0; + // Compare RR with all RRs in the first RRSet. + size_t insert_to = 0; + for (uint16_t j = 0; j < rrset->rdata_count && (!duplicated && !found); ++j) { + int cmp = rrset_rdata_compare_one(rrset, rr, j, pos); + if (cmp == 0) { + // Duplication - no need to merge this RR + duplicated = 1; + } else if (cmp > 0) { + // Found position to insert + found = 1; + } else { + // Not yet - it might be next position + insert_to = j + 1; } + } - if (!duplicated) { - *merged += 1; // = need to shallow free rrset2 - // This index goes to merged RRSet. - int ret = knot_rrset_add_rdata(rrset1, - rrset_rdata_pointer(rrset2, i), - rrset_rdata_item_size(rrset2, i)); - if (ret != KNOT_EOK) { - dbg_rrset("rrset: merge_no_dupl: Could not " - "add RDATA to RRSet. (%s)\n", - knot_strerror(ret)); - return ret; - } - } else { - *deleted_rrs += 1; // = need to shallow free rrset2 + if (!duplicated) { + *merged += 1; // = need to shallow free rrset2 + // Insert RR to RRSet + int ret = knot_rrset_add_rdata_at_pos(rrset, insert_to, + rrset_rdata_pointer(rr, pos), + rrset_rdata_item_size(rr, pos)); + if (ret != KNOT_EOK) { + dbg_rrset("rrset: add_rr: Could not " + "add RDATA to RRSet. (%s)\n", + knot_strerror(ret)); + return ret; } + } else { + assert(!found); + *deleted_rr = 1; // = need to shallow free rr } return KNOT_EOK; } -/*----------------------------------------------------------------------------*/ +int knot_rrset_merge_sort(knot_rrset_t *rrset1, const knot_rrset_t *rrset2, + int *merged, int *deleted_rrs) +{ + for (uint16_t i = 0; i < rrset2->rdata_count; ++i) { + int deleted = 0; + int ret = knot_rrset_add_rr_sort_n(rrset1, rrset2, merged, + &deleted, i); + if (ret != KNOT_EOK) { + return ret; + } + *deleted_rrs += deleted ? 1 : 0; + } + + return KNOT_EOK; +} const knot_dname_t *knot_rrset_rdata_cname_name(const knot_rrset_t *rrset) { @@ -1616,8 +1636,6 @@ const knot_dname_t *knot_rrset_rdata_cname_name(const knot_rrset_t *rrset) return dname; } -/*----------------------------------------------------------------------------*/ - const knot_dname_t *knot_rrset_rdata_dname_target(const knot_rrset_t *rrset) { if (rrset == NULL) { @@ -1628,8 +1646,6 @@ const knot_dname_t *knot_rrset_rdata_dname_target(const knot_rrset_t *rrset) return dname; } -/*---------------------------------------------------------------------------*/ - const knot_dname_t *knot_rrset_rdata_soa_primary_ns(const knot_rrset_t *rrset) { if (rrset == NULL) { @@ -2192,7 +2208,7 @@ uint64_t rrset_binary_size(const knot_rrset_t *rrset) sizeof(uint16_t) + // class sizeof(uint32_t) + // ttl sizeof(uint16_t) + //RR count - sizeof(uint32_t) * rrset->rdata_count; //RR indices + sizeof(uint32_t) * rrset->rdata_count; // RR indices for (uint16_t i = 0; i < rrset->rdata_count; i++) { /* Space to store length of one RR. */ size += sizeof(uint32_t); @@ -2442,10 +2458,9 @@ int knot_rrset_find_rr_pos(const knot_rrset_t *rr_search_in, return found ? KNOT_EOK : KNOT_ENOENT; } -int knot_rrset_remove_rr(knot_rrset_t *rrset, - const knot_rrset_t *rr_from, size_t rdata_pos) +static int knot_rrset_remove_rr(knot_rrset_t *rrset, + const knot_rrset_t *rr_from, size_t rdata_pos) { - /* [code-review] Missing parameter checks. */ /* * Position in first and second rrset can differ, we have * to search for position first. @@ -2473,7 +2488,7 @@ int knot_rrset_remove_rr(knot_rrset_t *rrset, return KNOT_EOK; } -int knot_rrset_rdata_reset(knot_rrset_t *rrset) +static int knot_rrset_rdata_reset(knot_rrset_t *rrset) { if (rrset == NULL) { return KNOT_EINVAL; @@ -2633,18 +2648,18 @@ int knot_rrset_remove_rr_using_rrset_del(knot_rrset_t *from, int ret = knot_rrset_remove_rr_using_rrset(from, what, &rr_removed, 0); knot_rrset_deep_free(&rr_removed, 1, 1); return ret; -// for (uint16_t i = 0; i < what->rdata_count; ++i) { -// int ret = knot_rrset_remove_rr(from, what, i); -// if (ret != KNOT_ENOENT || ret != KNOT_EOK) { -// /* NOENT is OK, but other errors are not. */ -// dbg_rrset("rrset: remove_rr_using_rrset: " -// "RRSet removal failed (%s).\n", -// knot_strerror(ret)); -// return ret; -// } -// } - -// return KNOT_EOK; + for (uint16_t i = 0; i < what->rdata_count; ++i) { + int ret = knot_rrset_remove_rr(from, what, i); + if (ret != KNOT_ENOENT || ret != KNOT_EOK) { + /* NOENT is OK, but other errors are not. */ + dbg_rrset("rrset: remove_rr_using_rrset: " + "RRSet removal failed (%s).\n", + knot_strerror(ret)); + return ret; + } + } + + return KNOT_EOK; } void knot_rrset_set_class(knot_rrset_t *rrset, uint16_t rclass) diff --git a/src/libknot/rrset.h b/src/libknot/rrset.h index 2b0cb6bd6b7d88a2140f4faff5ef2507aea10ccf..db7a2a395590e4927e07e53297ba8231faa54560 100644 --- a/src/libknot/rrset.h +++ b/src/libknot/rrset.h @@ -59,7 +59,6 @@ struct knot_rrset { /*! \brief Beginnings of RRs - first one does not contain 0, last * last one holds total length of all RRs together */ - /* [code-review] Does this have to be 32b integer? Isn't 16b enough? */ uint32_t *rdata_indices; /*!< Indices to beginnings of RRs (without 0)*/ uint16_t rdata_count; /*!< Count of RRs in this RRSet. */ struct knot_rrset *rrsigs; /*!< Set of RRSIGs covering this RRSet. */ @@ -165,7 +164,7 @@ int knot_rrset_set_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs); */ //TODO test int knot_rrset_add_rrsigs(knot_rrset_t *rrset, knot_rrset_t *rrsigs, - knot_rrset_dupl_handling_t dupl); + knot_rrset_dupl_handling_t dupl); /*! * \brief Returns the Owner of the RRSet. @@ -329,67 +328,29 @@ void knot_rrset_deep_free_no_sig(knot_rrset_t **rrset, int free_owner, int knot_rrset_to_wire(const knot_rrset_t *rrset, uint8_t *wire, size_t *size, size_t max_size, uint16_t *rr_count, void *comp_data); -/*! - * \brief Merges two RRSets. - * - * Merges \a r1 into \a r2 by concatenating the list of RDATAs in \a r2 after - * the list of RDATAs in \a r1. You must not - * destroy the RDATAs in \a r2 as they are now identical to RDATAs in \a r1. - * (You may use function knot_rrset_free() though, as it does not touch RDATAs). - * - * \note Member \a rrsigs is preserved from the first RRSet. - * - * \param r1 Pointer to RRSet to be merged into. - * \param r2 Poitner to RRSet to be merged. - * - * \retval KNOT_EOK - * \retval KNOT_EINVAL if the RRSets could not be merged, because their - * Owner, Type, Class or TTL does not match. - */ -int knot_rrset_merge(knot_rrset_t *rrset1, const knot_rrset_t *rrset2); - - -/*! - * \brief Merges two RRSets, but will only merge unique items. - * - * \param r1 Pointer to RRSet to be merged into. - * \param r2 Poitner to RRSet to be merged. - * - * \retval KNOT_EOK - * \retval KNOT_EINVAL if the RRSets could not be merged, because their - * Owner, Type, Class or TTL does not match. - */ -int knot_rrset_merge_no_dupl(knot_rrset_t *rrset1, const knot_rrset_t *rrset2, int *merged, int *deleted_rrs); +int knot_rrset_add_rr(knot_rrset_t *rrset, const knot_rrset_t *rr); +int knot_rrset_add_rr_sort(knot_rrset_t *rrset, const knot_rrset_t *rr, + int *merged, int *deleted_rr); +int knot_rrset_merge(knot_rrset_t *rrset1, const knot_rrset_t *rrset2); +int knot_rrset_merge_sort(knot_rrset_t *rrset1, const knot_rrset_t *rrset2, + int *merged, int *deleted_rrs); -//TODO test const knot_dname_t *knot_rrset_rdata_cname_name(const knot_rrset_t *rrset); -//TODO test const knot_dname_t *knot_rrset_rdata_dname_target(const knot_rrset_t *rrset); -//TODO test void knot_rrset_rdata_set_cname_name(knot_rrset_t *rrset, const knot_dname_t *name); -//TODO test void knot_rrset_rdata_set_dname_target(knot_rrset_t *rrset, const knot_dname_t *target); -//TODO test const knot_dname_t *knot_rrset_rdata_soa_primary_ns(const knot_rrset_t *rrset); -//TODO test const knot_dname_t *knot_rrset_rdata_soa_mailbox(const knot_rrset_t *rrset); uint32_t knot_rrset_rdata_soa_serial(const knot_rrset_t *rrset); -//TODO test void knot_rrset_rdata_soa_serial_set(knot_rrset_t *rrset, uint32_t serial); -//TODO test uint32_t knot_rrset_rdata_soa_refresh(const knot_rrset_t *rrset); -//TODO test uint32_t knot_rrset_rdata_soa_retry(const knot_rrset_t *rrset); -//TODO test uint32_t knot_rrset_rdata_soa_expire(const knot_rrset_t *rrset); -//TODO test uint32_t knot_rrset_rdata_soa_minimum(const knot_rrset_t *rrset); -//TODO test uint16_t knot_rrset_rdata_rrsig_type_covered(const knot_rrset_t *rrset); -/* TODO not all of these need to have rr_pos as a parameter. */ uint8_t knot_rrset_rdata_rrsig_algorithm(const knot_rrset_t *rrset, size_t rr_pos); uint8_t knot_rrset_rdata_rrsig_labels(const knot_rrset_t *rrset, size_t rr_pos); @@ -416,32 +377,22 @@ void knot_rrset_rdata_nsec_bitmap(const knot_rrset_t *rrset, size_t rr_pos, void knot_rrset_rdata_nsec3_bitmap(const knot_rrset_t *rrset, size_t rr_pos, uint8_t **bitmap, uint16_t *size); -//TODO test uint8_t knot_rrset_rdata_nsec3_algorithm(const knot_rrset_t *rrset, size_t pos); uint8_t knot_rrset_rdata_nsec3_flags(const knot_rrset_t *rrset, size_t pos); -//TODO test uint16_t knot_rrset_rdata_nsec3_iterations(const knot_rrset_t *rrset, size_t pos); -//TODO test uint8_t knot_rrset_rdata_nsec3_salt_length(const knot_rrset_t *rrset, size_t pos); -// TODO same as salt, size and data void knot_rrset_rdata_nsec3_next_hashed(const knot_rrset_t *rrset, size_t pos, uint8_t **name, uint8_t *name_size); -//TODO test const uint8_t *knot_rrset_rdata_nsec3_salt(const knot_rrset_t *rrset, size_t pos); -//TODO test uint8_t knot_rrset_rdata_nsec3param_algorithm(const knot_rrset_t *rrset); -//TODO test uint8_t knot_rrset_rdata_nsec3param_flags(const knot_rrset_t *rrset); -//TODO test uint16_t knot_rrset_rdata_nsec3param_iterations(const knot_rrset_t *rrset); -//TODO test uint8_t knot_rrset_rdata_nsec3param_salt_length(const knot_rrset_t *rrset); -//TODO test const uint8_t *knot_rrset_rdata_nsec3param_salt(const knot_rrset_t *rrset); const knot_dname_t *knot_rrset_rdata_rp_first_dname(const knot_rrset_t *rrset, @@ -458,6 +409,7 @@ const knot_dname_t *knot_rrset_rdata_minfo_second_dname(const knot_rrset_t *rrse * * \param rrset Inspected rrset. * \param prev_dname Pointer to previous dname. + * This pointer *has* to be obtained by this function or be NULL. * \return next dname or NULL. */ /* [code-review] Emphasize that the 'prev' pointer must point into the RDATA @@ -478,16 +430,12 @@ knot_dname_t **knot_rrset_get_next_dname(const knot_rrset_t *rrset, knot_dname_t **knot_rrset_get_next_rr_dname(const knot_rrset_t *rrset, knot_dname_t **prev_dname, size_t rr_pos); - const knot_dname_t *knot_rrset_rdata_ns_name(const knot_rrset_t *rrset, size_t rdata_pos); - const knot_dname_t *knot_rrset_rdata_mx_name(const knot_rrset_t *rrset, size_t rdata_pos); - const knot_dname_t *knot_rrset_rdata_srv_name(const knot_rrset_t *rrset, size_t rdata_pos); - const knot_dname_t *knot_rrset_rdata_name(const knot_rrset_t *rrset, size_t rdata_pos); @@ -505,11 +453,6 @@ int rrset_serialize_alloc(const knot_rrset_t *rrset, uint8_t **stream, int rrset_deserialize(uint8_t *stream, size_t *stream_size, knot_rrset_t **rrset); -int knot_rrset_remove_rr(knot_rrset_t *dest, - const knot_rrset_t *source, size_t rdata_pos); - -int knot_rrset_rdata_reset(knot_rrset_t *rrset); - int knot_rrset_add_rr_from_rrset(knot_rrset_t *dest, const knot_rrset_t *source, size_t rdata_pos); diff --git a/src/libknot/updates/ddns.c b/src/libknot/updates/ddns.c index 7f4f14fc58609b5a1eef1c1ea8072052f92d43fa..3e380a3e25d18b797d7ba7bd80ece014d43115ec 100644 --- a/src/libknot/updates/ddns.c +++ b/src/libknot/updates/ddns.c @@ -76,7 +76,7 @@ static int knot_ddns_add_prereq_rrset(const knot_rrset_t *rrset, int ret; for (int i = 0; i < *count; ++i) { if (knot_rrset_equal(rrset, (*rrsets)[i], - KNOT_RRSET_COMPARE_HEADER) == 1) { + KNOT_RRSET_COMPARE_HEADER)) { ret = knot_rrset_merge((*rrsets)[i], rrset); if (ret != KNOT_EOK) { return ret; @@ -1263,8 +1263,8 @@ static int knot_ddns_add_rr_merge_normal(knot_rrset_t *node_rrset_copy, int rdata_in_copy = knot_rrset_rdata_rr_count(*rr_copy); int merged, deleted_rrs; - int ret = knot_rrset_merge_no_dupl(node_rrset_copy, *rr_copy, &merged, - &deleted_rrs); + int ret = knot_rrset_merge_sort(node_rrset_copy, *rr_copy, &merged, + &deleted_rrs); dbg_ddns_detail("Merge returned: %d\n", ret); if (ret != KNOT_EOK) { @@ -1330,8 +1330,8 @@ static int knot_ddns_add_rr_merge_rrsig(knot_rrset_t *node_rrset_copy, int rdata_in_copy = knot_rrset_rdata_rr_count(*rr_copy); int merged, deleted_rrs; - ret = knot_rrset_merge_no_dupl(rrsigs_copy, *rr_copy, &merged, - &deleted_rrs); + ret = knot_rrset_merge_sort(rrsigs_copy, *rr_copy, &merged, + &deleted_rrs); if (ret < 0) { dbg_xfrin("Failed to merge UPDATE RRSIG to copy: %s.\n", knot_strerror(ret)); diff --git a/src/libknot/updates/xfr-in.c b/src/libknot/updates/xfr-in.c index eff8ced69430124a2edd4306308a720c2fd991ba..febc73acbde415d4ad821aed7a7b5a752dd1c7b9 100644 --- a/src/libknot/updates/xfr-in.c +++ b/src/libknot/updates/xfr-in.c @@ -507,8 +507,8 @@ int xfrin_process_axfr_packet(knot_ns_xfr_t *xfr) return KNOT_EOK; } - if (knot_dname_compare(knot_rrset_owner(rr), - knot_packet_qname(packet)) != 0) { + if (knot_dname_compare_non_canon(knot_rrset_owner(rr), + knot_packet_qname(packet)) != 0) { dbg_xfrin_exec( char *rr_owner = knot_dname_to_str(knot_rrset_owner(rr)); @@ -569,7 +569,7 @@ dbg_xfrin_exec( assert(zone->apex->owner == rr->owner); // add the RRSet to the node ret = knot_zone_contents_add_rrset(zone, rr, &node, - KNOT_RRSET_DUPL_MERGE); + KNOT_RRSET_DUPL_MERGE); if (ret < 0) { dbg_xfrin("Failed to add RRSet to zone node: %s.\n", knot_strerror(ret)); @@ -1917,7 +1917,7 @@ int xfrin_replace_rrset_in_node(knot_node_t *node, // insert the new RRSet to the node dbg_xfrin_verb("Adding new RRSet.\n"); ret = knot_zone_contents_add_rrset(contents, rrset_new, &node, - KNOT_RRSET_DUPL_SKIP); + KNOT_RRSET_DUPL_SKIP); if (ret < 0) { dbg_xfrin("Failed to add RRSet to node.\n"); @@ -2083,15 +2083,11 @@ dbg_xfrin_exec_detail( free(name); ); // add the RRSet from the changeset to the node - /*! \todo What about domain names?? Shouldn't we use the - * zone-contents' version of this function?? - */ /*! * \note The new zone must be adjusted nevertheless, so it * doesn't matter whether there are some extra dnames to * be added to the table or not. */ -// ret = knot_node_add_rrset(node, add, 0); ret = knot_zone_contents_add_rrset(contents, add, &node, KNOT_RRSET_DUPL_SKIP); @@ -2142,7 +2138,7 @@ dbg_xfrin_exec_detail( } int merged, deleted_rrs; - ret = knot_rrset_merge_no_dupl(*rrset, add, &merged, &deleted_rrs); + ret = knot_rrset_merge_sort(*rrset, add, &merged, &deleted_rrs); if (ret < 0) { dbg_xfrin("Failed to merge changeset RRSet.\n"); return ret; @@ -2308,7 +2304,7 @@ dbg_xfrin_exec_detail( // merge the changeset RRSet to the copy dbg_xfrin_detail("Merging RRSIG to the one in the RRSet.\n"); int merged, deleted_rrs; - ret = knot_rrset_merge_no_dupl(rrsig, add, &merged, &deleted_rrs); + ret = knot_rrset_merge_sort(rrsig, add, &merged, &deleted_rrs); if (ret != KNOT_EOK) { dbg_xfrin("Failed to merge changeset RRSIG to copy: %s" ".\n", knot_strerror(ret)); diff --git a/src/libknot/zone/node.c b/src/libknot/zone/node.c index d22bc8749eb3d0657f149dd9706feb8421c2efcf..cd358f7528be13676b98b26272fa7187cbabd8cc 100644 --- a/src/libknot/zone/node.c +++ b/src/libknot/zone/node.c @@ -192,8 +192,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) { int merged, deleted_rrs; - int ret = knot_rrset_merge_no_dupl(node->rrset_tree[i], - rrset, &merged, &deleted_rrs); + int ret = knot_rrset_merge_sort(node->rrset_tree[i], + rrset, &merged, + &deleted_rrs); if (ret != KNOT_EOK) { return ret; } else if (merged || deleted_rrs) { @@ -204,6 +205,7 @@ int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset) } } + // New RRSet (with one RR) return knot_node_add_rrset_no_merge(node, rrset); } @@ -252,12 +254,6 @@ knot_rrset_t *knot_node_remove_rrset(knot_node_t *node, uint16_t type) } } - /*!< \todo I've added this to fix a leak, but probably this wasn't the cause. Remove once tests are availabe. */ - void *tmp = realloc(node->rrset_tree, - node->rrset_count * sizeof(knot_rrset_t *)); - assert(tmp || node->rrset_count == 0); //Realloc to smaller memory, if it fails, something is really odd. - node->rrset_tree = tmp; - return ret; } diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c index 751d76af6fbbce971d9cf8af21dfc25993a4078b..91bdeaae8b20c2abf44681a8509ad989f55d154c 100644 --- a/src/libknot/zone/zone-contents.c +++ b/src/libknot/zone/zone-contents.c @@ -859,7 +859,7 @@ dbg_zone_exec_detail( knot_dname_left_chop(knot_node_owner(node)); if(chopped == NULL) { /* Root domain and root domain only. */ - assert(node->owner && *node->owner->name == '\0'); + assert(node->owner && *node->owner == '\0'); return KNOT_EOK; } @@ -978,16 +978,14 @@ dbg_zone_exec_detail( ); // check if the RRSet belongs to the zone - if (knot_dname_compare(knot_rrset_owner(rrset), - zone->apex->owner) != 0 - && !knot_dname_is_subdomain(knot_rrset_owner(rrset), - zone->apex->owner)) { + if (knot_dname_compare_non_canon(rrset->owner, zone->apex->owner) != 0 + && !knot_dname_is_subdomain(rrset->owner, zone->apex->owner)) { return KNOT_EBADZONE; } if ((*node) == NULL && (*node = knot_zone_contents_get_node(zone, - knot_rrset_owner(rrset))) == NULL) { + rrset->owner)) == NULL) { return KNOT_ENONODE; } @@ -1367,7 +1365,7 @@ dbg_zone_detail("Search function returned %d, node %s (%p) and prev: %s (%p)\n", int matched_labels = knot_dname_matched_labels( knot_node_owner((*closest_encloser)), name); while (matched_labels < knot_dname_wire_labels( - knot_node_owner((*closest_encloser))->name, NULL)) { + knot_node_owner((*closest_encloser)), NULL)) { (*closest_encloser) = knot_node_parent((*closest_encloser)); assert(*closest_encloser); @@ -2144,7 +2142,7 @@ static void knot_zc_integrity_check_parent(const knot_node_t *node, // if direct child if (knot_dname_is_subdomain(node_owner, parent_owner) && knot_dname_matched_labels(node_owner, parent_owner) - == knot_dname_wire_labels(parent_owner->name, NULL)) { + == knot_dname_wire_labels(parent_owner, NULL)) { // check the parent pointer const knot_node_t *parent = knot_node_parent(node); diff --git a/src/libknot/zone/zone-contents.h b/src/libknot/zone/zone-contents.h index 19ba512ee6b4dbd11bcf2f4c96abd9b10fef599e..6070e7a7f541097a1e3505e3a4cb18ec2a819e3e 100644 --- a/src/libknot/zone/zone-contents.h +++ b/src/libknot/zone/zone-contents.h @@ -140,9 +140,8 @@ int knot_zone_contents_add_node(knot_zone_contents_t *contents, * \retval KNOT_EBADZONE */ 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); + 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, diff --git a/src/libknot/zone/zone-tree.c b/src/libknot/zone/zone-tree.c index c31c6dc51c301155f3818fc303492d69a963f314..89188ebe3d92150eff8df300f9f3bc5ea3f731af 100644 --- a/src/libknot/zone/zone-tree.c +++ b/src/libknot/zone/zone-tree.c @@ -328,7 +328,8 @@ void knot_zone_tree_deep_free(knot_zone_tree_t **tree) void hattrie_insert_dname(hattrie_t *tr, knot_dname_t *dname) { - *hattrie_get(tr, (char *)dname->name, dname->size) = dname; + *hattrie_get(tr, (char *)(dname), + knot_dname_wire_size(dname, NULL)) = dname; } /*----------------------------------------------------------------------------*/ @@ -339,7 +340,8 @@ knot_dname_t *hattrie_get_dname(hattrie_t *tr, knot_dname_t *dname) return NULL; } - value_t *val = hattrie_tryget(tr, (char *)dname->name, dname->size); + value_t *val = hattrie_tryget(tr, (char *)(dname), + knot_dname_wire_size(dname, NULL)); if (val == NULL) { return NULL; } else { diff --git a/src/libknot/zone/zonedb.c b/src/libknot/zone/zonedb.c index 3650b24120018605ee937ccb58d40b5ea8848fa0..8dd0af9b2cb617b277f05aed63cbf58b410c9598 100644 --- a/src/libknot/zone/zonedb.c +++ b/src/libknot/zone/zonedb.c @@ -128,8 +128,8 @@ const knot_zone_t *knot_zonedb_find_zone_for_name(knot_zonedb_t *db, } knot_zone_t *zone = NULL; - const char *name = (const char*)dname->name; - size_t len = dname->size; + const char *name = (const char*)dname; + size_t len = knot_dname_wire_size(dname, NULL); while (len > 0) { value_t *found = hattrie_tryget(db->zone_tree, name, len);