From: George Thessalonikefs Date: Fri, 3 Jun 2022 14:11:35 +0000 (+0200) Subject: - Fix for edns client subnet to respect not looking in its cache when X-Git-Tag: release-1.16.1rc1~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=459b73018f26a6976aefbb361c6d0e491ae8fa5e;p=thirdparty%2Funbound.git - Fix for edns client subnet to respect not looking in its cache when instructed to do so (e.g., prefetch). --- diff --git a/doc/Changelog b/doc/Changelog index 77ad26205..72729c314 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c index 25190b040..f629d631f 100644 --- a/edns-subnet/subnetmod.c +++ b/edns-subnet/subnetmod.c @@ -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) { diff --git a/edns-subnet/subnetmod.h b/edns-subnet/subnetmod.h index c877692b4..4acd1a0a0 100644 --- a/edns-subnet/subnetmod.h +++ b/edns-subnet/subnetmod.h @@ -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)); diff --git a/testdata/subnet_prefetch.crpl b/testdata/subnet_prefetch.crpl index 7083aba6a..04922f2bb 100644 --- a/testdata/subnet_prefetch.crpl +++ b/testdata/subnet_prefetch.crpl @@ -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 diff --git a/testdata/subnet_prefetch_with_client_ecs.crpl b/testdata/subnet_prefetch_with_client_ecs.crpl index b0410255e..ddc832c47 100644 --- a/testdata/subnet_prefetch_with_client_ecs.crpl +++ b/testdata/subnet_prefetch_with_client_ecs.crpl @@ -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