]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Synthesize ANY responses from cache. Does not search exhaustively,
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 17 Apr 2015 14:58:07 +0000 (14:58 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 17 Apr 2015 14:58:07 +0000 (14:58 +0000)
  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

doc/Changelog
services/cache/dns.c
util/config_file.c

index ce5aa5b3f2b5b2aa4166c236d05d87922fd9601d..d108daedcae5f1d72873008f5a4aa376dd9e7b05 100644 (file)
@@ -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
index cec2629e1300d9de2514747d6621af62041b9c10..dd6f7e0401fde0389518a2fcd629824c38db787d 100644 (file)
@@ -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; i<num; i++) {
+               /* look up this RR for inclusion in type ANY response */
+               struct ub_packed_rrset_key* rrset = rrset_cache_lookup(
+                       env->rrset_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;
 }
 
index eae7f2e4293efec1bbaac61c653dd6dc8219a659..61291575a5f7d870e440646111c94470ba91c3f0 100644 (file)
@@ -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);