Fix for lame reply corner case.

git-svn-id: file:///svn/unbound/trunk@2168 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2010-06-25 08:32:51 +00:00
parent 60035e31a2
commit 14f178e486
7 changed files with 362 additions and 3 deletions

View file

@ -1,3 +1,8 @@
25 June 2010: Wouter
- Fix handling of corner case reply from lame server, follows rfc2308.
It could lead to a nodata reply getting into the cache if the search
for a non-lame server turned up other misconfigured servers.
23 June 2010: Wouter
- iana portlist updated.
- makedist upgraded cross compile openssl option, like this:

View file

@ -225,9 +225,14 @@ response_type_from_server(int rdset,
/* Or if a lame server is deployed,
* which gives ns==zone delegation from cache
* without AA bit as well, with nodata nosoa*/
/* real answer must be +AA and SOA RFC(2308),
* so this is wrong, and we SERVFAIL it if
* this is the only possible reply, if it
* is misdeployed the THROWAWAY makes us pick
* the next server from the selection */
if(msg->rep->an_numrrsets==0 &&
!(msg->rep->flags&BIT_AA) && !rdset)
return RESPONSE_TYPE_REC_LAME;
return RESPONSE_TYPE_THROWAWAY;
return RESPONSE_TYPE_ANSWER;
}
/* If we are getting a referral upwards (or to

View file

@ -54,6 +54,7 @@
#include "util/config_file.h"
#include "services/listen_dnsport.h"
#include "services/outside_network.h"
#include "services/cache/infra.h"
#include "testcode/replay.h"
#include "testcode/ldns-testpkts.h"
#include "util/log.h"
@ -134,6 +135,7 @@ repevt_string(enum replay_event_type t)
case repevt_error: return "ERROR";
case repevt_assign: return "ASSIGN";
case repevt_traffic: return "TRAFFIC";
case repevt_infra_rtt: return "INFRA_RTT";
default: return "UNKNOWN";
}
}
@ -541,6 +543,18 @@ autotrust_check(struct replay_runtime* runtime, struct replay_moment* mom)
log_info("autotrust %s is OK", mom->autotrust_id);
}
/** Store RTT in infra cache */
static void
do_infra_rtt(struct replay_runtime* runtime)
{
struct replay_moment* now = runtime->now;
int rto = infra_rtt_update(runtime->infra, &now->addr,
now->addrlen, atoi(now->string), -1, runtime->now_secs);
log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen);
log_info("INFRA_RTT(roundtrip %d): rto of %d", atoi(now->string), rto);
if(rto == 0) fatal_exit("infra_rtt_update failed");
}
/**
* Advance to the next moment.
*/
@ -619,6 +633,10 @@ do_moment_and_advance(struct replay_runtime* runtime)
case repevt_traffic:
advance_moment(runtime);
break;
case repevt_infra_rtt:
do_infra_rtt(runtime);
advance_moment(runtime);
break;
default:
fatal_exit("testbound: unknown event type %d",
runtime->now->evt_type);
@ -847,18 +865,20 @@ outside_network_create(struct comm_base* base, size_t bufsize,
size_t ATTR_UNUSED(num_ports), char** ATTR_UNUSED(ifs),
int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4),
int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp),
struct infra_cache* ATTR_UNUSED(infra),
struct infra_cache* infra,
struct ub_randstate* ATTR_UNUSED(rnd),
int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
int ATTR_UNUSED(do_udp))
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
struct outside_network* outnet = calloc(1,
sizeof(struct outside_network));
(void)unwanted_action;
if(!outnet)
return NULL;
runtime->infra = infra;
outnet->base = base;
outnet->udp_buff = ldns_buffer_new(bufsize);
if(!outnet->udp_buff)

View file

@ -330,6 +330,24 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
} else if(parse_keyword(&remain, "ASSIGN")) {
mom->evt_type = repevt_assign;
read_assign_step(remain, mom);
} else if(parse_keyword(&remain, "INFRA_RTT")) {
char *s;
mom->evt_type = repevt_infra_rtt;
while(isspace((int)*remain))
remain++;
s = remain;
remain = strchr(s, ' ');
if(!remain) fatal_exit("expected two args for INFRA_RTT");
remain[0] = 0;
remain++;
while(isspace((int)*remain))
remain++;
if(!extstrtoaddr(s, &mom->addr, &mom->addrlen))
fatal_exit("bad infra_rtt address %s", s);
if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n')
remain[strlen(remain)-1] = 0;
mom->string = strdup(remain);
if(!mom->string) fatal_exit("out of memory");
} else {
log_err("%d: unknown event type %s", *lineno, remain);
free(mom);

View file

@ -75,6 +75,7 @@
* the step waits for traffic to stop.
* o CHECK_AUTOTRUST [id] - followed by FILE_BEGIN [to match] FILE_END.
* The file contents is macro expanded before match.
* o INFRA_RTT [ip] [rtt] - update infra cache entry with rtt.
* o ERROR
* ; following entry starts on the next line, ENTRY_BEGIN.
* ; more STEP items
@ -136,6 +137,7 @@ struct replay_range;
struct fake_pending;
struct fake_timer;
struct replay_var;
struct infra_cache;
/**
* A replay scenario.
@ -196,9 +198,11 @@ struct replay_moment {
repevt_error,
/** assignment to a variable */
repevt_assign,
/** store infra rtt cache entry: addr and string (int) */
repevt_infra_rtt,
/** cause traffic to flow */
repevt_traffic
}
}
/** variable with what is to happen this moment */
evt_type;
@ -285,6 +289,9 @@ struct replay_runtime {
/** user argument for incoming query callback */
void *cb_arg;
/** ref the infra cache (was passed to outside_network_create) */
struct infra_cache* infra;
/** the current time in seconds */
uint32_t now_secs;
/** the current time in microseconds */

290
testdata/iter_lame_nosoa.rpl vendored Normal file
View file

@ -0,0 +1,290 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test resolution with lame reply looks like nodata with noSOA
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
net. IN NS
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns.example.net.
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
ENTRY_END
RANGE_END
; e.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.12.94.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
net. IN NS
SECTION ANSWER
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.net. IN NS
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
RANGE_END
; ns.example.net.
; advertises +RA so it is REC_LAME.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.44
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
example.net. IN NS
SECTION ANSWER
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION ANSWER
ns.example.net. IN A 1.2.3.44
SECTION AUTHORITY
example.net. IN NS ns.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
www.example.net. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.net.
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION ANSWER
SECTION AUTHORITY
example.com. IN NS ns.example.net.
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.55
SECTION AUTHORITY
example.com. IN NS ns.example.net.
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.net.
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
ns.example.net IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
mail.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
example.com. IN NS ns.example.net.
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ENTRY_END
RANGE_END
; ns.example.com.
; is like a BIND server that is LAME, authoritative for other domains,
; but not this one, and somehow got this NS record in its cache.
; trying to give 'lame referral' but to the same name, not up.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.55
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ENTRY_END
RANGE_END
; store bad timing for one server to influence server selection
; 1.2.3.44 (ns.example.net) gets 900 msec.
; so the 376 ns.example.com is preferred.
STEP 1 INFRA_RTT 1.2.3.44 900
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.net.
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
; scrubbed off
;ns.example.net IN A 1.2.3.44
ENTRY_END
; query to recursion-lame server
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
mail.example.com. IN A
ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
mail.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
example.com. IN NS ns.example.net.
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ENTRY_END
SCENARIO_END

View file

@ -162,6 +162,20 @@ ns.sub.example.com. IN A 1.2.3.6
ns.sub.example.com. 3600 IN RRSIG A 12 4 3600 20070926134150 20070829134150 60385 sub.example.com. kJEyinL7BkpiPW2HxmFHRLAi68EdrLXToJiK83a5cedDe5ABL7c/k+nFHd3WjATUtVoueY3pSnCDVCJaFmd+/A== ;{id = 60385}
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.sub.example.com. IN A
SECTION ANSWER
ns.sub.example.com. IN A 1.2.3.6
ns.sub.example.com. 3600 IN RRSIG A 12 4 3600 20070926134150 20070829134150 60385 sub.example.com. kJEyinL7BkpiPW2HxmFHRLAi68EdrLXToJiK83a5cedDe5ABL7c/k+nFHd3WjATUtVoueY3pSnCDVCJaFmd+/A== ;{id = 60385}
SECTION AUTHORITY
sub.example.com. IN NS ns.sub.example.com.
sub.example.com. 3600 IN RRSIG NS 12 3 3600 20070926134150 20070829134150 60385 sub.example.com. 6mNrX32/DC2RU1A+yWCccn5H6wnsbNYTlf8e/LyF1fsuNfw6tH12sKGBCtk1mp4HpDIgH02HDHplJskSFOvzTw== ;{id = 60385}
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname