]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
cache: fix answers from wildcards
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 19 Jan 2018 16:10:32 +0000 (17:10 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 19 Jan 2018 16:10:32 +0000 (17:10 +0100)
Also make the control flow more readable and tweak comments.

lib/cache.c
lib/cache/impl.h
lib/cache/nsec1.c

index 603e93bbd0569776e04360de63ea80494602eb39..bc8ef4dc1db043909fad8e400298ae5d4ae89f38 100644 (file)
@@ -420,9 +420,8 @@ static int cache_peek_real(kr_layer_t *ctx, knot_pkt_t *pkt)
        }
 #endif
 
-       /* collecting multiple NSEC* + RRSIG records, in preparation for the answer
-        *  + track the progress
-        */
+       /** Collecting multiple NSEC* + RRSIG records, in preparation for the answer
+        *  + track the progress */
        struct answer ans;
        memset(&ans, 0, sizeof(ans));
        ans.mm = &pkt->mm;
@@ -461,12 +460,14 @@ static int cache_peek_real(kr_layer_t *ctx, knot_pkt_t *pkt)
                }
        //}
 
-       if (!ans.rcode) {
-               /* Nothing suitable found. */
+       if (ans.rcode != PKT_NODATA && ans.rcode != PKT_NXDOMAIN) {
+               assert(ans.rcode == 0); /* Nothing suitable found. */
                return ctx->state;
        }
+       /* At this point, sname was either covered or matched. */
+       const bool sname_covered = ans.rcode == PKT_NXDOMAIN;
 
-       /* Name of the closest (provable) encloser. */
+       /** Name of the closest (provable) encloser. */
        const knot_dname_t *clencl_name = qry->sname;
        for (int l = sname_labels; l > clencl_labels; --l)
                clencl_name = knot_wire_next_label(clencl_name, NULL);
@@ -476,15 +477,15 @@ static int cache_peek_real(kr_layer_t *ctx, knot_pkt_t *pkt)
         * 3a. We want to query for NSEC* of source of synthesis (SS) or its predecessor,
         * providing us with a proof of its existence or non-existence.
         */
-       if (ans.rcode == PKT_NODATA) {
+       if (!sname_covered) {
                /* No wildcard checks needed, as we proved that sname exists. */
                assert(ans.nsec_v == 1); // for now
 
-       } else if (ans.nsec_v == 1 && ans.rcode == PKT_NXDOMAIN) {
+       } else if (ans.nsec_v == 1 && sname_covered) {
                int ret = nsec1_src_synth(k, &ans, clencl_name,
                                          cover_low_kwz, cover_hi_kwz, qry, cache);
                if (ret < 0) return ctx->state;
-               if (ret == AR_SOA) goto do_soa;
+               if (ret == AR_SOA) goto do_soa; /* SS was covered or matched for NODATA */
                assert(ret == 0);
 
        } else {
@@ -493,10 +494,10 @@ static int cache_peek_real(kr_layer_t *ctx, knot_pkt_t *pkt)
        }
 
 
-       /** 3b. We need to find wildcarded answer, if SS wasn't covered.
-        * (common for NSEC*)
+       /** 3b. We need to find wildcarded answer, if sname was covered
+        * and we don't have a full proof yet.  (common for NSEC*)
         */
-       if (ans.rcode == PKT_NOERROR) {
+       if (sname_covered) {
                /* Construct key for exact qry->stype + source of synthesis. */
                int ret = kr_dname_lf(k->buf, clencl_name, true);
                if (ret) {
@@ -541,7 +542,10 @@ static int cache_peek_real(kr_layer_t *ctx, knot_pkt_t *pkt)
                const void *eh_bound = val.data + val.len;
                ret = entry2answer(&ans, AR_ANSWER, eh, eh_bound,
                                   qry->sname, qry->stype, new_ttl);
+               VERBOSE_MSG(qry, "=> NSEC wildcard: answer expanded, ret = %d, new TTL %d\n",
+                               ret, (int)new_ttl);
                if (ret) return ctx->state;
+               ans.rcode = PKT_NOERROR;
        }
 
 
index e176feddb66a7a679bede5550d9d023ae165f958..c4215716dc35dc511470890c5463f4b13d3ad7ba 100644 (file)
@@ -168,7 +168,7 @@ int rdataset_dematerialize(const knot_rdataset_t *rds, void * restrict data);
 
 /** Partially constructed answer when gathering RRsets from cache. */
 struct answer {
-       int rcode;      /**< PKT_NODATA, etc. ?? */
+       int rcode;      /**< PKT_NODATA, etc. */
        uint8_t nsec_v; /**< 1 or 3 */
        knot_mm_t *mm;  /**< Allocator for rrsets */
        struct answer_rrset {
@@ -224,9 +224,10 @@ int nsec1_encloser(struct key *k, struct answer *ans,
                   knot_db_val_t *cover_low_kwz, knot_db_val_t *cover_hi_kwz,
                   const struct kr_query *qry, struct kr_cache *cache);
 
-/** Source of synthesis check for NSEC (1).
+/** Source of synthesis (SS) check for NSEC (1).
  * To understand the interface, see the call point.
- * \return 0: continue;  AR_SOA: skip to adding SOA;  <0: exit cache immediately. */
+ * \return 0: continue; <0: exit cache immediately;
+ *     AR_SOA: skip to adding SOA (SS was covered or matched for NODATA). */
 int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name,
                    knot_db_val_t cover_low_kwz, knot_db_val_t cover_hi_kwz,
                    const struct kr_query *qry, struct kr_cache *cache);
index 4b04f473e87e8c537ab5e4b0a7ac3b0dba2864cd..a05ea106a0ce55af43928466e4c807b98d9f1146 100644 (file)
@@ -415,7 +415,7 @@ int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clenc
                                &exact_match, &wild_low_kwz, NULL, &new_ttl);
                if (err) {
                        VERBOSE_MSG(qry, "=> NSEC wildcard: %s\n", err);
-                       return -ABS(ENOENT);
+                       return kr_ok();
                }
                /* Materialize the record into answer (speculatively). */
                const struct entry_h *nsec_eh = val.data;
@@ -452,7 +452,7 @@ int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clenc
                if (is_sub && kr_nsec_children_in_zone_check(bm, bm_size) != 0) {
                        VERBOSE_MSG(qry,
                                "=> NSEC wildcard: covered but delegated (or error)\n");
-                       ret = -ABS(ENOENT);
+                       ret = kr_ok();
                        goto clean_wild;
                }
                /* We have a record proving wildcard non-existence. */
@@ -479,7 +479,7 @@ int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clenc
                        }
                }
                ans->rcode = PKT_NODATA;
-               return kr_ok();
+               return AR_SOA;
 
        } /* else */
        /* The data probably exists -> don't add this NSEC