From: Wouter Wijngaards Date: Fri, 17 Apr 2015 14:58:07 +0000 (+0000) Subject: - Synthesize ANY responses from cache. Does not search exhaustively, X-Git-Tag: release-1.5.4~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff898bfdd6a64eab2e3d94a75286a71c8291ae7d;p=thirdparty%2Funbound.git - Synthesize ANY responses from cache. Does not search exhaustively, but MX,A,AAAA,SOA,NS also CNAME. - Fix leaked dns64prefix configuration string. git-svn-id: file:///svn/unbound/trunk@3405 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index ce5aa5b3f..d108daedc 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,8 @@ +17 April 2015: Wouter + - Synthesize ANY responses from cache. Does not search exhaustively, + but MX,A,AAAA,SOA,NS also CNAME. + - Fix leaked dns64prefix configuration string. + 16 April 2015: Wouter - Add local-zone type inform_deny, that logs query and drops answer. - Ratelimit does not apply to prefetched queries, and ratelimit-factor diff --git a/services/cache/dns.c b/services/cache/dns.c index cec2629e1..dd6f7e040 100644 --- a/services/cache/dns.c +++ b/services/cache/dns.c @@ -389,6 +389,18 @@ dns_msg_authadd(struct dns_msg* msg, struct regional* region, return 1; } +/** add rrset to answer section */ +static int +dns_msg_ansadd(struct dns_msg* msg, struct regional* region, + struct ub_packed_rrset_key* rrset, time_t now) +{ + if(!(msg->rep->rrsets[msg->rep->rrset_count++] = + packed_rrset_copy_region(rrset, region, now))) + return 0; + msg->rep->an_numrrsets++; + return 1; +} + struct delegpt* dns_cache_find_delegation(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, @@ -635,6 +647,58 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region, return msg; } +/** Fill TYPE_ANY response with some data from cache */ +static struct dns_msg* +fill_any(struct module_env* env, + uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, + struct regional* region) +{ + time_t now = *env->now; + struct dns_msg* msg = NULL; + uint16_t lookup[] = {LDNS_RR_TYPE_A, LDNS_RR_TYPE_AAAA, + LDNS_RR_TYPE_MX, LDNS_RR_TYPE_SOA, LDNS_RR_TYPE_NS, 0}; + int i, num=5; /* number of RR types to look up */ + log_assert(lookup[num] == 0); + + for(i=0; irrset_cache, qname, qnamelen, lookup[i], + qclass, 0, now, 0); + struct packed_rrset_data *d; + if(!rrset) + continue; + + /* only if rrset from answer section */ + d = (struct packed_rrset_data*)rrset->entry.data; + if(d->trust == rrset_trust_add_noAA || + d->trust == rrset_trust_auth_noAA || + d->trust == rrset_trust_add_AA || + d->trust == rrset_trust_auth_AA) { + lock_rw_unlock(&rrset->entry.lock); + continue; + } + + /* create msg if none */ + if(!msg) { + msg = dns_msg_create(qname, qnamelen, qtype, qclass, + region, num-i); + if(!msg) { + lock_rw_unlock(&rrset->entry.lock); + return NULL; + } + } + + /* add RRset to response */ + if(!dns_msg_ansadd(msg, region, rrset, now)) { + lock_rw_unlock(&rrset->entry.lock); + return NULL; + } + lock_rw_unlock(&rrset->entry.lock); + } + return msg; +} + struct dns_msg* dns_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, @@ -747,6 +811,11 @@ dns_cache_lookup(struct module_env* env, } } + /* fill common RR types for ANY response to avoid requery */ + if(qtype == LDNS_RR_TYPE_ANY) { + return fill_any(env, qname, qnamelen, qtype, qclass, region); + } + return NULL; } diff --git a/util/config_file.c b/util/config_file.c index eae7f2e42..61291575a 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -937,6 +937,7 @@ config_delete(struct config_file* cfg) free(cfg->server_cert_file); free(cfg->control_key_file); free(cfg->control_cert_file); + free(cfg->dns64_prefix); free(cfg->dnstap_socket_path); free(cfg->dnstap_identity); free(cfg->dnstap_version);