From: Vladimír Čunát Date: Mon, 23 Oct 2017 13:19:42 +0000 (+0200) Subject: fix some bugs around key->dname conversion X-Git-Tag: v2.0.0~6^2~84 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b80ddce45a6b6a60c3c54c290f56594fef2df45;p=thirdparty%2Fknot-resolver.git fix some bugs around key->dname conversion e.g. in _lf2wire --- diff --git a/lib/cache.c b/lib/cache.c index fefe645e2..eb1c75284 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -161,7 +161,7 @@ int kr_cache_clear(struct kr_cache *cache) * * 'E' entry (exact hit): * - ktype == NS: multiple chained entry_h, based on has_* : 1 flags; - * FIXME: NSEC3 chain descriptors (iff nsec3_cnt > 0) + * TODO: NSEC3 chain descriptors (iff nsec3_cnt > 0) * - is_negative: uint16_t length, otherwise opaque ATM; * - otherwise RRset + its RRSIG set (possibly empty). * */ @@ -562,10 +562,6 @@ static knot_db_val_t key_NSEC1(struct key *k, const knot_dname_t *name, int zone return (knot_db_val_t){}; } - VERBOSE_MSG(NULL, "<> key_NSEC1; "); - kr_dname_print(name, "name: ", " "); - kr_log_verbose("(zone name LF length: %d)\n", zonename_len); - uint8_t *begin = k->buf + 1 + zonename_len; /* one byte after zone's zero */ uint8_t *end = k->buf + 1 + k->buf[0]; /* we don't use the final zero in key, * but move it anyway */ @@ -573,13 +569,26 @@ static knot_db_val_t key_NSEC1(struct key *k, const knot_dname_t *name, int zone assert(false); return (knot_db_val_t){}; } - if (end > begin) + int key_len; + if (end > begin) { memmove(begin + 2, begin, end - begin); + key_len = k->buf[0] + 1; + } else { + key_len = k->buf[0] + 2; + } + /* CACHE_KEY_DEF: key == zone's dname_lf + 0 + '1' + dname_lf + * of the name within the zone without the final 0. Iff the latter is empty, + * there's no zero to cut and thus the key_len difference. + */ begin[0] = 0; begin[1] = '1'; /* tag for NSEC1 */ - /* CACHE_KEY_DEF: key == zone's dname_lf + 0 + '1' + dname_lf - * of the name within the zone without the final 0 */ - return (knot_db_val_t){ k->buf + 1, k->buf[0] + 1 }; + + VERBOSE_MSG(NULL, "<> key_NSEC1; "); + kr_dname_print(name, "name: ", " "); + kr_log_verbose("(zone name LF length: %d; total key length: %d)\n", + zonename_len, key_len); + + return (knot_db_val_t){ k->buf + 1, key_len }; } @@ -786,17 +795,17 @@ int cache_lmdb_peek(kr_layer_t *ctx, knot_pkt_t *pkt) ret = knot_dname_lf2wire(dname_buf, key.len - nwz_off, key.data + nwz_off); /* CACHE_KEY_DEF */ - if (ret) break; - ret = knot_dname_to_wire(dname_buf + (key.len - nwz_off), k->dname, - /* TODO: messy zone name ^^ */ - KNOT_DNAME_MAXLEN - (key.len-nwz_off)); + VERBOSE_MSG(qry, "=> NSEC: LF2wire ret = %d\n", ret); + if (ret < 0) break; + ret = knot_dname_to_wire(dname_buf + ret, k->dname, + /* TODO: messy zone name ^^ */ + KNOT_DNAME_MAXLEN - (key.len-nwz_off)); if (ret != zname_lf_len + 1) { assert(false); break; } owner = dname_buf; } - VERBOSE_MSG(qry, "=> NSEC: LF2wire OK\n"); /* Basic checks OK -> materialize data. */ ret = entry2answer(&ans, AR_NSEC, eh, eh_data_bound, @@ -1100,7 +1109,7 @@ static int stash_rrset(const ranked_rr_array_t *arr, int arr_i, uint32_t min_ttl } -/** FIXME: description; see the single call site for now. */ +/** TODO: description; see the single call site for now. */ static int found_exact_hit(kr_layer_t *ctx, knot_pkt_t *pkt, knot_db_val_t val, uint8_t lowest_rank, uint16_t ktype) { diff --git a/lib/utils.c b/lib/utils.c index d2b33a64a..5412c17af 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -797,16 +797,23 @@ void kr_qry_print(const struct kr_query *qry, const char *prefix, const char *po kr_rrtype_print(qry->stype, " ", postfix); } -int knot_dname_lf2wire(knot_dname_t *dst, uint8_t len, const uint8_t *lf) +int knot_dname_lf2wire(knot_dname_t *dst0, uint8_t len, const uint8_t *lf) { + knot_dname_t *dst = dst0; bool ok = dst && (len == 0 || lf); if (!ok) { assert(false); return kr_error(EINVAL); } - if (lf[len]) /* we allow the final zero byte to be omitted */ + /* we allow the final zero byte to be omitted */ + if (!len) { + goto finish; + } + if (lf[len - 1]) { ++len; - int label_end = len; /* index of the zero byte after the current label */ + } + /* convert the name, one label at a time */ + int label_end = len - 1; /* index of the zero byte after the current label */ while (label_end >= 0) { /* find label_start */ int i = len - 1; @@ -824,6 +831,8 @@ int knot_dname_lf2wire(knot_dname_t *dst, uint8_t len, const uint8_t *lf) /* next label */ label_end = i; } +finish: *dst = 0; /* the final zero */ - return kr_ok(); + ++dst; + return dst - dst0; } diff --git a/lib/utils.h b/lib/utils.h index 3aa3d932d..fe9522f73 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -294,7 +294,7 @@ static inline uint16_t kr_rrset_type_maysig(const knot_rrset_t *rr) * * \note len bytes are read and len+1 are written with *normal* LF, * but it's also allowed that the final zero byte is omitted in LF. - * \return error code + * \return the number of bytes written (>0) or error code (<0) */ int knot_dname_lf2wire(knot_dname_t *dst, uint8_t len, const uint8_t *lf);