From: Wouter Wijngaards Date: Fri, 25 Jun 2010 08:32:51 +0000 (+0000) Subject: Fix for lame reply corner case. X-Git-Tag: release-1.4.6rc1~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14f178e486ae2044c5de63a3f92d5472f3dad470;p=thirdparty%2Funbound.git Fix for lame reply corner case. git-svn-id: file:///svn/unbound/trunk@2168 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 1e0d1e3ec..2fa2be5fa 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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: diff --git a/iterator/iter_resptype.c b/iterator/iter_resptype.c index 2c5da3dce..5d4844720 100644 --- a/iterator/iter_resptype.c +++ b/iterator/iter_resptype.c @@ -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 diff --git a/testcode/fake_event.c b/testcode/fake_event.c index 4e5eb59be..1fd80d2b1 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -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) diff --git a/testcode/replay.c b/testcode/replay.c index 9839ee7d0..2ba8d8044 100644 --- a/testcode/replay.c +++ b/testcode/replay.c @@ -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); diff --git a/testcode/replay.h b/testcode/replay.h index dcc0d02fa..07f602e04 100644 --- a/testcode/replay.h +++ b/testcode/replay.h @@ -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 */ diff --git a/testdata/iter_lame_nosoa.rpl b/testdata/iter_lame_nosoa.rpl new file mode 100644 index 000000000..fac181388 --- /dev/null +++ b/testdata/iter_lame_nosoa.rpl @@ -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 diff --git a/testdata/val_ds_gost_downgrade.rpl b/testdata/val_ds_gost_downgrade.rpl index b3f238097..00e6e4e3b 100644 --- a/testdata/val_ds_gost_downgrade.rpl +++ b/testdata/val_ds_gost_downgrade.rpl @@ -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