- Ignore expired error responses.

This commit is contained in:
George Thessalonikefs 2022-11-22 17:44:55 +01:00
parent f72116883b
commit 896f7a8306
8 changed files with 337 additions and 16 deletions

View File

@ -551,10 +551,16 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
verbose(VERB_ALGO, "cachedb msg expired"); verbose(VERB_ALGO, "cachedb msg expired");
/* If serve-expired is enabled, we still use an expired message /* If serve-expired is enabled, we still use an expired message
* setting the TTL to 0. */ * setting the TTL to 0. */
if(qstate->env->cfg->serve_expired) if(!qstate->env->cfg->serve_expired ||
adjust = -1; (FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
else != LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_YXDOMAIN))
return 0; /* message expired */ return 0; /* message expired */
else
adjust = -1;
} }
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust); verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
adjust_msg_ttl(qstate->return_msg, adjust); adjust_msg_ttl(qstate->return_msg, adjust);

View File

@ -623,6 +623,14 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
if(worker->env.cfg->serve_expired_ttl && if(worker->env.cfg->serve_expired_ttl &&
rep->serve_expired_ttl < timenow) rep->serve_expired_ttl < timenow)
return 0; return 0;
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0)) if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
return 0; return 0;
*is_expired_answer = 1; *is_expired_answer = 1;
@ -730,8 +738,6 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
goto bail_out; goto bail_out;
} }
} else { } else {
/* We don't check the global ede as this is a warning, not
* an error */
if (*is_expired_answer == 1 && if (*is_expired_answer == 1 &&
worker->env.cfg->ede_serve_expired && worker->env.cfg->ede) { worker->env.cfg->ede_serve_expired && worker->env.cfg->ede) {
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out, EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,

View File

@ -1,3 +1,6 @@
22 November 2022: George
- Ignore expired error responses.
11 November 2022: Wouter 11 November 2022: Wouter
- Fix #779: [doc] Missing documention in ub_resolve_event() for - Fix #779: [doc] Missing documention in ub_resolve_event() for
callback parameter was_ratelimited. callback parameter was_ratelimited.

View File

@ -636,6 +636,14 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
r->serve_expired_ttl < now) { r->serve_expired_ttl < now) {
return NULL; return NULL;
} }
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
} else { } else {
return NULL; return NULL;
} }

View File

@ -2,6 +2,7 @@
; config options go here. ; config options go here.
server: server:
serve-expired: yes serve-expired: yes
prefetch: yes
forward-zone: name: "." forward-addr: 216.0.0.1 forward-zone: name: "." forward-addr: 216.0.0.1
CONFIG_END CONFIG_END
@ -45,7 +46,7 @@ SECTION ANSWER
ENTRY_END ENTRY_END
; enough to pass by the TTL of the servfail answer in cache ; enough to pass by the TTL of the servfail answer in cache
STEP 50 TIME_PASSES ELAPSE 40 STEP 50 TIME_PASSES ELAPSE 5
; this query triggers a prefetch ; this query triggers a prefetch
STEP 210 QUERY STEP 210 QUERY

View File

@ -0,0 +1,130 @@
; config options
server:
module-config: "validator iterator"
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
serve-expired-reply-ttl: 123
log-servfail: yes
ede: yes
ede-serve-expired: yes
stub-zone:
name: "example.com"
stub-addr: 1.2.3.4
CONFIG_END
SCENARIO_BEGIN Test serve-expired with client-timeout and a SERVFAIL upstream reply
; Scenario overview:
; - query for example.com. IN A
; - answer from upstream is SERVFAIL; will be cached for NORR_TTL(5)
; - check that the client gets the SERVFAIL; also cached
; - query again right after the TTL expired
; - cached SERVFAIL should be ignored and upstream queried
; - check that we get the correct answer
; ns.example.com.
RANGE_BEGIN 0 20
ADDRESS 1.2.3.4
; response to A query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA SERVFAIL
SECTION QUESTION
example.com. IN A
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 30 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. 10 IN NS
SECTION ANSWER
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
RANGE_END
; Query with RD flag
STEP 0 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
; Check that we get the SERVFAIL (will be cached)
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
example.com. IN A
ENTRY_END
; Query again
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
; Check that we get the cached SERVFAIL
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
example.com. IN A
ENTRY_END
; Wait for the SERVFAIL to expire
STEP 31 TIME_PASSES ELAPSE 6
; Query again
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
; Check that we got the correct answer
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
SCENARIO_END

View File

@ -4,7 +4,7 @@ server:
qname-minimisation: "no" qname-minimisation: "no"
minimal-responses: no minimal-responses: no
serve-expired: yes serve-expired: yes
serve-expired-client-timeout: 1800 serve-expired-client-timeout: 1
serve-expired-reply-ttl: 123 serve-expired-reply-ttl: 123
log-servfail: yes log-servfail: yes
ede: yes ede: yes
@ -32,11 +32,11 @@ RANGE_BEGIN 0 20
ADJUST copy_id ADJUST copy_id
REPLY QR NOERROR REPLY QR NOERROR
SECTION QUESTION SECTION QUESTION
example.com. IN NS example.com. 10 IN NS
SECTION ANSWER SECTION ANSWER
example.com. IN NS ns.example.com. example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4 ns.example.com. 10 IN A 1.2.3.4
ENTRY_END ENTRY_END
ENTRY_BEGIN ENTRY_BEGIN
@ -48,14 +48,14 @@ RANGE_BEGIN 0 20
SECTION ANSWER SECTION ANSWER
example.com. 10 IN A 5.6.7.8 example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY SECTION AUTHORITY
example.com. IN NS ns.example.com. example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4 ns.example.com. 10 IN A 1.2.3.4
ENTRY_END ENTRY_END
RANGE_END RANGE_END
; ns.example.com. ; ns.example.com.
RANGE_BEGIN 30 100 RANGE_BEGIN 30 70
ADDRESS 1.2.3.4 ADDRESS 1.2.3.4
; response to A query ; response to A query
ENTRY_BEGIN ENTRY_BEGIN
@ -85,13 +85,13 @@ ENTRY_BEGIN
SECTION ANSWER SECTION ANSWER
example.com. 10 IN A 5.6.7.8 example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY SECTION AUTHORITY
example.com. IN NS ns.example.com. example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4 ns.example.com. 10 IN A 1.2.3.4
ENTRY_END ENTRY_END
; Wait for the TTL to expire ; Wait for the TTL to expire
STEP 11 TIME_PASSES ELAPSE 3601 STEP 11 TIME_PASSES ELAPSE 11
; Query again ; Query again
STEP 30 QUERY STEP 30 QUERY

167
testdata/subnet_cached_servfail.crpl vendored Normal file
View File

@ -0,0 +1,167 @@
; Check if an expired SERVFAIL answer stored in the global cache does not block
; ECS queries to reach the ECS cache.
server:
trust-anchor-signaling: no
target-fetch-policy: "0 0 0 0 0"
send-client-subnet: 1.2.3.4
max-client-subnet-ipv4: 21
module-config: "subnetcache iterator"
verbosity: 3
access-control: 127.0.0.1 allow_snoop
qname-minimisation: no
minimal-responses: no
serve-expired: yes
prefetch: yes
stub-zone:
name: "example.com."
stub-addr: 1.2.3.4
CONFIG_END
SCENARIO_BEGIN Test that expired SERVFAIL in global cache does not block clients to reach the ECS cache
; ns.example.com.
RANGE_BEGIN 0 10
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR SERVFAIL
SECTION QUESTION
www.example.com. IN A
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 11 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id copy_ednsdata_assume_clientsubnet
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 127.0.0.1
00 08 ; OPC
00 05 ; option length
00 01 ; Family
08 00 ; source mask, scopemask
7f ; address
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; This answer should be in the global cache
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; Bring the cached SERVFAIL to prefetch time
STEP 10 TIME_PASSES ELAPSE 5
STEP 11 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 answer was cached but a prefetch was triggerred
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR RD RA SERVFAIL
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; Wait for the SERVFAIL to expire
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