]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix for edns client subnet to respect not looking in its cache when
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Fri, 3 Jun 2022 14:11:35 +0000 (16:11 +0200)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Fri, 3 Jun 2022 14:11:35 +0000 (16:11 +0200)
  instructed to do so (e.g., prefetch).

doc/Changelog
edns-subnet/subnetmod.c
edns-subnet/subnetmod.h
testdata/subnet_prefetch.crpl
testdata/subnet_prefetch_with_client_ecs.crpl

index 77ad26205ec07414b31e49fe20aeada2056eda37..72729c31408512276463806e524738e27085153d 100644 (file)
@@ -1,3 +1,7 @@
+3 June 2022: George
+       - Fix for edns client subnet to respect not looking in its cache when
+         instructed to do so (e.g., prefetch).
+
 3 June 2022: Wouter
        - makedist.sh picks up 32bit libssp-0.dll when 32bit compile.
 
index 25190b040d45a0fa7e4a0d92544b0bb3f3e1b34d..f629d631f53a1f3343a8b809939e578fb453259c 100644 (file)
@@ -93,6 +93,7 @@ subnet_new_qstate(struct module_qstate *qstate, int id)
        qstate->minfo[id] = sq;
        memset(sq, 0, sizeof(*sq));
        sq->started_no_cache_store = qstate->no_cache_store;
+       sq->started_no_cache_lookup = qstate->no_cache_lookup;
        return 1;
 }
 
@@ -331,9 +332,11 @@ update_cache(struct module_qstate *qstate, int id)
        struct ecs_data *edns = &sq->ecs_client_in;
        size_t i;
 
-       /* We already calculated hash upon lookup */
-       hashvalue_type h = qstate->minfo[id] ? 
-               ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash : 
+       /* We already calculated hash upon lookup (lookup_and_reply) if we were
+        * allowed to look in the ECS cache */
+       hashvalue_type h = qstate->minfo[id] &&
+               ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash_calculated?
+               ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash :
                query_info_hash(&qstate->qinfo, qstate->query_flags);
        /* Step 1, general qinfo lookup */
        struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h,
@@ -416,7 +419,10 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
 
        memset(&sq->ecs_client_out, 0, sizeof(sq->ecs_client_out));
 
-       if (sq) sq->qinfo_hash = h; /* Might be useful on cache miss */
+       if (sq) {
+               sq->qinfo_hash = h; /* Might be useful on cache miss */
+               sq->qinfo_hash_calculated = 1;
+       }
        e = slabhash_lookup(sne->subnet_msg_cache, h, &qstate->qinfo, 1);
        if (!e) return 0; /* qinfo not in cache */
        data = e->data;
@@ -758,18 +764,20 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
                                return;
                }
 
-               lock_rw_wrlock(&sne->biglock);
-               if (lookup_and_reply(qstate, id, sq)) {
-                       sne->num_msg_cache++;
-                       lock_rw_unlock(&sne->biglock);
-                       verbose(VERB_QUERY, "subnetcache: answered from cache");
-                       qstate->ext_state[id] = module_finished;
+               if(!sq->started_no_cache_lookup && !qstate->blacklist) {
+                       lock_rw_wrlock(&sne->biglock);
+                       if(lookup_and_reply(qstate, id, sq)) {
+                               sne->num_msg_cache++;
+                               lock_rw_unlock(&sne->biglock);
+                               verbose(VERB_QUERY, "subnetcache: answered from cache");
+                               qstate->ext_state[id] = module_finished;
 
-                       subnet_ecs_opt_list_append(&sq->ecs_client_out,
-                               &qstate->edns_opts_front_out, qstate);
-                       return;
+                               subnet_ecs_opt_list_append(&sq->ecs_client_out,
+                                       &qstate->edns_opts_front_out, qstate);
+                               return;
+                       }
+                       lock_rw_unlock(&sne->biglock);
                }
-               lock_rw_unlock(&sne->biglock);
                
                sq->ecs_server_out.subnet_addr_fam =
                        sq->ecs_client_in.subnet_addr_fam;
@@ -815,6 +823,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
                                &qstate->edns_opts_front_out, qstate);
                }
                qstate->no_cache_store = sq->started_no_cache_store;
+               qstate->no_cache_lookup = sq->started_no_cache_lookup;
                return;
        }
        if(sq && outbound) {
index c877692b46b16aa4ca7b49acfb16f75e0d7fc6dd..4acd1a0a06674cc1093caf8cb53d4b0c8217bf7b 100644 (file)
@@ -76,6 +76,7 @@ struct subnet_msg_cache_data {
 struct subnet_qstate {
        /** We need the hash for both cache lookup and insert */
        hashvalue_type qinfo_hash;
+       int qinfo_hash_calculated;
        /** ecs_data for client communication */
        struct ecs_data ecs_client_in;
        struct ecs_data ecs_client_out;
@@ -92,6 +93,8 @@ struct subnet_qstate {
        uint8_t max_scope;
        /** has the subnet module been started with no_cache_store? */
        int started_no_cache_store;
+       /** has the subnet module been started with no_cache_lookup? */
+       int started_no_cache_lookup;
 };
 
 void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
index 7083aba6a5637f37bb69e2cafa080adb42fecce6..04922f2bbe4810f99573d15e73d02e4a07b83b71 100644 (file)
@@ -12,7 +12,6 @@ server:
        access-control: 127.0.0.1 allow_snoop
        qname-minimisation: no
        minimal-responses: no
-       serve-expired: yes
        prefetch: yes
 
 stub-zone:
@@ -20,7 +19,7 @@ stub-zone:
        stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
 CONFIG_END
 
-SCENARIO_BEGIN Test prefetch option for global cache
+SCENARIO_BEGIN Test prefetch option for global cache with ECS enabled
 
 ; K.ROOT-SERVERS.NET.
 RANGE_BEGIN 0 100
@@ -34,9 +33,6 @@ RANGE_BEGIN 0 100
                SECTION ANSWER
                        . IN NS K.ROOT-SERVERS.NET.
                SECTION ADDITIONAL
-                       HEX_EDNSDATA_BEGIN
-                               ;; we expect to receive empty
-                       HEX_EDNSDATA_END
                        K.ROOT-SERVERS.NET.     IN      A       193.0.14.129
        ENTRY_END
 
@@ -65,9 +61,6 @@ RANGE_BEGIN 0 100
                SECTION ANSWER
                        com.    IN NS   a.gtld-servers.net.
                SECTION ADDITIONAL
-                       HEX_EDNSDATA_BEGIN
-                               ;; we expect to receive empty
-                       HEX_EDNSDATA_END
                        a.gtld-servers.net.     IN      A       192.5.6.30
        ENTRY_END
 
@@ -96,9 +89,6 @@ RANGE_BEGIN 0 10
                SECTION ANSWER
                        example.com.    IN NS   ns.example.com.
                SECTION ADDITIONAL
-                       HEX_EDNSDATA_BEGIN
-                               ;; we expect to receive empty
-                       HEX_EDNSDATA_END
                        ns.example.com.         IN      A       1.2.3.4
        ENTRY_END
 
@@ -130,9 +120,6 @@ RANGE_BEGIN 11 100
                SECTION ANSWER
                        example.com.    IN NS   ns.example.com.
                SECTION ADDITIONAL
-                       HEX_EDNSDATA_BEGIN
-                               ;; we expect to receive empty
-                       HEX_EDNSDATA_END
                        ns.example.com.         IN      A       1.2.3.4
        ENTRY_END
 
@@ -144,7 +131,7 @@ RANGE_BEGIN 11 100
                SECTION QUESTION
                        www.example.com. IN A
                SECTION ANSWER
-                       www.example.com. IN A   10.20.30.40
+                       www.example.com. 10 IN A        10.20.30.40
                SECTION AUTHORITY
                        example.com.    IN NS   ns.example.com.
                SECTION ADDITIONAL
@@ -167,23 +154,23 @@ SECTION QUESTION
 www.example.com. IN A
 ENTRY_END
 
-; This answer should be in the global cache
+; This answer should be in the global cache (because no ECS from upstream)
 STEP 2 CHECK_ANSWER
 ENTRY_BEGIN
 MATCH all
 REPLY QR RD RA NOERROR
 SECTION QUESTION
-www.example.com. IN A
+www.example.com.       IN A
 SECTION ANSWER
-www.example.com. IN A  10.20.30.40
+www.example.com.       IN A    10.20.30.40
 SECTION AUTHORITY
-example.com.   IN NS   ns.example.com.
+example.com.           IN NS   ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.                IN      A       1.2.3.4
+ns.example.com.                IN A    1.2.3.4
 ENTRY_END
 
 ; Try to trigger a prefetch
-STEP 3 TIME_PASSES ELAPSE 11
+STEP 3 TIME_PASSES ELAPSE 9
 
 STEP 11 QUERY
 ENTRY_BEGIN
@@ -192,24 +179,46 @@ SECTION QUESTION
 www.example.com. IN A
 ENTRY_END
 
-; This expired record came from the cache and a prefetch is triggered
+; This record came from the global cache and a prefetch was triggered
 STEP 12 CHECK_ANSWER
 ENTRY_BEGIN
 MATCH all ttl
 REPLY QR RD RA NOERROR
 SECTION QUESTION
-www.example.com. IN A
+www.example.com.               IN A
 SECTION ANSWER
-www.example.com. 30 IN A       10.20.30.40
+www.example.com.       1       IN A    10.20.30.40
 SECTION AUTHORITY
-example.com.   3589 IN NS      ns.example.com.
+example.com.           3591    IN NS   ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.                3589 IN         A       1.2.3.4
+ns.example.com.                3591    IN A    1.2.3.4
+ENTRY_END
+
+; Allow time to pass so that the global cache record is expired
+STEP 13 TIME_PASSES ELAPSE 2
+
+; Query again to verify that the record was prefetched and stored in the ECS
+; cache (because the server replied with ECS this time)
+STEP 14 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
 ENTRY_END
 
-; Allow upstream to reply to the prefetch query.
-; It can only be answered if correct ECS was derived from the client's IP.
-; Otherwise the test will fail with "messages pending".
-STEP 13 TRAFFIC
+; This record came from the ECS cache
+STEP 15 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com.               IN A
+SECTION ANSWER
+www.example.com.       8       IN A    10.20.30.40
+SECTION AUTHORITY
+example.com.           3598    IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                3598    IN A    1.2.3.4
+ENTRY_END
 
 SCENARIO_END
index b0410255e85dc235f449f8dac6dffac47176bb9e..ddc832c475def26b5308ebf69a2ef18818870cf1 100644 (file)
@@ -12,7 +12,6 @@ server:
        access-control: 127.0.0.1 allow_snoop
        qname-minimisation: no
        minimal-responses: no
-       serve-expired: yes
        prefetch: yes
 
 stub-zone:
@@ -20,7 +19,7 @@ stub-zone:
        stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
 CONFIG_END
 
-SCENARIO_BEGIN Test prefetch option for global cache
+SCENARIO_BEGIN Test prefetch option for global cache with ECS enabled and ECS client
 
 ; K.ROOT-SERVERS.NET.
 RANGE_BEGIN 0 100
@@ -34,9 +33,6 @@ RANGE_BEGIN 0 100
                SECTION ANSWER
                        . IN NS K.ROOT-SERVERS.NET.
                SECTION ADDITIONAL
-                       HEX_EDNSDATA_BEGIN
-                               ;; we expect to receive empty
-                       HEX_EDNSDATA_END
                        K.ROOT-SERVERS.NET.     IN      A       193.0.14.129
        ENTRY_END
 
@@ -65,9 +61,6 @@ RANGE_BEGIN 0 100
                SECTION ANSWER
                        com.    IN NS   a.gtld-servers.net.
                SECTION ADDITIONAL
-                       HEX_EDNSDATA_BEGIN
-                               ;; we expect to receive empty
-                       HEX_EDNSDATA_END
                        a.gtld-servers.net.     IN      A       192.5.6.30
        ENTRY_END
 
@@ -96,9 +89,6 @@ RANGE_BEGIN 0 10
                SECTION ANSWER
                        example.com.    IN NS   ns.example.com.
                SECTION ADDITIONAL
-                       HEX_EDNSDATA_BEGIN
-                               ;; we expect to receive empty
-                       HEX_EDNSDATA_END
                        ns.example.com.         IN      A       1.2.3.4
        ENTRY_END
 
@@ -130,9 +120,6 @@ RANGE_BEGIN 11 100
                SECTION ANSWER
                        example.com.    IN NS   ns.example.com.
                SECTION ADDITIONAL
-                       HEX_EDNSDATA_BEGIN
-                               ;; we expect to receive empty
-                       HEX_EDNSDATA_END
                        ns.example.com.         IN      A       1.2.3.4
        ENTRY_END
 
@@ -144,7 +131,7 @@ RANGE_BEGIN 11 100
                SECTION QUESTION
                        www.example.com. IN A
                SECTION ANSWER
-                       www.example.com. IN A   10.20.30.40
+                       www.example.com. 10 IN A        10.20.30.40
                SECTION AUTHORITY
                        example.com.    IN NS   ns.example.com.
                SECTION ADDITIONAL
@@ -173,17 +160,17 @@ ENTRY_BEGIN
 MATCH all
 REPLY QR RD RA NOERROR
 SECTION QUESTION
-www.example.com. IN A
+www.example.com.       IN A
 SECTION ANSWER
-www.example.com. IN A  10.20.30.40
+www.example.com.       IN A    10.20.30.40
 SECTION AUTHORITY
-example.com.   IN NS   ns.example.com.
+example.com.           IN NS   ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.                IN      A       1.2.3.4
+ns.example.com.                IN A    1.2.3.4
 ENTRY_END
 
 ; Try to trigger a prefetch
-STEP 3 TIME_PASSES ELAPSE 11
+STEP 3 TIME_PASSES ELAPSE 9
 
 STEP 11 QUERY
 ENTRY_BEGIN
@@ -192,30 +179,63 @@ SECTION QUESTION
 www.example.com. IN A
 SECTION ADDITIONAL
 HEX_EDNSDATA_BEGIN
-               00 08 00 05     ; OPC, optlen
-               00 01 08 00     ; ip4, source 8, scope 0
-               7f              ; 127.0.0.0/8
+       00 08 00 05     ; OPC, optlen
+       00 01 08 00     ; ip4, source 8, scope 0
+       7f              ; 127.0.0.0/8
 HEX_EDNSDATA_END
 ENTRY_END
 
-; This expired record came from the cache and a prefetch is triggered
+; This record came from the global cache and a prefetch was triggered
 STEP 12 CHECK_ANSWER
 ENTRY_BEGIN
 MATCH all ttl
 REPLY QR RD RA DO NOERROR
 SECTION QUESTION
-www.example.com. IN A
+www.example.com.               IN A
 SECTION ANSWER
-www.example.com. 30 IN A       10.20.30.40
+www.example.com.       1       IN A    10.20.30.40
 SECTION AUTHORITY
-example.com.   3589 IN NS      ns.example.com.
+example.com.           3591    IN NS   ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.                3589 IN         A       1.2.3.4
+ns.example.com.                3591    IN A    1.2.3.4
 ENTRY_END
 
-; Allow upstream to reply to the prefetch query.
-; It can only be answered if correct ECS was derived from the client's IP.
-; Otherwise the test will fail with "messages pending".
-STEP 13 TRAFFIC
+; Allow time to pass so that the global cache record is expired
+STEP 13 TIME_PASSES ELAPSE 2
+
+; Query again to verify that the record was prefetched and stored in the ECS
+; cache (because the server replied with ECS this time)
+STEP 14 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+SECTION ADDITIONAL
+HEX_EDNSDATA_BEGIN
+       00 08 00 05     ; OPC, optlen
+       00 01 08 00     ; ip4, source 8, scope 0
+       7f              ; 127.0.0.0/8
+HEX_EDNSDATA_END
+ENTRY_END
+
+; This record came from the ECS cache
+STEP 15 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.example.com.               IN A
+SECTION ANSWER
+www.example.com.       8       IN A    10.20.30.40
+SECTION AUTHORITY
+example.com.           3598    IN NS   ns.example.com.
+SECTION ADDITIONAL
+HEX_EDNSDATA_BEGIN
+       00 08 00 05     ; OPC, optlen
+       00 01 08 08     ; ip4, source 8, scope 0
+       7f              ; 127.0.0.0/8
+HEX_EDNSDATA_END
+ns.example.com.                3598    IN A    1.2.3.4
+ENTRY_END
 
 SCENARIO_END