]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Fix for lame reply corner case.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 25 Jun 2010 08:32:51 +0000 (08:32 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 25 Jun 2010 08:32:51 +0000 (08:32 +0000)
git-svn-id: file:///svn/unbound/trunk@2168 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iter_resptype.c
testcode/fake_event.c
testcode/replay.c
testcode/replay.h
testdata/iter_lame_nosoa.rpl [new file with mode: 0644]
testdata/val_ds_gost_downgrade.rpl

index 1e0d1e3ecefd6c644970a753c2a2c455a6866063..2fa2be5fa6349ed0ca0f6e21647fd4982a731b56 100644 (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: 
index 2c5da3dce0f8adc0e0165c04d7dd2905d0f83f7d..5d4844720d31c2cf384e9ccf1231cb19e1ca6e37 100644 (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 
index 4e5eb59becc1bd22810ffb2a190442455767a072..1fd80d2b1d9a1b86c417fad61014d00b3abead54 100644 (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)
index 9839ee7d0d97a86fd2d7ee9045488b323edc2c75..2ba8d8044e13dab5587148b550525458305b061b 100644 (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);
index dcc0d02fa6fb4c9900e7347b9e367d4293c8706d..07f602e04232e57c8c73431d4cdfeefb44e19a42 100644 (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 */
diff --git a/testdata/iter_lame_nosoa.rpl b/testdata/iter_lame_nosoa.rpl
new file mode 100644 (file)
index 0000000..fac1813
--- /dev/null
@@ -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
index b3f23809753a64718cb37c4da2249729ff3f09f4..00e6e4e3b50ddeb33024ee6d4d2f7d47833853c4 100644 (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