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);