]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
layer/iterate: ignore bad NS, don’t fail the packet
authorMarek Vavruša <marek.vavrusa@nic.cz>
Fri, 29 May 2015 00:33:01 +0000 (02:33 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Fri, 29 May 2015 00:33:01 +0000 (02:33 +0200)
if an authoritative answer comes and the server responds correctly, but appends out-of-bailiwick NS records, ignore them but resolve the query

lib/layer/iterate.c
lib/layer/rrcache.c

index 406aef9024192536b9e2315d9065b48a6c8b8676..da49252d1f578c0a680347f4593cfb83b12357d7 100644 (file)
@@ -192,8 +192,8 @@ static int update_cut(knot_pkt_t *pkt, const knot_rrset_t *rr, struct kr_request
        /* Authority MUST be at/below the authority of the nameserver, otherwise
         * possible cache injection attempt. */
        if (!knot_dname_in(cut->name, rr->owner)) {
-               DEBUG_MSG("<= authority: ns outside bailiwick, rejecting\n");
-               return KNOT_STATE_FAIL;
+               DEBUG_MSG("<= authority: ns outside bailiwick, ignoring\n");
+               return state;
        }
 
        /* Update zone cut name */
index 821da0688b38057d0accfd366b97aaef31546fc5..8001452b0478822217f72e4752b8a503545390cd 100644 (file)
@@ -192,7 +192,7 @@ static int write_cache_answer(knot_pkt_t *pkt, struct kr_cache_txn *txn, mm_ctx_
 }
 
 /** Cache stub nameservers. */
-static int write_cache_authority(knot_pkt_t *pkt, struct kr_cache_txn *txn, mm_ctx_t *pool, uint32_t timestamp)
+static int write_cache_authority(struct kr_zonecut *cut, knot_pkt_t *pkt, struct kr_cache_txn *txn, mm_ctx_t *pool, uint32_t timestamp)
 {
        knot_rrset_t glue_rr = { NULL, 0, 0 };
        knot_rrset_t cache_rr = { NULL, 0, 0 };
@@ -204,6 +204,10 @@ static int write_cache_authority(knot_pkt_t *pkt, struct kr_cache_txn *txn, mm_c
        for (unsigned i = 0; i < ns->count; ++i) {
                const knot_rrset_t *rr = knot_pkt_rr(ns, i);
                if (rr->type == KNOT_RRTYPE_NS) {
+                       /* Cache in-bailiwick data only */
+                       if (!knot_dname_in(cut->name, rr->owner)) {
+                               return KNOT_ENOENT;
+                       }
                        /* Cache glue (if contains) */
                        for (unsigned i = 0; i < sizeof(type_list)/sizeof(uint16_t); ++i) {
                                knot_dname_t *owner = (knot_dname_t *)knot_ns_name(&rr->rrs, 0);
@@ -254,7 +258,7 @@ static int stash(knot_layer_t *ctx, knot_pkt_t *pkt)
                ret = write_cache_answer(pkt, &txn, pool, timestamp);
        }
        if (ret == KNOT_EOK) {
-               ret = write_cache_authority(pkt, &txn, pool, timestamp);
+               ret = write_cache_authority(&query->zone_cut, pkt, &txn, pool, timestamp);
        }
 
        /* Cache full, do what we must. */