From: Wouter Wijngaards Date: Tue, 30 Nov 2010 12:55:48 +0000 (+0000) Subject: Fix storage of noEDNS in the infra cache. X-Git-Tag: release-1.4.8rc1~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79f4ca6a28029aedd4f4214591c6c99d559bf5b7;p=thirdparty%2Funbound.git Fix storage of noEDNS in the infra cache. iana portlist updated. git-svn-id: file:///svn/unbound/trunk@2348 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index da3f4a27e..bedb5c27a 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +30 November 2010: Wouter + - Fix storage of EDNS failures in the infra cache. + - iana portlist updated. + 18 November 2010: Wouter - harden-below-nxdomain option, default off (because very old software may be incompatible). We could enable it by default in diff --git a/services/cache/infra.c b/services/cache/infra.c index ba02b5083..4e39886e5 100644 --- a/services/cache/infra.c +++ b/services/cache/infra.c @@ -575,7 +575,8 @@ infra_edns_update(struct infra_cache* infra, /* have an entry, update the rtt, and the ttl */ data = (struct infra_host_data*)e->data; /* do not update if noEDNS and stored is yesEDNS */ - if(!(edns_version == -1 && data->edns_version != -1)) { + if(!(edns_version == -1 && (data->edns_version != -1 && + data->edns_lame_known))) { data->edns_version = edns_version; data->edns_lame_known = 1; } diff --git a/services/outside_network.c b/services/outside_network.c index b9297940a..4812a9cb2 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -1308,6 +1308,7 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff) &edns_lame_known, &rtt)) return 0; sq->last_rtt = rtt; + verbose(VERB_ALGO, "EDNS lookup known=%d vs=%d", edns_lame_known, vs); if(sq->status == serviced_initial) { if(edns_lame_known == 0 && rtt > 5000 && rtt < 10001) { /* perform EDNS lame probe - check if server is @@ -1593,6 +1594,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, == LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE( ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) { /* try to get an answer by falling back without EDNS */ + verbose(VERB_ALGO, "serviced query: attempt without EDNS"); sq->status = serviced_query_UDP_EDNS_fallback; sq->retry = 0; if(!serviced_udp_send(sq, c->buffer)) { @@ -1614,6 +1616,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, } else if(sq->status == serviced_query_UDP_EDNS && !sq->edns_lame_known) { /* now we know that edns queries received answers store that */ + log_addr(VERB_ALGO, "serviced query: EDNS works for", + &sq->addr, sq->addrlen); if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, 0, (uint32_t)now.tv_sec)) { log_err("Out of memory caching edns works"); @@ -1628,11 +1632,18 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, /* the fallback produced a result that looks promising, note * that this server should be approached without EDNS */ /* only store noEDNS in cache if domain is noDNSSEC */ - if(!sq->want_dnssec) + if(!sq->want_dnssec) { + log_addr(VERB_ALGO, "serviced query: EDNS fails for", + &sq->addr, sq->addrlen); if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, -1, (uint32_t)now.tv_sec)) { log_err("Out of memory caching no edns for host"); } + } else { + log_addr(VERB_ALGO, "serviced query: EDNS fails, but " + "not stored because need DNSSEC for", &sq->addr, + sq->addrlen); + } sq->status = serviced_query_UDP; } if(now.tv_sec > sq->last_sent_time.tv_sec || diff --git a/testcode/do-tests.sh b/testcode/do-tests.sh index fe67c26d8..1ffe19c0f 100755 --- a/testcode/do-tests.sh +++ b/testcode/do-tests.sh @@ -7,7 +7,7 @@ NEED_XXD='fwd_compress_c00c.tpkg fwd_zero.tpkg' NEED_NC='fwd_compress_c00c.tpkg fwd_zero.tpkg' NEED_CURL='06-ianaports.tpkg root_anchor.tpkg' NEED_WHOAMI='07-confroot.tpkg' -NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg stub_udp6.tpkg' +NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg stub_udp6.tpkg edns_cache.tpkg' NEED_NOMINGW='tcp_sigpipe.tpkg 07-confroot.tpkg 08-host-lib.tpkg fwd_ancil.tpkg' # test if dig and ldns-testns are available. diff --git a/testcode/unitmain.c b/testcode/unitmain.c index 3adff443b..aac49586f 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -435,7 +435,7 @@ infra_test(void) unit_assert( infra_edns_update(slab, &one, onelen, -1, now) ); unit_assert( infra_host(slab, &one, onelen, now, &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init*2 && edns_lame == 0); + unit_assert( vs == -1 && to == init*2 && edns_lame == 1); now += cfg->host_ttl + 10; unit_assert( infra_host(slab, &one, onelen, @@ -465,6 +465,22 @@ infra_test(void) unit_assert(!dlame && !rlame && alame && olame); lock_rw_unlock(&k->entry.lock); + /* test that noEDNS cannot overwrite known-yesEDNS */ + now += cfg->host_ttl + 10; + unit_assert( infra_host(slab, &one, onelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init && edns_lame == 0 ); + + unit_assert( infra_edns_update(slab, &one, onelen, 0, now) ); + unit_assert( infra_host(slab, &one, onelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init && edns_lame == 1 ); + + unit_assert( infra_edns_update(slab, &one, onelen, -1, now) ); + unit_assert( infra_host(slab, &one, onelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init && edns_lame == 1 ); + infra_delete(slab); config_delete(cfg); } diff --git a/testdata/edns_cache.tpkg b/testdata/edns_cache.tpkg new file mode 100644 index 000000000..c816f2cbd Binary files /dev/null and b/testdata/edns_cache.tpkg differ diff --git a/util/iana_ports.inc b/util/iana_ports.inc index bff957383..021cbe16a 100644 --- a/util/iana_ports.inc +++ b/util/iana_ports.inc @@ -5269,6 +5269,7 @@ 40841, 40842, 40843, +40853, 41111, 41794, 41795,