]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/cache: improve cache materialization
authorMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 3 Jun 2015 22:42:06 +0000 (00:42 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 3 Jun 2015 22:42:06 +0000 (00:42 +0200)
lib/cache.c
lib/cache.h
lib/layer/rrcache.c

index 9f639d6d03d97a1e9f570a3f90382ae67a5228ba..b5df162827cc48cda5bae9e2c1a2d273af6f37cc 100644 (file)
@@ -241,35 +241,34 @@ int kr_cache_peek_rr(struct kr_cache_txn *txn, knot_rrset_t *rr, uint32_t *times
        return kr_error(ENOENT);
 }
 
-knot_rrset_t kr_cache_materialize(const knot_rrset_t *src, uint32_t drift, mm_ctx_t *mm)
+int kr_cache_materialize(knot_rrset_t *dst, const knot_rrset_t *src, uint32_t drift, mm_ctx_t *mm)
 {
        assert(src);
 
-       /* Make RRSet copy. */
-       knot_rrset_t copy;
-       knot_rrset_init(&copy, NULL, src->type, src->rclass);
-       copy.owner = knot_dname_copy(src->owner, mm);
-       if (!copy.owner) {
-               return copy;
+       /* Make RRSet copy */
+       knot_rrset_init(dst, NULL, src->type, src->rclass);
+       dst->owner = knot_dname_copy(src->owner, mm);
+       if (!dst->owner) {
+               return kr_error(ENOMEM);
        }
 
+       knot_rdata_t *rd = knot_rdataset_at(&src->rrs, 0);
+       knot_rdata_t *rd_dst = NULL;
        for (uint16_t i = 0; i < src->rrs.rr_count; ++i) {
-               knot_rdata_t *rd = knot_rdataset_at(&src->rrs, i);
                if (knot_rdata_ttl(rd) > drift) {
-                       if (knot_rdataset_add(&copy.rrs, rd, mm) != 0) {
-                               knot_rrset_clear(&copy, mm);
-                               return copy;
+                       /* Append record */
+                       if (knot_rdataset_add(&dst->rrs, rd, mm) != 0) {
+                               knot_rrset_clear(dst, mm);
+                               return kr_error(ENOMEM);
                        }
+                       /* Fixup TTL from absolute time */
+                       rd_dst = knot_rdataset_at(&dst->rrs, dst->rrs.rr_count - 1);
+                       knot_rdata_set_ttl(rd_dst, knot_rdata_ttl(rd) - drift);
                }
+               rd += knot_rdata_array_size(knot_rdata_rdlen(rd));
        }
 
-       /* Update TTLs. */
-       for (uint16_t i = 0; i < copy.rrs.rr_count; ++i) {
-               knot_rdata_t *rd = knot_rdataset_at(&copy.rrs, i);
-               knot_rdata_set_ttl(rd, knot_rdata_ttl(rd) - drift);
-       }
-
-       return copy;
+       return kr_ok();
 }
 
 int kr_cache_insert_rr(struct kr_cache_txn *txn, const knot_rrset_t *rr, uint32_t timestamp)
index 1b7c48526ea6d9325412f6d6347931e452c649b7..9981aba4fada1982941bd3a6f8fef3dc5b120056 100644 (file)
@@ -165,12 +165,13 @@ int kr_cache_peek_rr(struct kr_cache_txn *txn, knot_rrset_t *rr, uint32_t *times
 
 /**
  * Clone read-only RRSet and adjust TTLs.
+ * @param dst destination for materialized RRSet
  * @param src read-only RRSet (its rdataset may be changed depending on the result)
  * @param drift time passed between cache time and now
  * @param mm memory context
- * @return materialized (or empty) RRSet
+ * @return 0 or an errcode
  */
-knot_rrset_t kr_cache_materialize(const knot_rrset_t *src, uint32_t drift, mm_ctx_t *mm);
+int kr_cache_materialize(knot_rrset_t *dst, const knot_rrset_t *src, uint32_t drift, mm_ctx_t *mm);
 
 /**
  * Insert RRSet into cache, replacing any existing data.
index 1557bca36d3876ff8185e2984dd86d8b9024e616..1618029c60682731b47f3dbf4723093e7b7c1064 100644 (file)
@@ -54,13 +54,15 @@ static int loot_rr(struct kr_cache_txn *txn, knot_pkt_t *pkt, const knot_dname_t
        }
 
        /* Update packet answer */
-       knot_rrset_t rr_copy = kr_cache_materialize(&cache_rr, timestamp, &pkt->mm);
-       ret = knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, &rr_copy, KNOT_PF_FREE);
-       if (ret != 0) {
-               knot_rrset_clear(&rr_copy, &pkt->mm);
-               return ret;
+       knot_rrset_t rr_copy;
+       ret = kr_cache_materialize(&rr_copy, &cache_rr, timestamp, &pkt->mm);
+       if (ret == 0) {
+               ret = knot_pkt_put(pkt, KNOT_COMPR_HINT_QNAME, &rr_copy, KNOT_PF_FREE);
+               if (ret != 0) {
+                       knot_rrset_clear(&rr_copy, &pkt->mm);
+               }
        }
-       return kr_ok();
+       return ret;
 }
 
 static int loot_cache_set(struct kr_cache_txn *txn, knot_pkt_t *pkt, const knot_dname_t *qname,