diff --git a/lib/utils.c b/lib/utils.c index 77e07bf966cb076427625d70d17423e0af162beb..40422f082f0369ca2fc5235946b30fef75344a0c 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 667ae66bb9cd9aaf298f48b73f2108b01bb880b0..cfa789cedc6a44b01bf8bd4fee38113909a71857 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.