From f4ad52dffd8d659f8dd70d425f0fb46ffb1277a0 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Mon, 20 Oct 2008 13:51:47 +0000 Subject: [PATCH] Do not query bogus name servers. git-svn-id: file:///svn/unbound/trunk@1312 be551aaa-1e26-0410-a405-d3ace91eadb9 --- daemon/cachedump.c | 9 +++++++-- doc/Changelog | 2 ++ doc/plan | 2 +- iterator/iter_delegpt.c | 24 ++++++++++++++++-------- iterator/iter_delegpt.h | 12 ++++++++++-- iterator/iter_fwd.c | 2 +- iterator/iter_hints.c | 10 ++++++---- iterator/iter_utils.c | 4 ++++ 8 files changed, 47 insertions(+), 18 deletions(-) diff --git a/daemon/cachedump.c b/daemon/cachedump.c index 4466290d9..483ae34fa 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -816,6 +816,10 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm, struct ub_packed_rrset_key* k = msg->rep->rrsets[i]; struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; + if(d->security == sec_status_bogus) { + if(!ssl_printf(ssl, "Address is BOGUS:\n")) + return 0; + } if(!dump_rrset(ssl, k, d, 0)) return 0; } @@ -824,8 +828,9 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm, /* since dp has not been used by iterator, all are available*/ if(!ssl_printf(ssl, "Delegation with %d names, of which %d " "have no addresses in cache.\n" - "It provides %d IP addresses.\n", - (int)n_ns, (int)n_miss, (int)n_addr)) + "It provides %d IP addresses. %s\n", + (int)n_ns, (int)n_miss, (int)n_addr, + (dp->bogus?"It is BOGUS":"") )) return 0; /* go up? */ if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) { diff --git a/doc/Changelog b/doc/Changelog index f89327579..7bef5262a 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,8 @@ 20 October 2008: Wouter - quench a log message that is debug only. - iana portlist updated. + - do not query bogus nameservers. It is like nameservers that have + the NS or A or AAAA record bogus are listed as donotquery. 17 October 2008: Wouter - port Leopard/G5: fixup type conversion size_t/uint32. diff --git a/doc/plan b/doc/plan index 673ca7238..7096bcc80 100644 --- a/doc/plan +++ b/doc/plan @@ -81,7 +81,7 @@ not stats on SIGUSR1. perhaps also see which slow auth servers cause >1sec value + off-path validation + root NS, root glue validation after prime -* ignore bogus nameservers, pretend they always return a servfail. ++ ignore bogus nameservers, pretend they always return a servfail. *** Features features, for later diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c index 03f4ec8f1..dae6d750b 100644 --- a/iterator/iter_delegpt.c +++ b/iterator/iter_delegpt.c @@ -74,7 +74,8 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region) copy->nslist->resolved = ns->resolved; } for(a = dp->target_list; a; a = a->next_target) { - if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen)) + if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, + a->bogus)) return NULL; } return copy; @@ -127,7 +128,7 @@ delegpt_find_ns(struct delegpt* dp, uint8_t* name, size_t namelen) int delegpt_add_target(struct delegpt* dp, struct regional* region, uint8_t* name, size_t namelen, struct sockaddr_storage* addr, - socklen_t addrlen) + socklen_t addrlen, int bogus) { struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); if(!ns) { @@ -135,12 +136,12 @@ delegpt_add_target(struct delegpt* dp, struct regional* region, return 1; } ns->resolved = 1; - return delegpt_add_addr(dp, region, addr, addrlen); + return delegpt_add_addr(dp, region, addr, addrlen, bogus); } int delegpt_add_addr(struct delegpt* dp, struct regional* region, - struct sockaddr_storage* addr, socklen_t addrlen) + struct sockaddr_storage* addr, socklen_t addrlen, int bogus) { struct delegpt_addr* a = (struct delegpt_addr*)regional_alloc(region, sizeof(struct delegpt_addr)); @@ -154,6 +155,7 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region, memcpy(&a->addr, addr, addrlen); a->addrlen = addrlen; a->attempts = 0; + a->bogus = bogus; return 1; } @@ -211,10 +213,14 @@ void delegpt_log(enum verbosity_value v, struct delegpt* dp) if(verbosity >= VERB_ALGO) { for(ns = dp->nslist; ns; ns = ns->next) { dname_str(ns->name, buf); - log_info(" %s%s", buf, (ns->resolved?"*":"")); + log_info(" %s%s%s", buf, (ns->resolved?"*":""), + (dp->bogus?" BOGUS":"") ); } for(a = dp->target_list; a; a = a->next_target) { - log_addr(VERB_ALGO, " ", &a->addr, a->addrlen); + if(a->bogus) + log_addr(VERB_ALGO, " BOGUS ", + &a->addr, a->addrlen); + else log_addr(VERB_ALGO, " ", &a->addr, a->addrlen); } } } @@ -310,6 +316,8 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region, struct packed_rrset_data* nsdata = (struct packed_rrset_data*) ns_rrset->entry.data; size_t i; + if(nsdata->security == sec_status_bogus) + dp->bogus = 1; for(i=0; icount; i++) { if(nsdata->rr_len[i] < 2+1) continue; /* len + root label */ if(dname_valid(nsdata->rr_data[i]+2, nsdata->rr_len[i]-2) != @@ -339,7 +347,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE); if(!delegpt_add_target(dp, region, ak->rk.dname, ak->rk.dname_len, (struct sockaddr_storage*)&sa, - len)) + len, (d->security==sec_status_bogus) )) return 0; } return 1; @@ -362,7 +370,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE); if(!delegpt_add_target(dp, region, ak->rk.dname, ak->rk.dname_len, (struct sockaddr_storage*)&sa, - len)) + len, (d->security==sec_status_bogus) )) return 0; } return 1; diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h index 8c122e520..23244fc00 100644 --- a/iterator/iter_delegpt.h +++ b/iterator/iter_delegpt.h @@ -70,6 +70,9 @@ struct delegpt { struct delegpt_addr* usable_list; /** the list of returned targets; subset of target_list */ struct delegpt_addr* result_list; + + /** if true, the NS RRset was bogus. All info is bad. */ + int bogus; }; /** @@ -108,6 +111,9 @@ struct delegpt_addr { int attempts; /** rtt stored here in the selection algorithm */ int sel_rtt; + /** if true, the A or AAAA RR was bogus, so this address is bad. + * Also check the dp->bogus to see if everything is bogus. */ + int bogus; }; /** @@ -164,11 +170,12 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional, * @param namelen: length of name. * @param addr: the address. * @param addrlen: the length of addr. + * @param bogus: security status for the address, pass true if bogus. * @return false on error. */ int delegpt_add_target(struct delegpt* dp, struct regional* regional, uint8_t* name, size_t namelen, struct sockaddr_storage* addr, - socklen_t addrlen); + socklen_t addrlen, int bogus); /** * Add A RRset to delegpt. @@ -206,10 +213,11 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional, * @param regional: where to allocate the info. * @param addr: the address. * @param addrlen: the length of addr. + * @param bogus: if address is bogus. * @return false on error. */ int delegpt_add_addr(struct delegpt* dp, struct regional* regional, - struct sockaddr_storage* addr, socklen_t addrlen); + struct sockaddr_storage* addr, socklen_t addrlen, int bogus); /** * Find NS record in name list of delegation point. diff --git a/iterator/iter_fwd.c b/iterator/iter_fwd.c index e61b5b491..09dde0d91 100644 --- a/iterator/iter_fwd.c +++ b/iterator/iter_fwd.c @@ -203,7 +203,7 @@ read_fwds_addr(struct iter_forwards* fwd, struct config_stub* s, s->name, p->str); return 0; } - if(!delegpt_add_addr(dp, fwd->region, &addr, addrlen)) { + if(!delegpt_add_addr(dp, fwd->region, &addr, addrlen, 0)) { log_err("out of memory"); return 0; } diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index 45ebfcffc..5c7e5863c 100644 --- a/iterator/iter_hints.c +++ b/iterator/iter_hints.c @@ -86,7 +86,7 @@ ah(struct delegpt* dp, struct regional* r, const char* sv, const char* ip) if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf)) || !extstrtoaddr(ip, &addr, &addrlen) || !delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf), - &addr, addrlen)) { + &addr, addrlen, 0)) { ldns_rdf_deep_free(rdf); return 0; } @@ -226,7 +226,7 @@ read_stubs_addr(struct iter_hints* hints, struct config_stub* s, s->name, p->str); return 0; } - if(!delegpt_add_addr(dp, hints->region, &addr, addrlen)) { + if(!delegpt_add_addr(dp, hints->region, &addr, addrlen, 0)) { log_err("out of memory"); return 0; } @@ -320,7 +320,8 @@ read_root_hints(struct iter_hints* hints, char* fname) if(!delegpt_add_target(dp, hints->region, ldns_rdf_data(ldns_rr_owner(rr)), ldns_rdf_size(ldns_rr_owner(rr)), - (struct sockaddr_storage*)&sa, len)) { + (struct sockaddr_storage*)&sa, len, + 0)) { log_err("out of memory reading root hints"); goto stop_read; } @@ -335,7 +336,8 @@ read_root_hints(struct iter_hints* hints, char* fname) if(!delegpt_add_target(dp, hints->region, ldns_rdf_data(ldns_rr_owner(rr)), ldns_rdf_size(ldns_rr_owner(rr)), - (struct sockaddr_storage*)&sa, len)) { + (struct sockaddr_storage*)&sa, len, + 0)) { log_err("out of memory reading root hints"); goto stop_read; } diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 24251a5c0..4cbd5da27 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -141,6 +141,8 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env, struct delegpt_addr* a) { int rtt, lame, reclame, dnsseclame; + if(a->bogus) + return -1; /* address of server is bogus */ if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) { return -1; /* server is on the donotquery list */ } @@ -173,6 +175,8 @@ iter_fill_rtt(struct iter_env* iter_env, struct module_env* env, { int got_it = 0; struct delegpt_addr* a; + if(dp->bogus) + return 0; /* NS bogus, all bogus, nothing found */ for(a=dp->result_list; a; a = a->next_result) { a->sel_rtt = iter_filter_unsuitable(iter_env, env, name, namelen, qtype, now, a);