]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
fix some bugs around key->dname conversion
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 23 Oct 2017 13:19:42 +0000 (15:19 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 23 Oct 2017 13:19:42 +0000 (15:19 +0200)
e.g. in _lf2wire

lib/cache.c
lib/utils.c
lib/utils.h

index fefe645e297b08494fd2c4080424355d35c66305..eb1c75284be651bf81607ba4e3643fa7e4adfd1c 100644 (file)
@@ -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)
 {
index d2b33a64adc63416309492dcdf867169fb242614..5412c17af4a3f7361baba51be010c5577ad6ab03 100644 (file)
@@ -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;
 }
index 3aa3d932d04bb4b0795fc9c9b0b2a5e770551a5f..fe9522f73031ea2e01367821cc263922ff4ab5bf 100644 (file)
@@ -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);