Deleted Added
full compact
dns.c (266114) dns.c (276605)
1/*
2 * services/cache/dns.c - Cache services for DNS using msg and rrset caches.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 170 unchanged lines hidden (view full) ---

179 msg->rep->ar_numrrsets++;
180 msg->rep->rrset_count++;
181 }
182}
183
184/** lookup message in message cache */
185static struct msgreply_entry*
186msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
1/*
2 * services/cache/dns.c - Cache services for DNS using msg and rrset caches.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 170 unchanged lines hidden (view full) ---

179 msg->rep->ar_numrrsets++;
180 msg->rep->rrset_count++;
181 }
182}
183
184/** lookup message in message cache */
185static struct msgreply_entry*
186msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
187 uint16_t qtype, uint16_t qclass, time_t now, int wr)
187 uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr)
188{
189 struct lruhash_entry* e;
190 struct query_info k;
191 hashvalue_t h;
192
193 k.qname = qname;
194 k.qname_len = qnamelen;
195 k.qtype = qtype;
196 k.qclass = qclass;
188{
189 struct lruhash_entry* e;
190 struct query_info k;
191 hashvalue_t h;
192
193 k.qname = qname;
194 k.qname_len = qnamelen;
195 k.qtype = qtype;
196 k.qclass = qclass;
197 h = query_info_hash(&k);
197 h = query_info_hash(&k, flags);
198 e = slabhash_lookup(env->msg_cache, h, &k, wr);
199
200 if(!e) return NULL;
201 if( now > ((struct reply_info*)e->data)->ttl ) {
202 lock_rw_unlock(&e->lock);
203 return NULL;
204 }
205 return (struct msgreply_entry*)e->key;

--- 15 unchanged lines hidden (view full) ---

221 if(!delegpt_add_rrset_A(dp, region, akey, 0)) {
222 lock_rw_unlock(&akey->entry.lock);
223 return 0;
224 }
225 if(msg)
226 addr_to_additional(akey, region, *msg, now);
227 lock_rw_unlock(&akey->entry.lock);
228 } else {
198 e = slabhash_lookup(env->msg_cache, h, &k, wr);
199
200 if(!e) return NULL;
201 if( now > ((struct reply_info*)e->data)->ttl ) {
202 lock_rw_unlock(&e->lock);
203 return NULL;
204 }
205 return (struct msgreply_entry*)e->key;

--- 15 unchanged lines hidden (view full) ---

221 if(!delegpt_add_rrset_A(dp, region, akey, 0)) {
222 lock_rw_unlock(&akey->entry.lock);
223 return 0;
224 }
225 if(msg)
226 addr_to_additional(akey, region, *msg, now);
227 lock_rw_unlock(&akey->entry.lock);
228 } else {
229 /* BIT_CD on false because delegpt lookup does
230 * not use dns64 translation */
229 neg = msg_cache_lookup(env, ns->name, ns->namelen,
231 neg = msg_cache_lookup(env, ns->name, ns->namelen,
230 LDNS_RR_TYPE_A, qclass, now, 0);
232 LDNS_RR_TYPE_A, qclass, 0, now, 0);
231 if(neg) {
232 delegpt_add_neg_msg(dp, neg);
233 lock_rw_unlock(&neg->entry.lock);
234 }
235 }
236 akey = rrset_cache_lookup(env->rrset_cache, ns->name,
237 ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
238 if(akey) {
239 if(!delegpt_add_rrset_AAAA(dp, region, akey, 0)) {
240 lock_rw_unlock(&akey->entry.lock);
241 return 0;
242 }
243 if(msg)
244 addr_to_additional(akey, region, *msg, now);
245 lock_rw_unlock(&akey->entry.lock);
246 } else {
233 if(neg) {
234 delegpt_add_neg_msg(dp, neg);
235 lock_rw_unlock(&neg->entry.lock);
236 }
237 }
238 akey = rrset_cache_lookup(env->rrset_cache, ns->name,
239 ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
240 if(akey) {
241 if(!delegpt_add_rrset_AAAA(dp, region, akey, 0)) {
242 lock_rw_unlock(&akey->entry.lock);
243 return 0;
244 }
245 if(msg)
246 addr_to_additional(akey, region, *msg, now);
247 lock_rw_unlock(&akey->entry.lock);
248 } else {
249 /* BIT_CD on false because delegpt lookup does
250 * not use dns64 translation */
247 neg = msg_cache_lookup(env, ns->name, ns->namelen,
251 neg = msg_cache_lookup(env, ns->name, ns->namelen,
248 LDNS_RR_TYPE_AAAA, qclass, now, 0);
252 LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
249 if(neg) {
250 delegpt_add_neg_msg(dp, neg);
251 lock_rw_unlock(&neg->entry.lock);
252 }
253 }
254 }
255 return 1;
256}

--- 14 unchanged lines hidden (view full) ---

271 if(!delegpt_add_rrset_A(dp, region, akey, ns->lame)) {
272 lock_rw_unlock(&akey->entry.lock);
273 return 0;
274 }
275 log_nametypeclass(VERB_ALGO, "found in cache",
276 ns->name, LDNS_RR_TYPE_A, qclass);
277 lock_rw_unlock(&akey->entry.lock);
278 } else {
253 if(neg) {
254 delegpt_add_neg_msg(dp, neg);
255 lock_rw_unlock(&neg->entry.lock);
256 }
257 }
258 }
259 return 1;
260}

--- 14 unchanged lines hidden (view full) ---

275 if(!delegpt_add_rrset_A(dp, region, akey, ns->lame)) {
276 lock_rw_unlock(&akey->entry.lock);
277 return 0;
278 }
279 log_nametypeclass(VERB_ALGO, "found in cache",
280 ns->name, LDNS_RR_TYPE_A, qclass);
281 lock_rw_unlock(&akey->entry.lock);
282 } else {
283 /* BIT_CD on false because delegpt lookup does
284 * not use dns64 translation */
279 neg = msg_cache_lookup(env, ns->name, ns->namelen,
285 neg = msg_cache_lookup(env, ns->name, ns->namelen,
280 LDNS_RR_TYPE_A, qclass, now, 0);
286 LDNS_RR_TYPE_A, qclass, 0, now, 0);
281 if(neg) {
282 delegpt_add_neg_msg(dp, neg);
283 lock_rw_unlock(&neg->entry.lock);
284 }
285 }
286 akey = rrset_cache_lookup(env->rrset_cache, ns->name,
287 ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
288 if(akey) {
289 if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame)) {
290 lock_rw_unlock(&akey->entry.lock);
291 return 0;
292 }
293 log_nametypeclass(VERB_ALGO, "found in cache",
294 ns->name, LDNS_RR_TYPE_AAAA, qclass);
295 lock_rw_unlock(&akey->entry.lock);
296 } else {
287 if(neg) {
288 delegpt_add_neg_msg(dp, neg);
289 lock_rw_unlock(&neg->entry.lock);
290 }
291 }
292 akey = rrset_cache_lookup(env->rrset_cache, ns->name,
293 ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
294 if(akey) {
295 if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame)) {
296 lock_rw_unlock(&akey->entry.lock);
297 return 0;
298 }
299 log_nametypeclass(VERB_ALGO, "found in cache",
300 ns->name, LDNS_RR_TYPE_AAAA, qclass);
301 lock_rw_unlock(&akey->entry.lock);
302 } else {
303 /* BIT_CD on false because delegpt lookup does
304 * not use dns64 translation */
297 neg = msg_cache_lookup(env, ns->name, ns->namelen,
305 neg = msg_cache_lookup(env, ns->name, ns->namelen,
298 LDNS_RR_TYPE_AAAA, qclass, now, 0);
306 LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
299 if(neg) {
300 delegpt_add_neg_msg(dp, neg);
301 lock_rw_unlock(&neg->entry.lock);
302 }
303 }
304 }
305 return 1;
306}

--- 314 unchanged lines hidden (view full) ---

621 msg->rep->an_numrrsets ++;
622 msg->rep->rrset_count ++;
623 return msg;
624}
625
626struct dns_msg*
627dns_cache_lookup(struct module_env* env,
628 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
307 if(neg) {
308 delegpt_add_neg_msg(dp, neg);
309 lock_rw_unlock(&neg->entry.lock);
310 }
311 }
312 }
313 return 1;
314}

--- 314 unchanged lines hidden (view full) ---

629 msg->rep->an_numrrsets ++;
630 msg->rep->rrset_count ++;
631 return msg;
632}
633
634struct dns_msg*
635dns_cache_lookup(struct module_env* env,
636 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
629 struct regional* region, struct regional* scratch)
637 uint16_t flags, struct regional* region, struct regional* scratch)
630{
631 struct lruhash_entry* e;
632 struct query_info k;
633 hashvalue_t h;
634 time_t now = *env->now;
635 struct ub_packed_rrset_key* rrset;
636
637 /* lookup first, this has both NXdomains and ANSWER responses */
638 k.qname = qname;
639 k.qname_len = qnamelen;
640 k.qtype = qtype;
641 k.qclass = qclass;
638{
639 struct lruhash_entry* e;
640 struct query_info k;
641 hashvalue_t h;
642 time_t now = *env->now;
643 struct ub_packed_rrset_key* rrset;
644
645 /* lookup first, this has both NXdomains and ANSWER responses */
646 k.qname = qname;
647 k.qname_len = qnamelen;
648 k.qtype = qtype;
649 k.qclass = qclass;
642 h = query_info_hash(&k);
650 h = query_info_hash(&k, flags);
643 e = slabhash_lookup(env->msg_cache, h, &k, 0);
644 if(e) {
645 struct msgreply_entry* key = (struct msgreply_entry*)e->key;
646 struct reply_info* data = (struct reply_info*)e->data;
647 struct dns_msg* msg = tomsg(env, &key->key, data, region, now,
648 scratch);
649 if(msg) {
650 lock_rw_unlock(&e->lock);

--- 60 unchanged lines hidden (view full) ---

711
712 /* stop downwards cache search on NXDOMAIN.
713 * Empty nonterminals are NOERROR, so an NXDOMAIN for foo
714 * means bla.foo also does not exist. The DNSSEC proofs are
715 * the same. We search upwards for NXDOMAINs. */
716 if(env->cfg->harden_below_nxdomain)
717 while(!dname_is_root(k.qname)) {
718 dname_remove_label(&k.qname, &k.qname_len);
651 e = slabhash_lookup(env->msg_cache, h, &k, 0);
652 if(e) {
653 struct msgreply_entry* key = (struct msgreply_entry*)e->key;
654 struct reply_info* data = (struct reply_info*)e->data;
655 struct dns_msg* msg = tomsg(env, &key->key, data, region, now,
656 scratch);
657 if(msg) {
658 lock_rw_unlock(&e->lock);

--- 60 unchanged lines hidden (view full) ---

719
720 /* stop downwards cache search on NXDOMAIN.
721 * Empty nonterminals are NOERROR, so an NXDOMAIN for foo
722 * means bla.foo also does not exist. The DNSSEC proofs are
723 * the same. We search upwards for NXDOMAINs. */
724 if(env->cfg->harden_below_nxdomain)
725 while(!dname_is_root(k.qname)) {
726 dname_remove_label(&k.qname, &k.qname_len);
719 h = query_info_hash(&k);
727 h = query_info_hash(&k, flags);
720 e = slabhash_lookup(env->msg_cache, h, &k, 0);
721 if(e) {
722 struct reply_info* data = (struct reply_info*)e->data;
723 struct dns_msg* msg;
724 if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
725 && data->security == sec_status_secure
726 && (msg=tomsg(env, &k, data, region, now, scratch))){
727 lock_rw_unlock(&e->lock);

--- 8 unchanged lines hidden (view full) ---

736 }
737
738 return NULL;
739}
740
741int
742dns_cache_store(struct module_env* env, struct query_info* msgqinf,
743 struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
728 e = slabhash_lookup(env->msg_cache, h, &k, 0);
729 if(e) {
730 struct reply_info* data = (struct reply_info*)e->data;
731 struct dns_msg* msg;
732 if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
733 && data->security == sec_status_secure
734 && (msg=tomsg(env, &k, data, region, now, scratch))){
735 lock_rw_unlock(&e->lock);

--- 8 unchanged lines hidden (view full) ---

744 }
745
746 return NULL;
747}
748
749int
750dns_cache_store(struct module_env* env, struct query_info* msgqinf,
751 struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
744 struct regional* region)
752 struct regional* region, uint16_t flags)
745{
746 struct reply_info* rep = NULL;
747 /* alloc, malloc properly (not in region, like msg is) */
748 rep = reply_info_copy(msgrep, env->alloc, NULL);
749 if(!rep)
750 return 0;
751 /* ttl must be relative ;i.e. 0..86400 not time(0)+86400.
752 * the env->now is added to message and RRsets in this routine. */

--- 28 unchanged lines hidden (view full) ---

781 reply_info_parsedelete(rep, env->alloc);
782 return 0;
783 }
784 /* fixup flags to be sensible for a reply based on the cache */
785 /* this module means that RA is available. It is an answer QR.
786 * Not AA from cache. Not CD in cache (depends on client bit). */
787 rep->flags |= (BIT_RA | BIT_QR);
788 rep->flags &= ~(BIT_AA | BIT_CD);
753{
754 struct reply_info* rep = NULL;
755 /* alloc, malloc properly (not in region, like msg is) */
756 rep = reply_info_copy(msgrep, env->alloc, NULL);
757 if(!rep)
758 return 0;
759 /* ttl must be relative ;i.e. 0..86400 not time(0)+86400.
760 * the env->now is added to message and RRsets in this routine. */

--- 28 unchanged lines hidden (view full) ---

789 reply_info_parsedelete(rep, env->alloc);
790 return 0;
791 }
792 /* fixup flags to be sensible for a reply based on the cache */
793 /* this module means that RA is available. It is an answer QR.
794 * Not AA from cache. Not CD in cache (depends on client bit). */
795 rep->flags |= (BIT_RA | BIT_QR);
796 rep->flags &= ~(BIT_AA | BIT_CD);
789 h = query_info_hash(&qinf);
797 h = query_info_hash(&qinf, flags);
790 dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
791 region);
792 /* qname is used inside query_info_entrysetup, and set to
793 * NULL. If it has not been used, free it. free(0) is safe. */
794 free(qinf.qname);
795 }
796 return 1;
797}
798 dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
799 region);
800 /* qname is used inside query_info_entrysetup, and set to
801 * NULL. If it has not been used, free it. free(0) is safe. */
802 free(qinf.qname);
803 }
804 return 1;
805}
806
807int
808dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
809 time_t adjust, uint16_t flags)
810{
811 struct msgreply_entry* msg;
812 msg = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
813 qinfo->qtype, qinfo->qclass, flags, *env->now, 1);
814 if(msg) {
815 struct reply_info* rep = (struct reply_info*)msg->entry.data;
816 if(rep) {
817 rep->prefetch_ttl += adjust;
818 lock_rw_unlock(&msg->entry.lock);
819 return 1;
820 }
821 lock_rw_unlock(&msg->entry.lock);
822 }
823 return 0;
824}