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} |
|