- Fix for edns client subnet to respect not looking in its cache when

instructed to do so (e.g., prefetch).
This commit is contained in:
George Thessalonikefs 2022-06-03 16:11:35 +02:00
parent 97b7224885
commit 459b73018f
5 changed files with 121 additions and 76 deletions

View 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.

View 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) {

View 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));

View 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 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
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; 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

View 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