]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
1.2.1 feature: stop AAAA queries that are not needed.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 13 Jan 2009 15:57:42 +0000 (15:57 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 13 Jan 2009 15:57:42 +0000 (15:57 +0000)
git-svn-id: file:///svn/unbound/trunk@1431 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iter_delegpt.c
iterator/iter_delegpt.h
services/cache/dns.c

index 7dd3c6afa5d7a33e11ef065ef92d1da1392fdca2..ac9c8a97cd60e5d04364bb4bd1b8138f638762da 100644 (file)
@@ -3,6 +3,8 @@
        - find NS rrset more cleanly for qtype NS.
        - Moved changes to 1.2.0 for release. Thanks to Mark Zealey for
          reporting and logs.
+       - 1.2.1 feature: stops resolving AAAAs promiscuously when they
+         are in the negative cache.
 
 12 January 2009: Wouter
        - fixed bug in infrastructure lameness cache, did not lowercase
index 0c5f02b993d13e7cd7e558cf366baa0e525825db..13bcdad47bca4559332950830cf4ab74dc73dab8 100644 (file)
@@ -423,3 +423,23 @@ delegpt_add_rrset(struct delegpt* dp, struct regional* region,
        log_warn("Unknown rrset type added to delegpt");
        return 1;
 }
+
+void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
+{
+       struct reply_info* rep = (struct reply_info*)msg->entry.data;
+       if(!rep) return;
+
+       /* if error or no answers */
+       if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) {
+               struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname, 
+                       msg->key.qname_len);
+               if(ns) {
+                       if(msg->key.qtype == LDNS_RR_TYPE_A)
+                               ns->got4 = 1;
+                       else if(msg->key.qtype == LDNS_RR_TYPE_AAAA)
+                               ns->got6 = 1;
+                       if(ns->got4 && ns->got6)
+                               ns->resolved = 1;
+               }
+       }
+}
index f164a6fab407ebd4151045b1313b589c628bef9b..4445c1b0a930ac2fdceb1aed66321eb13237d5f4 100644 (file)
@@ -48,6 +48,7 @@ struct delegpt_ns;
 struct delegpt_addr;
 struct dns_msg;
 struct ub_packed_rrset_key;
+struct msgreply_entry;
 
 /**
  * Delegation Point.
@@ -299,4 +300,11 @@ size_t delegpt_count_missing_targets(struct delegpt* dp);
 struct delegpt* delegpt_from_message(struct dns_msg* msg, 
        struct regional* regional);
 
+/**
+ * Add negative message to delegation point.
+ * @param dp: delegation point.
+ * @param msg: the message added, marks off A or AAAA from an NS entry.
+ */
+void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg);
+
 #endif /* ITERATOR_ITER_DELEGPT_H */
index c1928a96bc7ae9f942be3e63dc30aa2e8e53f912..2164dd3b0937557fe70f6cd0a58659a0d6473bf9 100644 (file)
@@ -142,6 +142,30 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
        }
 }
 
+/** lookup message in message cache */
+static struct msgreply_entry* 
+msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, 
+       uint16_t qtype, uint16_t qclass, uint32_t now, int wr)
+{
+       struct lruhash_entry* e;
+       struct query_info k;
+       hashvalue_t h;
+
+       k.qname = qname;
+       k.qname_len = qnamelen;
+       k.qtype = qtype;
+       k.qclass = qclass;
+       h = query_info_hash(&k);
+       e = slabhash_lookup(env->msg_cache, h, &k, wr);
+
+       if(!e) return NULL;
+       if( now > ((struct reply_info*)e->data)->ttl ) {
+               lock_rw_unlock(&e->lock);
+               return NULL;
+       }
+       return (struct msgreply_entry*)e->key;
+}
+
 /** find and add A and AAAA records for nameservers in delegpt */
 static int
 find_add_addrs(struct module_env* env, uint16_t qclass, 
@@ -149,6 +173,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
        struct dns_msg** msg)
 {
        struct delegpt_ns* ns;
+       struct msgreply_entry* neg;
        struct ub_packed_rrset_key* akey;
        for(ns = dp->nslist; ns; ns = ns->next) {
                akey = rrset_cache_lookup(env->rrset_cache, ns->name, 
@@ -161,6 +186,13 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
                        if(msg)
                                addr_to_additional(akey, region, *msg, now);
                        lock_rw_unlock(&akey->entry.lock);
+               } else {
+                       neg = msg_cache_lookup(env, ns->name, ns->namelen,
+                               LDNS_RR_TYPE_A, qclass, now, 0);
+                       if(neg) {
+                               delegpt_add_neg_msg(dp, neg);
+                               lock_rw_unlock(&neg->entry.lock);
+                       }
                }
                akey = rrset_cache_lookup(env->rrset_cache, ns->name, 
                        ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
@@ -172,6 +204,13 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
                        if(msg)
                                addr_to_additional(akey, region, *msg, now);
                        lock_rw_unlock(&akey->entry.lock);
+               } else {
+                       neg = msg_cache_lookup(env, ns->name, ns->namelen,
+                               LDNS_RR_TYPE_AAAA, qclass, now, 0);
+                       if(neg) {
+                               delegpt_add_neg_msg(dp, neg);
+                               lock_rw_unlock(&neg->entry.lock);
+                       }
                }
        }
        return 1;
@@ -183,6 +222,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
        struct regional* region, struct delegpt* dp)
 {
        struct delegpt_ns* ns;
+       struct msgreply_entry* neg;
        struct ub_packed_rrset_key* akey;
        uint32_t now = *env->now;
        for(ns = dp->nslist; ns; ns = ns->next) {
@@ -198,6 +238,13 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
                        log_nametypeclass(VERB_ALGO, "found in cache",
                                ns->name, LDNS_RR_TYPE_A, qclass);
                        lock_rw_unlock(&akey->entry.lock);
+               } else {
+                       neg = msg_cache_lookup(env, ns->name, ns->namelen,
+                               LDNS_RR_TYPE_A, qclass, now, 0);
+                       if(neg) {
+                               delegpt_add_neg_msg(dp, neg);
+                               lock_rw_unlock(&neg->entry.lock);
+                       }
                }
                akey = rrset_cache_lookup(env->rrset_cache, ns->name, 
                        ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
@@ -209,6 +256,13 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
                        log_nametypeclass(VERB_ALGO, "found in cache",
                                ns->name, LDNS_RR_TYPE_AAAA, qclass);
                        lock_rw_unlock(&akey->entry.lock);
+               } else {
+                       neg = msg_cache_lookup(env, ns->name, ns->namelen,
+                               LDNS_RR_TYPE_AAAA, qclass, now, 0);
+                       if(neg) {
+                               delegpt_add_neg_msg(dp, neg);
+                               lock_rw_unlock(&neg->entry.lock);
+                       }
                }
        }
        return 1;