]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
cname chain caching (part).
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 19 Jul 2007 15:16:39 +0000 (15:16 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 19 Jul 2007 15:16:39 +0000 (15:16 +0000)
git-svn-id: file:///svn/unbound/trunk@440 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/worker.c
doc/Changelog
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c

index 9af0631286d22f717cf3a37be7bd159e9692080d..1dd6cdb5dcb8a3ddcde7cfd8c692b580895c36a9 100644 (file)
@@ -222,6 +222,12 @@ worker_handle_control_cmd(struct comm_point* c, void* arg, int error,
        return 0;
 }
 
+/** check cname chain in cache reply */
+static int
+check_cache_chain(struct reply_info* rep) {
+       return 1;
+}
+
 /** answer query from the cache */
 static int
 answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
@@ -246,6 +252,17 @@ answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
        if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
                return 0;
        /* locked and ids and ttls are OK. */
+       /* check CNAME chain (if any) */
+       if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type == 
+               htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type == 
+               htons(LDNS_RR_TYPE_DNAME))) {
+               if(!check_cache_chain(rep)) {
+                       rrset_array_unlock_touch(worker->env.rrset_cache, 
+                               worker->scratchpad, rep->ref, rep->rrset_count);
+                       region_free_all(worker->scratchpad);
+                       return 0;
+               }
+       }
        if(!reply_info_answer_encode(&mrentry->key, rep, id, flags, 
                repinfo->c->buffer, timenow, 1, worker->scratchpad,
                udpsize, edns, (int)(edns->bits & EDNS_DO) )) {
index e84d93a71ab2303c7a3e27f6e1f8e0f415bc3016..18e7dada7fcef6837be33f3f1168e14b32854329 100644 (file)
@@ -3,6 +3,7 @@
        - fixup of deadlock warnings, yield cpu in checklock code so that
          freebsd scheduler selects correct process to run.
        - added identity and version config options and replies.
+       - store cname messages complete answers.
 
 18 July 2007: Wouter
        - do not query addresses, 127.0.0.1, and ::1 by default.
index 53f3c3343326f84321db7f01898c6f604a700a95..656b58f5cebdade0f35df24dac4671bca9a65785 100644 (file)
@@ -293,11 +293,12 @@ dns_copy_msg(struct dns_msg* from, struct region* region)
 }
 
 int 
-iter_dns_store(struct module_env* env, struct dns_msg* msg, int is_referral)
+iter_dns_store(struct module_env* env, struct query_info* msgqinf,
+       struct reply_info* msgrep, int is_referral)
 {
        struct reply_info* rep = NULL;
        /* alloc, malloc properly (not in region, like msg is) */
-       rep = reply_info_copy(msg->rep, env->alloc, NULL);
+       rep = reply_info_copy(msgrep, env->alloc, NULL);
        if(!rep)
                return 0;
 
@@ -322,10 +323,10 @@ iter_dns_store(struct module_env* env, struct dns_msg* msg, int is_referral)
                struct query_info qinf;
                hashvalue_t h;
 
-               qinf = msg->qinfo;
-               qinf.qname = memdup(msg->qinfo.qname, msg->qinfo.qname_len);
+               qinf = *msgqinf;
+               qinf.qname = memdup(msgqinf->qname, msgqinf->qname_len);
                if(!qinf.qname) {
-                       reply_info_parsedelete(msg->rep, env->alloc);
+                       reply_info_parsedelete(rep, env->alloc);
                        return 0;
                }
                /* fixup flags to be sensible for a reply based on the cache */
index dacd954784a4e51e9ae6d003038a70d9c7f6af2a..2531ad37f4249c193a9c18843a8634a123e7b288 100644 (file)
@@ -50,6 +50,8 @@ struct delegpt;
 struct region;
 struct msg_parse;
 struct ub_randstate;
+struct query_info;
+struct reply_info;
 
 /**
  * Process config options and set iterator module state.
@@ -98,13 +100,14 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct region* region);
 /**
  * Allocate a dns_msg with malloc/alloc structure and store in dns cache.
  * @param env: environment, with alloc structure and dns cache.
- * @param msg: dns_msg from dns_alloc_msg for example.
+ * @param qinf: query info, the query for which answer is stored.
+ * @param rep: reply in dns_msg from dns_alloc_msg for example.
  * @param is_referral: If true, then the given message to be stored is a
  *     referral. The cache implementation may use this as a hint.
  * @return 0 on alloc error (out of memory).
  */
-int iter_dns_store(struct module_env* env, struct dns_msg* msg, 
-       int is_referral);
+int iter_dns_store(struct module_env* env, struct query_info* qinf,
+       struct reply_info* rep, int is_referral);
 
 /**
  * Select randomly with n/m probability.
index 5f339ed86ce108b9a40f53edfabe02a8036f6c07..44641923d5fb6a6c7a63403a186349f14d1b7c59 100644 (file)
@@ -1053,13 +1053,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                /* ANSWER type responses terminate the query algorithm, 
                 * so they sent on their */
                verbose(VERB_DETAIL, "query response was ANSWER");
-               
-               /* FIXME: there is a question about whether this gets 
-                * stored under the original query or most recent query. 
-                * The original query would reduce cache work, but you 
-                * need to apply the prependList before caching, and 
-                * also cache under the latest query. */
-               if(!iter_dns_store(qstate->env, iq->response, 0))
+               if(!iter_dns_store(qstate->env, &iq->response->qinfo,
+                       iq->response->rep, 0))
                        return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
                /* close down outstanding requests to be discarded */
                outbound_list_clear(&iq->outlist);
@@ -1073,7 +1068,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                verbose(VERB_DETAIL, "query response was REFERRAL");
 
                /* Store the referral under the current query */
-               if(!iter_dns_store(qstate->env, iq->response, 1))
+               if(!iter_dns_store(qstate->env, &iq->response->qinfo,
+                       iq->response->rep, 1))
                        return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
 
                /* Reset the event state, setting the current delegation 
@@ -1111,7 +1107,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                /* cache the CNAME response under the current query */
                /* NOTE : set referral=1, so that rrsets get stored but not 
                 * the partial query answer (CNAME only). */
-               if(!iter_dns_store(qstate->env, iq->response, 1))
+               if(!iter_dns_store(qstate->env, &iq->response->qinfo,
+                       iq->response->rep, 1))
                        return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
                /* set the current request's qname to the new value. */
                iq->qchase.qname = sname;
@@ -1347,6 +1344,10 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
                        log_err("prepend rrsets: out of memory");
                        return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
                }
+               /* store message with the finished prepended items */
+               if(!iter_dns_store(qstate->env, &qstate->qinfo, 
+                       iq->response->rep, 0))
+                       return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
        }
        if(query_dname_compare(qstate->qinfo.qname, 
                iq->response->qinfo.qname) == 0) {