From 6170374f28fb6e31d228fc048333fb18764945f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Vavru=C5=A1a?= <marek.vavrusa@nic.cz>
Date: Thu, 3 Dec 2015 19:00:18 +0100
Subject: [PATCH] lib/utils: function to get unique key for RR (string)

---
 lib/utils.c | 39 ++++++++++++++++++++++++++-------------
 lib/utils.h |  5 +++++
 2 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/lib/utils.c b/lib/utils.c
index 77e07bf96..40422f082 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -304,6 +304,26 @@ int kr_bitcmp(const char *a, const char *b, int bits)
 	return ret;
 }
 
+int kr_rrmap_key(char *key, const knot_dname_t *owner, uint16_t type, uint8_t rank)
+{
+	if (!key || !owner) {
+		printf("key owner %p %p\n", key, owner);
+		return kr_error(EINVAL);
+	}
+	key[0] = (rank << 2) | 0x01; /* Must be non-zero */
+	uint8_t *key_buf = (uint8_t *)key + 1;
+	int ret = knot_dname_to_wire(key_buf, owner, KNOT_DNAME_MAXLEN);
+	if (ret <= 0) {
+		return ret;
+	}
+	knot_dname_to_lower(key_buf);
+	key_buf += ret - 1;
+	/* Must convert to string, as the key must not contain 0x00 */
+	ret = u16tostr(key_buf, type);
+	key_buf[ret] = '\0';
+	return (char *)&key_buf[ret] - key;
+}
+
 int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, mm_ctx_t *pool)
 {
 	if (!stash || !rr) {
@@ -311,27 +331,20 @@ int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, mm_ctx_t *p
 	}
 
 	/* Stash key = {[1] flags, [1-255] owner, [5] type, [1] \x00 } */
-	char key[9 + KNOT_DNAME_MAXLEN];
+	char key[RRMAP_KEYSIZE];
+	uint8_t extra_flags = 0;
 	uint16_t rrtype = rr->type;
-	key[0] = (rank << 2) | 0x01; /* Must be non-zero */
-
 	/* Stash RRSIGs in a special cache, flag them and set type to its covering RR.
 	 * This way it the stash won't merge RRSIGs together. */
 	if (rr->type == KNOT_RRTYPE_RRSIG) {
 		rrtype = knot_rrsig_type_covered(&rr->rrs, 0);
-		key[0] |= KEY_FLAG_RRSIG;
+		extra_flags |= KEY_FLAG_RRSIG;
 	}
-
-	uint8_t *key_buf = (uint8_t *)key + 1;
-	int ret = knot_dname_to_wire(key_buf, rr->owner, KNOT_DNAME_MAXLEN);
+	int ret = kr_rrmap_key(key, rr->owner, rrtype, rank);
 	if (ret <= 0) {
-		return ret;
+		return kr_error(EILSEQ);
 	}
-	knot_dname_to_lower(key_buf);
-	key_buf += ret - 1;
-	/* Must convert to string, as the key must not contain 0x00 */
-	ret = u16tostr(key_buf, rrtype);
-	key_buf[ret] = '\0';
+	key[0] |= extra_flags;
 
 	/* Check if already exists */
 	knot_rrset_t *stashed = map_get(stash, key);
diff --git a/lib/utils.h b/lib/utils.h
index 667ae66bb..cfa789ced 100644
--- a/lib/utils.h
+++ b/lib/utils.h
@@ -117,6 +117,11 @@ int kr_bitcmp(const char *a, const char *b, int bits);
 #define KEY_FLAG_RRSIG 0x02
 #define KEY_FLAG_RANK(key) (key[0] >> 2)
 #define KEY_COVERING_RRSIG(key) (key[0] & KEY_FLAG_RRSIG)
+/* Stash key = {[1] flags, [1-255] owner, [5] type, [1] \x00 } */
+#define RRMAP_KEYSIZE (9 + KNOT_DNAME_MAXLEN)
+
+/** @internal Create unique string key for RR. */
+int kr_rrmap_key(char *key, const knot_dname_t *owner, uint16_t type, uint8_t rank);
 
 /** @internal Merges RRSets with matching owner name and type together.
  * @note RRSIG RRSets are merged according the type covered fields.
-- 
GitLab