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 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /** 37 * \file 38 * 39 * This file contains the DNS cache. 40 */ 41 #include "config.h" 42 #include "iterator/iter_delegpt.h" 43 #include "iterator/iter_utils.h" 44 #include "validator/val_nsec.h" 45 #include "validator/val_utils.h" 46 #include "iterator/iter_utils.h" 47 #include "services/cache/dns.h" 48 #include "services/cache/rrset.h" 49 #include "util/data/msgparse.h" 50 #include "util/data/msgreply.h" 51 #include "util/data/packed_rrset.h" 52 #include "util/data/dname.h" 53 #include "util/module.h" 54 #include "util/net_help.h" 55 #include "util/regional.h" 56 #include "util/config_file.h" 57 #include "sldns/sbuffer.h" 58 59 /** store rrsets in the rrset cache. 60 * @param env: module environment with caches. 61 * @param rep: contains list of rrsets to store. 62 * @param now: current time. 63 * @param leeway: during prefetch how much leeway to update TTLs. 64 * This makes rrsets expire sooner so they get updated with a new full 65 * TTL. 66 * Child side type NS does get this but TTL checks are done using the time 67 * the query was created rather than the time the answer was received. 68 * @param pside: if from parentside discovered NS, so that its NS is okay 69 * in a prefetch situation to be updated (without becoming sticky). 70 * @param qrep: update rrsets here if cache is better 71 * @param region: for qrep allocs. 72 * @param qstarttime: time when delegations were looked up, this is perhaps 73 * earlier than the time in now. The time is used to determine if RRsets 74 * of type NS have expired, so that they can only be updated using 75 * lookups of delegation points that did not use them, since they had 76 * expired then. 77 */ 78 static void 79 store_rrsets(struct module_env* env, struct reply_info* rep, time_t now, 80 time_t leeway, int pside, struct reply_info* qrep, 81 struct regional* region, time_t qstarttime) 82 { 83 size_t i; 84 time_t ttl, min_ttl = rep->ttl; 85 /* see if rrset already exists in cache, if not insert it. */ 86 for(i=0; i<rep->rrset_count; i++) { 87 rep->ref[i].key = rep->rrsets[i]; 88 rep->ref[i].id = rep->rrsets[i]->id; 89 /* update ref if it was in the cache */ 90 switch(rrset_cache_update(env->rrset_cache, &rep->ref[i], 91 env->alloc, ((ntohs(rep->ref[i].key->rk.type)== 92 LDNS_RR_TYPE_NS && !pside)?qstarttime:now) + leeway)) { 93 case 0: /* ref unchanged, item inserted */ 94 break; 95 case 2: /* ref updated, cache is superior */ 96 if(region) { 97 struct ub_packed_rrset_key* ck; 98 lock_rw_rdlock(&rep->ref[i].key->entry.lock); 99 /* if deleted rrset, do not copy it */ 100 if(rep->ref[i].key->id == 0 || 101 rep->ref[i].id != rep->ref[i].key->id) 102 ck = NULL; 103 else ck = packed_rrset_copy_region( 104 rep->ref[i].key, region, 105 ((ntohs(rep->ref[i].key->rk.type)== 106 LDNS_RR_TYPE_NS && !pside)?qstarttime:now)); 107 lock_rw_unlock(&rep->ref[i].key->entry.lock); 108 if(ck) { 109 /* use cached copy if memory allows */ 110 qrep->rrsets[i] = ck; 111 ttl = ((struct packed_rrset_data*) 112 ck->entry.data)->ttl; 113 if(ttl < qrep->ttl) { 114 qrep->ttl = ttl; 115 qrep->prefetch_ttl = PREFETCH_TTL_CALC(qrep->ttl); 116 qrep->serve_expired_ttl = qrep->ttl + SERVE_EXPIRED_TTL; 117 } 118 } 119 } 120 /* no break: also copy key item */ 121 /* the line below is matched by gcc regex and silences 122 * the fallthrough warning */ 123 ATTR_FALLTHROUGH 124 /* fallthrough */ 125 case 1: /* ref updated, item inserted */ 126 rep->rrsets[i] = rep->ref[i].key; 127 /* ref was updated; make sure the message ttl is 128 * updated to the minimum of the current rrsets. */ 129 lock_rw_rdlock(&rep->ref[i].key->entry.lock); 130 /* if deleted, skip ttl update. */ 131 if(rep->ref[i].key->id != 0 && 132 rep->ref[i].id == rep->ref[i].key->id) { 133 ttl = ((struct packed_rrset_data*) 134 rep->rrsets[i]->entry.data)->ttl; 135 if(ttl < min_ttl) min_ttl = ttl; 136 } 137 lock_rw_unlock(&rep->ref[i].key->entry.lock); 138 } 139 } 140 if(min_ttl < rep->ttl) { 141 rep->ttl = min_ttl; 142 rep->prefetch_ttl = PREFETCH_TTL_CALC(rep->ttl); 143 rep->serve_expired_ttl = rep->ttl + SERVE_EXPIRED_TTL; 144 } 145 } 146 147 /** delete message from message cache */ 148 void 149 msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen, 150 uint16_t qtype, uint16_t qclass, uint16_t flags) 151 { 152 struct query_info k; 153 hashvalue_type h; 154 155 k.qname = qname; 156 k.qname_len = qnamelen; 157 k.qtype = qtype; 158 k.qclass = qclass; 159 k.local_alias = NULL; 160 h = query_info_hash(&k, flags); 161 slabhash_remove(env->msg_cache, h, &k); 162 } 163 164 void 165 dns_cache_store_msg(struct module_env* env, struct query_info* qinfo, 166 hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside, 167 struct reply_info* qrep, uint32_t flags, struct regional* region, 168 time_t qstarttime) 169 { 170 struct msgreply_entry* e; 171 time_t ttl = rep->ttl; 172 size_t i; 173 174 /* store RRsets */ 175 for(i=0; i<rep->rrset_count; i++) { 176 rep->ref[i].key = rep->rrsets[i]; 177 rep->ref[i].id = rep->rrsets[i]->id; 178 } 179 180 /* there was a reply_info_sortref(rep) here but it seems to be 181 * unnecessary, because the cache gets locked per rrset. */ 182 if((flags & DNSCACHE_STORE_EXPIRED_MSG_CACHEDB)) { 183 reply_info_absolute_ttls(rep, *env->now, *env->now - ttl); 184 } else reply_info_set_ttls(rep, *env->now); 185 store_rrsets(env, rep, *env->now, leeway, pside, qrep, region, 186 qstarttime); 187 if(ttl == 0) { 188 /* we do not store the message, but we did store the RRs, 189 * which could be useful for delegation information */ 190 verbose(VERB_ALGO, "TTL 0: dropped msg from cache"); 191 reply_info_delete(rep, NULL); 192 /* if the message is in the cache, remove that msg, 193 * so that the TTL 0 response can be returned for future 194 * responses (i.e. don't get answered from 195 * cache, but instead go to recursion to get this TTL0 196 * response). 197 * Possible messages that could be in the cache: 198 * - SERVFAIL 199 * - NXDOMAIN 200 * - NODATA 201 * - an older record that is expired 202 * - an older record that did not yet expire */ 203 msg_cache_remove(env, qinfo->qname, qinfo->qname_len, 204 qinfo->qtype, qinfo->qclass, flags); 205 return; 206 } 207 208 /* store msg in the cache */ 209 reply_info_sortref(rep); 210 if(!(e = query_info_entrysetup(qinfo, rep, hash))) { 211 log_err("store_msg: malloc failed"); 212 reply_info_delete(rep, NULL); 213 return; 214 } 215 slabhash_insert(env->msg_cache, hash, &e->entry, rep, env->alloc); 216 } 217 218 /** find closest NS or DNAME and returns the rrset (locked) */ 219 static struct ub_packed_rrset_key* 220 find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen, 221 uint16_t qclass, time_t now, uint16_t searchtype, int stripfront, 222 int noexpiredabove, uint8_t* expiretop, size_t expiretoplen) 223 { 224 struct ub_packed_rrset_key *rrset; 225 uint8_t lablen; 226 227 if(stripfront) { 228 /* strip off so that DNAMEs have strict subdomain match */ 229 lablen = *qname; 230 qname += lablen + 1; 231 qnamelen -= lablen + 1; 232 } 233 234 /* snip off front part of qname until the type is found */ 235 while(qnamelen > 0) { 236 rrset = rrset_cache_lookup(env->rrset_cache, qname, 237 qnamelen, searchtype, qclass, 0, now, 0); 238 if(!rrset && searchtype == LDNS_RR_TYPE_DNAME) 239 /* If not found, for type DNAME, try 0TTL stored, 240 * for its grace period. */ 241 rrset = rrset_cache_lookup(env->rrset_cache, qname, 242 qnamelen, searchtype, qclass, 243 PACKED_RRSET_UPSTREAM_0TTL, now, 0); 244 if(rrset) { 245 uint8_t* origqname = qname; 246 size_t origqnamelen = qnamelen; 247 if(!noexpiredabove) 248 return rrset; 249 /* if expiretop set, do not look above it, but 250 * qname is equal, so the just found result is also 251 * the nonexpired above part. */ 252 if(expiretop && qnamelen == expiretoplen && 253 query_dname_compare(qname, expiretop)==0) 254 return rrset; 255 /* check for expiry, but we have to let go of the rrset 256 * for the lock ordering */ 257 lock_rw_unlock(&rrset->entry.lock); 258 /* the rrset_cache_expired_above function always takes 259 * off one label (if qnamelen>0) and returns the final 260 * qname where it searched, so we can continue from 261 * there turning the O N*N search into O N. */ 262 if(!rrset_cache_expired_above(env->rrset_cache, &qname, 263 &qnamelen, searchtype, qclass, now, expiretop, 264 expiretoplen)) { 265 /* we want to return rrset, but it may be 266 * gone from cache, if so, just loop like 267 * it was not in the cache in the first place. 268 */ 269 if((rrset = rrset_cache_lookup(env-> 270 rrset_cache, origqname, origqnamelen, 271 searchtype, qclass, 0, now, 0))) { 272 return rrset; 273 } 274 } 275 log_nametypeclass(VERB_ALGO, "ignoring rrset because expired rrsets exist above it", origqname, searchtype, qclass); 276 continue; 277 } 278 279 /* snip off front label */ 280 lablen = *qname; 281 if(lablen == 0) 282 break; 283 qname += lablen + 1; 284 qnamelen -= lablen + 1; 285 } 286 return NULL; 287 } 288 289 /** add addr to additional section */ 290 static void 291 addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region, 292 struct dns_msg* msg, time_t now) 293 { 294 if((msg->rep->rrsets[msg->rep->rrset_count] = 295 packed_rrset_copy_region(rrset, region, now))) { 296 struct packed_rrset_data* d = rrset->entry.data; 297 msg->rep->ar_numrrsets++; 298 msg->rep->rrset_count++; 299 UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); 300 } 301 } 302 303 /** lookup message in message cache */ 304 struct msgreply_entry* 305 msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, 306 uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr) 307 { 308 struct lruhash_entry* e; 309 struct query_info k; 310 hashvalue_type h; 311 312 k.qname = qname; 313 k.qname_len = qnamelen; 314 k.qtype = qtype; 315 k.qclass = qclass; 316 k.local_alias = NULL; 317 h = query_info_hash(&k, flags); 318 e = slabhash_lookup(env->msg_cache, h, &k, wr); 319 320 if(!e) return NULL; 321 if( now > ((struct reply_info*)e->data)->ttl ) { 322 lock_rw_unlock(&e->lock); 323 return NULL; 324 } 325 return (struct msgreply_entry*)e->key; 326 } 327 328 /** find and add A and AAAA records for nameservers in delegpt */ 329 static int 330 find_add_addrs(struct module_env* env, uint16_t qclass, 331 struct regional* region, struct delegpt* dp, time_t now, 332 struct dns_msg** msg) 333 { 334 struct delegpt_ns* ns; 335 struct msgreply_entry* neg; 336 struct ub_packed_rrset_key* akey; 337 for(ns = dp->nslist; ns; ns = ns->next) { 338 akey = rrset_cache_lookup(env->rrset_cache, ns->name, 339 ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0); 340 if(akey) { 341 if(!delegpt_add_rrset_A(dp, region, akey, 0, NULL)) { 342 lock_rw_unlock(&akey->entry.lock); 343 return 0; 344 } 345 if(msg) 346 addr_to_additional(akey, region, *msg, now); 347 lock_rw_unlock(&akey->entry.lock); 348 } else { 349 /* BIT_CD on false because delegpt lookup does 350 * not use dns64 translation */ 351 neg = msg_cache_lookup(env, ns->name, ns->namelen, 352 LDNS_RR_TYPE_A, qclass, 0, now, 0); 353 if(neg) { 354 delegpt_add_neg_msg(dp, neg); 355 lock_rw_unlock(&neg->entry.lock); 356 } 357 } 358 akey = rrset_cache_lookup(env->rrset_cache, ns->name, 359 ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); 360 if(akey) { 361 if(!delegpt_add_rrset_AAAA(dp, region, akey, 0, NULL)) { 362 lock_rw_unlock(&akey->entry.lock); 363 return 0; 364 } 365 if(msg) 366 addr_to_additional(akey, region, *msg, now); 367 lock_rw_unlock(&akey->entry.lock); 368 } else { 369 /* BIT_CD on false because delegpt lookup does 370 * not use dns64 translation */ 371 neg = msg_cache_lookup(env, ns->name, ns->namelen, 372 LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); 373 /* Because recursion for lookup uses BIT_CD, check 374 * for that so it stops the recursion lookup, if a 375 * negative answer is cached. Because the cache uses 376 * the CD flag for type AAAA. */ 377 if(!neg) 378 neg = msg_cache_lookup(env, ns->name, ns->namelen, 379 LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0); 380 if(neg) { 381 delegpt_add_neg_msg(dp, neg); 382 lock_rw_unlock(&neg->entry.lock); 383 } 384 } 385 } 386 return 1; 387 } 388 389 /** find and add A and AAAA records for missing nameservers in delegpt */ 390 int 391 cache_fill_missing(struct module_env* env, uint16_t qclass, 392 struct regional* region, struct delegpt* dp, uint32_t flags) 393 { 394 struct delegpt_ns* ns; 395 struct msgreply_entry* neg; 396 struct ub_packed_rrset_key* akey; 397 time_t now = *env->now; 398 for(ns = dp->nslist; ns; ns = ns->next) { 399 if(ns->cache_lookup_count > ITERATOR_NAME_CACHELOOKUP_MAX) 400 continue; 401 ns->cache_lookup_count++; 402 akey = rrset_cache_lookup(env->rrset_cache, ns->name, 403 ns->namelen, LDNS_RR_TYPE_A, qclass, flags, now, 0); 404 if(akey) { 405 if(!delegpt_add_rrset_A(dp, region, akey, ns->lame, 406 NULL)) { 407 lock_rw_unlock(&akey->entry.lock); 408 return 0; 409 } 410 log_nametypeclass(VERB_ALGO, "found in cache", 411 ns->name, LDNS_RR_TYPE_A, qclass); 412 lock_rw_unlock(&akey->entry.lock); 413 } else { 414 /* BIT_CD on false because delegpt lookup does 415 * not use dns64 translation */ 416 neg = msg_cache_lookup(env, ns->name, ns->namelen, 417 LDNS_RR_TYPE_A, qclass, 0, now, 0); 418 if(neg) { 419 delegpt_add_neg_msg(dp, neg); 420 lock_rw_unlock(&neg->entry.lock); 421 } 422 } 423 akey = rrset_cache_lookup(env->rrset_cache, ns->name, 424 ns->namelen, LDNS_RR_TYPE_AAAA, qclass, flags, now, 0); 425 if(akey) { 426 if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame, 427 NULL)) { 428 lock_rw_unlock(&akey->entry.lock); 429 return 0; 430 } 431 log_nametypeclass(VERB_ALGO, "found in cache", 432 ns->name, LDNS_RR_TYPE_AAAA, qclass); 433 lock_rw_unlock(&akey->entry.lock); 434 } else { 435 /* BIT_CD on false because delegpt lookup does 436 * not use dns64 translation */ 437 neg = msg_cache_lookup(env, ns->name, ns->namelen, 438 LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); 439 /* Because recursion for lookup uses BIT_CD, check 440 * for that so it stops the recursion lookup, if a 441 * negative answer is cached. Because the cache uses 442 * the CD flag for type AAAA. */ 443 if(!neg) 444 neg = msg_cache_lookup(env, ns->name, ns->namelen, 445 LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0); 446 if(neg) { 447 delegpt_add_neg_msg(dp, neg); 448 lock_rw_unlock(&neg->entry.lock); 449 } 450 } 451 } 452 return 1; 453 } 454 455 /** find and add DS or NSEC to delegation msg */ 456 static void 457 find_add_ds(struct module_env* env, struct regional* region, 458 struct dns_msg* msg, struct delegpt* dp, time_t now) 459 { 460 /* Lookup the DS or NSEC at the delegation point. */ 461 struct ub_packed_rrset_key* rrset = rrset_cache_lookup( 462 env->rrset_cache, dp->name, dp->namelen, LDNS_RR_TYPE_DS, 463 msg->qinfo.qclass, 0, now, 0); 464 if(!rrset) { 465 /* NOTE: this won't work for alternate NSEC schemes 466 * (opt-in, NSEC3) */ 467 rrset = rrset_cache_lookup(env->rrset_cache, dp->name, 468 dp->namelen, LDNS_RR_TYPE_NSEC, msg->qinfo.qclass, 469 0, now, 0); 470 /* Note: the PACKED_RRSET_NSEC_AT_APEX flag is not used. 471 * since this is a referral, we need the NSEC at the parent 472 * side of the zone cut, not the NSEC at apex side. */ 473 if(rrset && nsec_has_type(rrset, LDNS_RR_TYPE_DS)) { 474 lock_rw_unlock(&rrset->entry.lock); 475 rrset = NULL; /* discard wrong NSEC */ 476 } 477 } 478 if(rrset) { 479 /* add it to auth section. This is the second rrset. */ 480 if((msg->rep->rrsets[msg->rep->rrset_count] = 481 packed_rrset_copy_region(rrset, region, now))) { 482 struct packed_rrset_data* d = rrset->entry.data; 483 msg->rep->ns_numrrsets++; 484 msg->rep->rrset_count++; 485 UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); 486 } 487 lock_rw_unlock(&rrset->entry.lock); 488 } 489 } 490 491 struct dns_msg* 492 dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype, 493 uint16_t qclass, struct regional* region, size_t capacity) 494 { 495 struct dns_msg* msg = (struct dns_msg*)regional_alloc(region, 496 sizeof(struct dns_msg)); 497 if(!msg) 498 return NULL; 499 msg->qinfo.qname = regional_alloc_init(region, qname, qnamelen); 500 if(!msg->qinfo.qname) 501 return NULL; 502 msg->qinfo.qname_len = qnamelen; 503 msg->qinfo.qtype = qtype; 504 msg->qinfo.qclass = qclass; 505 msg->qinfo.local_alias = NULL; 506 /* non-packed reply_info, because it needs to grow the array */ 507 msg->rep = (struct reply_info*)regional_alloc_zero(region, 508 sizeof(struct reply_info)-sizeof(struct rrset_ref)); 509 if(!msg->rep) 510 return NULL; 511 if(capacity > RR_COUNT_MAX) 512 return NULL; /* integer overflow protection */ 513 msg->rep->flags = BIT_QR; /* with QR, no AA */ 514 msg->rep->qdcount = 1; 515 msg->rep->ttl = MAX_TTL; /* will be updated (brought down) while we add 516 * rrsets to the message */ 517 msg->rep->reason_bogus = LDNS_EDE_NONE; 518 msg->rep->rrsets = (struct ub_packed_rrset_key**) 519 regional_alloc(region, 520 capacity*sizeof(struct ub_packed_rrset_key*)); 521 if(!msg->rep->rrsets) 522 return NULL; 523 return msg; 524 } 525 526 int 527 dns_msg_authadd(struct dns_msg* msg, struct regional* region, 528 struct ub_packed_rrset_key* rrset, time_t now) 529 { 530 struct packed_rrset_data* d = rrset->entry.data; 531 if(!(msg->rep->rrsets[msg->rep->rrset_count++] = 532 packed_rrset_copy_region(rrset, region, now))) 533 return 0; 534 msg->rep->ns_numrrsets++; 535 UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); 536 return 1; 537 } 538 539 int 540 dns_msg_ansadd(struct dns_msg* msg, struct regional* region, 541 struct ub_packed_rrset_key* rrset, time_t now) 542 { 543 struct packed_rrset_data* d = rrset->entry.data; 544 if(!(msg->rep->rrsets[msg->rep->rrset_count++] = 545 packed_rrset_copy_region(rrset, region, now))) 546 return 0; 547 msg->rep->an_numrrsets++; 548 UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); 549 return 1; 550 } 551 552 struct delegpt* 553 dns_cache_find_delegation(struct module_env* env, uint8_t* qname, 554 size_t qnamelen, uint16_t qtype, uint16_t qclass, 555 struct regional* region, struct dns_msg** msg, time_t now, 556 int noexpiredabove, uint8_t* expiretop, size_t expiretoplen) 557 { 558 /* try to find closest NS rrset */ 559 struct ub_packed_rrset_key* nskey; 560 struct packed_rrset_data* nsdata; 561 struct delegpt* dp; 562 563 nskey = find_closest_of_type(env, qname, qnamelen, qclass, now, 564 LDNS_RR_TYPE_NS, 0, noexpiredabove, expiretop, expiretoplen); 565 if(!nskey) /* hope the caller has hints to prime or something */ 566 return NULL; 567 nsdata = (struct packed_rrset_data*)nskey->entry.data; 568 /* got the NS key, create delegation point */ 569 dp = delegpt_create(region); 570 if(!dp || !delegpt_set_name(dp, region, nskey->rk.dname)) { 571 lock_rw_unlock(&nskey->entry.lock); 572 log_err("find_delegation: out of memory"); 573 return NULL; 574 } 575 /* create referral message */ 576 if(msg) { 577 /* allocate the array to as much as we could need: 578 * NS rrset + DS/NSEC rrset + 579 * A rrset for every NS RR 580 * AAAA rrset for every NS RR 581 */ 582 *msg = dns_msg_create(qname, qnamelen, qtype, qclass, region, 583 2 + nsdata->count*2); 584 if(!*msg || !dns_msg_authadd(*msg, region, nskey, now)) { 585 lock_rw_unlock(&nskey->entry.lock); 586 log_err("find_delegation: out of memory"); 587 return NULL; 588 } 589 } 590 if(!delegpt_rrset_add_ns(dp, region, nskey, 0, 591 deleg_port_number(env))) { 592 lock_rw_unlock(&nskey->entry.lock); 593 log_err("find_delegation: addns out of memory"); 594 return NULL; 595 } 596 lock_rw_unlock(&nskey->entry.lock); /* first unlock before next lookup*/ 597 /* find and add DS/NSEC (if any) */ 598 if(msg) 599 find_add_ds(env, region, *msg, dp, now); 600 /* find and add A entries */ 601 if(!find_add_addrs(env, qclass, region, dp, now, msg)) 602 log_err("find_delegation: addrs out of memory"); 603 return dp; 604 } 605 606 /** allocate dns_msg from query_info and reply_info */ 607 static struct dns_msg* 608 gen_dns_msg(struct regional* region, struct query_info* q, size_t num) 609 { 610 struct dns_msg* msg = (struct dns_msg*)regional_alloc(region, 611 sizeof(struct dns_msg)); 612 if(!msg) 613 return NULL; 614 memcpy(&msg->qinfo, q, sizeof(struct query_info)); 615 msg->qinfo.qname = regional_alloc_init(region, q->qname, q->qname_len); 616 if(!msg->qinfo.qname) 617 return NULL; 618 /* allocate replyinfo struct and rrset key array separately */ 619 msg->rep = (struct reply_info*)regional_alloc(region, 620 sizeof(struct reply_info) - sizeof(struct rrset_ref)); 621 if(!msg->rep) 622 return NULL; 623 msg->rep->ttl = MAX_TTL; 624 msg->rep->reason_bogus = LDNS_EDE_NONE; 625 msg->rep->reason_bogus_str = NULL; 626 if(num > RR_COUNT_MAX) 627 return NULL; /* integer overflow protection */ 628 msg->rep->rrsets = (struct ub_packed_rrset_key**) 629 regional_alloc(region, 630 num * sizeof(struct ub_packed_rrset_key*)); 631 if(!msg->rep->rrsets) 632 return NULL; 633 return msg; 634 } 635 636 struct dns_msg* 637 tomsg(struct module_env* env, struct query_info* q, struct reply_info* r, 638 struct regional* region, time_t now, int allow_expired, 639 struct regional* scratch) 640 { 641 struct dns_msg* msg; 642 size_t i; 643 int is_expired = 0; 644 time_t now_control = now; 645 if(TTL_IS_EXPIRED(r->ttl, now)) { 646 /* Check if we are allowed to serve expired */ 647 if(!allow_expired || !reply_info_can_answer_expired(r, now)) 648 return NULL; 649 /* Change the current time so we can pass the below TTL checks 650 * when serving expired data. */ 651 now_control = 0; 652 is_expired = 1; 653 } 654 655 msg = gen_dns_msg(region, q, r->rrset_count); 656 if(!msg) return NULL; 657 msg->rep->flags = r->flags; 658 msg->rep->qdcount = r->qdcount; 659 msg->rep->security = r->security; 660 msg->rep->an_numrrsets = r->an_numrrsets; 661 msg->rep->ns_numrrsets = r->ns_numrrsets; 662 msg->rep->ar_numrrsets = r->ar_numrrsets; 663 msg->rep->rrset_count = r->rrset_count; 664 msg->rep->authoritative = r->authoritative; 665 msg->rep->reason_bogus = r->reason_bogus; 666 if(r->reason_bogus_str) { 667 msg->rep->reason_bogus_str = regional_strdup(region, r->reason_bogus_str); 668 } 669 670 if(!rrset_array_lock(r->ref, r->rrset_count, now_control)) { 671 return NULL; 672 } 673 if(r->an_numrrsets > 0 && (r->rrsets[0]->rk.type == htons( 674 LDNS_RR_TYPE_CNAME) || r->rrsets[0]->rk.type == htons( 675 LDNS_RR_TYPE_DNAME)) && !reply_check_cname_chain(q, r)) { 676 /* cname chain is now invalid, reconstruct msg */ 677 rrset_array_unlock(r->ref, r->rrset_count); 678 return NULL; 679 } 680 if(r->security == sec_status_secure && !reply_an_ns_rrsets_secure(r)) { 681 /* message rrsets have changed status, revalidate */ 682 rrset_array_unlock(r->ref, r->rrset_count); 683 return NULL; 684 } 685 for(i=0; i<msg->rep->rrset_count; i++) { 686 struct packed_rrset_data* d; 687 msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i], 688 region, now); 689 if(!msg->rep->rrsets[i]) { 690 rrset_array_unlock(r->ref, r->rrset_count); 691 return NULL; 692 } 693 d = msg->rep->rrsets[i]->entry.data; 694 UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); 695 } 696 if(msg->rep->rrset_count < 1) { 697 msg->rep->ttl = is_expired 698 ?SERVE_EXPIRED_REPLY_TTL 699 :r->ttl - now; 700 if(r->prefetch_ttl > now) 701 msg->rep->prefetch_ttl = r->prefetch_ttl - now; 702 else 703 msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); 704 } else { 705 /* msg->rep->ttl has been updated through the RRSets above */ 706 msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); 707 } 708 msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; 709 msg->rep->serve_expired_norec_ttl = 0; 710 if(env) 711 rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref, 712 r->rrset_count); 713 else 714 rrset_array_unlock(r->ref, r->rrset_count); 715 return msg; 716 } 717 718 struct dns_msg* 719 dns_msg_deepcopy_region(struct dns_msg* origin, struct regional* region) 720 { 721 size_t i; 722 struct ub_packed_rrset_key** saved_rrsets; 723 struct dns_msg* res = NULL; 724 size_t rep_alloc_size = sizeof(struct reply_info) 725 - sizeof(struct rrset_ref); /* this is the size of res->rep 726 allocated in gen_dns_msg() */ 727 res = gen_dns_msg(region, &origin->qinfo, origin->rep->rrset_count); 728 if(!res) return NULL; 729 saved_rrsets = res->rep->rrsets; /* save rrsets alloc by gen_dns_msg */ 730 memcpy(res->rep, origin->rep, rep_alloc_size); 731 res->rep->rrsets = saved_rrsets; 732 if(origin->rep->reason_bogus_str) { 733 res->rep->reason_bogus_str = regional_strdup(region, 734 origin->rep->reason_bogus_str); 735 } 736 for(i=0; i<res->rep->rrset_count; i++) { 737 res->rep->rrsets[i] = packed_rrset_copy_region( 738 origin->rep->rrsets[i], region, 0); 739 if(!res->rep->rrsets[i]) { 740 return NULL; 741 } 742 } 743 return res; 744 } 745 746 /** synthesize RRset-only response from cached RRset item */ 747 static struct dns_msg* 748 rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region, 749 time_t now, struct query_info* q) 750 { 751 struct dns_msg* msg; 752 struct packed_rrset_data* d = (struct packed_rrset_data*) 753 rrset->entry.data; 754 if(TTL_IS_EXPIRED(d->ttl, now)) 755 return NULL; 756 msg = gen_dns_msg(region, q, 1); /* only the CNAME (or other) RRset */ 757 if(!msg) 758 return NULL; 759 msg->rep->flags = BIT_QR; /* reply, no AA, no error */ 760 msg->rep->authoritative = 0; /* reply stored in cache can't be authoritative */ 761 msg->rep->qdcount = 1; 762 msg->rep->ttl = d->ttl - now; 763 msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); 764 msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; 765 msg->rep->serve_expired_norec_ttl = 0; 766 msg->rep->security = sec_status_unchecked; 767 msg->rep->an_numrrsets = 1; 768 msg->rep->ns_numrrsets = 0; 769 msg->rep->ar_numrrsets = 0; 770 msg->rep->rrset_count = 1; 771 msg->rep->reason_bogus = LDNS_EDE_NONE; 772 msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now); 773 if(!msg->rep->rrsets[0]) /* copy CNAME */ 774 return NULL; 775 return msg; 776 } 777 778 /** synthesize DNAME+CNAME response from cached DNAME item */ 779 static struct dns_msg* 780 synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region, 781 time_t now, struct query_info* q, enum sec_status* sec_status) 782 { 783 struct dns_msg* msg; 784 struct ub_packed_rrset_key* ck; 785 struct packed_rrset_data* newd, *d = (struct packed_rrset_data*) 786 rrset->entry.data; 787 uint8_t* newname, *dtarg = NULL; 788 size_t newlen, dtarglen; 789 time_t rr_ttl; 790 int graceperiod = 0; 791 if(TTL_IS_EXPIRED(d->ttl, now)) { 792 /* Allow TTL=0 DNAME from upstream within grace period */ 793 if(!(rrset->rk.flags & PACKED_RRSET_UPSTREAM_0TTL)) 794 return NULL; 795 rr_ttl = 0; 796 /* Since PACKED_RRSET_UPSTREAM_0TTL set the flag that 797 * the grace period has been applied, this stops the rrset 798 * from getting stored back into the cache with a bigger TTL.*/ 799 graceperiod = 1; 800 } else { 801 rr_ttl = d->ttl - now; 802 } 803 /* only allow validated (with DNSSEC) DNAMEs used from cache 804 * for insecure DNAMEs, query again. */ 805 *sec_status = d->security; 806 /* return sec status, so the status of the CNAME can be checked 807 * by the calling routine. */ 808 msg = gen_dns_msg(region, q, 2); /* DNAME + CNAME RRset */ 809 if(!msg) 810 return NULL; 811 msg->rep->flags = BIT_QR; /* reply, no AA, no error */ 812 msg->rep->authoritative = 0; /* reply stored in cache can't be authoritative */ 813 msg->rep->qdcount = 1; 814 msg->rep->ttl = rr_ttl; 815 msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); 816 msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; 817 msg->rep->serve_expired_norec_ttl = 0; 818 msg->rep->security = sec_status_unchecked; 819 msg->rep->an_numrrsets = 1; 820 msg->rep->ns_numrrsets = 0; 821 msg->rep->ar_numrrsets = 0; 822 msg->rep->rrset_count = 1; 823 msg->rep->reason_bogus = LDNS_EDE_NONE; 824 msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now); 825 if(!msg->rep->rrsets[0]) /* copy DNAME */ 826 return NULL; 827 if(graceperiod) 828 msg->rep->rrsets[0]->rk.flags |= PACKED_RRSET_0TTL_GRACE; 829 /* synth CNAME rrset */ 830 get_cname_target(rrset, &dtarg, &dtarglen); 831 if(!dtarg) 832 return NULL; 833 newlen = q->qname_len + dtarglen - rrset->rk.dname_len; 834 if(newlen > LDNS_MAX_DOMAINLEN) { 835 msg->rep->flags |= LDNS_RCODE_YXDOMAIN; 836 return msg; 837 } 838 newname = (uint8_t*)regional_alloc(region, newlen); 839 if(!newname) 840 return NULL; 841 /* new name is concatenation of qname front (without DNAME owner) 842 * and DNAME target name */ 843 memcpy(newname, q->qname, q->qname_len-rrset->rk.dname_len); 844 memmove(newname+(q->qname_len-rrset->rk.dname_len), dtarg, dtarglen); 845 /* create rest of CNAME rrset */ 846 ck = (struct ub_packed_rrset_key*)regional_alloc(region, 847 sizeof(struct ub_packed_rrset_key)); 848 if(!ck) 849 return NULL; 850 memset(&ck->entry, 0, sizeof(ck->entry)); 851 msg->rep->rrsets[1] = ck; 852 ck->entry.key = ck; 853 ck->rk.type = htons(LDNS_RR_TYPE_CNAME); 854 ck->rk.rrset_class = rrset->rk.rrset_class; 855 ck->rk.flags = 0; 856 ck->rk.dname = regional_alloc_init(region, q->qname, q->qname_len); 857 if(!ck->rk.dname) 858 return NULL; 859 ck->rk.dname_len = q->qname_len; 860 ck->entry.hash = rrset_key_hash(&ck->rk); 861 newd = (struct packed_rrset_data*)regional_alloc_zero(region, 862 sizeof(struct packed_rrset_data) + sizeof(size_t) + 863 sizeof(uint8_t*) + sizeof(time_t) + sizeof(uint16_t) 864 + newlen); 865 if(!newd) 866 return NULL; 867 ck->entry.data = newd; 868 newd->ttl = rr_ttl; /* RFC6672: synth CNAME TTL == DNAME TTL */ 869 newd->count = 1; 870 newd->rrsig_count = 0; 871 newd->trust = rrset_trust_ans_noAA; 872 newd->rr_len = (size_t*)((uint8_t*)newd + 873 sizeof(struct packed_rrset_data)); 874 newd->rr_len[0] = newlen + sizeof(uint16_t); 875 packed_rrset_ptr_fixup(newd); 876 newd->rr_ttl[0] = newd->ttl; 877 msg->rep->ttl = newd->ttl; 878 msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(newd->ttl); 879 msg->rep->serve_expired_ttl = newd->ttl + SERVE_EXPIRED_TTL; 880 sldns_write_uint16(newd->rr_data[0], newlen); 881 memmove(newd->rr_data[0] + sizeof(uint16_t), newname, newlen); 882 msg->rep->an_numrrsets ++; 883 msg->rep->rrset_count ++; 884 return msg; 885 } 886 887 /** Fill TYPE_ANY response with some data from cache */ 888 static struct dns_msg* 889 fill_any(struct module_env* env, 890 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 891 struct regional* region) 892 { 893 time_t now = *env->now; 894 struct dns_msg* msg = NULL; 895 uint16_t lookup[] = {LDNS_RR_TYPE_A, LDNS_RR_TYPE_AAAA, 896 LDNS_RR_TYPE_MX, LDNS_RR_TYPE_SOA, LDNS_RR_TYPE_NS, 897 LDNS_RR_TYPE_DNAME, 0}; 898 int i, num=6; /* number of RR types to look up */ 899 log_assert(lookup[num] == 0); 900 901 if(env->cfg->deny_any) { 902 /* return empty message */ 903 msg = dns_msg_create(qname, qnamelen, qtype, qclass, 904 region, 0); 905 if(!msg) { 906 return NULL; 907 } 908 /* set NOTIMPL for RFC 8482 */ 909 msg->rep->flags |= LDNS_RCODE_NOTIMPL; 910 msg->rep->security = sec_status_indeterminate; 911 msg->rep->ttl = 1; /* empty NOTIMPL response will never be 912 * updated with rrsets, set TTL to 1 */ 913 return msg; 914 } 915 916 for(i=0; i<num; i++) { 917 /* look up this RR for inclusion in type ANY response */ 918 struct ub_packed_rrset_key* rrset = rrset_cache_lookup( 919 env->rrset_cache, qname, qnamelen, lookup[i], 920 qclass, 0, now, 0); 921 struct packed_rrset_data *d; 922 if(!rrset) 923 continue; 924 925 /* only if rrset from answer section */ 926 d = (struct packed_rrset_data*)rrset->entry.data; 927 if(d->trust == rrset_trust_add_noAA || 928 d->trust == rrset_trust_auth_noAA || 929 d->trust == rrset_trust_add_AA || 930 d->trust == rrset_trust_auth_AA) { 931 lock_rw_unlock(&rrset->entry.lock); 932 continue; 933 } 934 935 /* create msg if none */ 936 if(!msg) { 937 msg = dns_msg_create(qname, qnamelen, qtype, qclass, 938 region, (size_t)(num-i)); 939 if(!msg) { 940 lock_rw_unlock(&rrset->entry.lock); 941 return NULL; 942 } 943 } 944 945 /* add RRset to response */ 946 if(!dns_msg_ansadd(msg, region, rrset, now)) { 947 lock_rw_unlock(&rrset->entry.lock); 948 return NULL; 949 } 950 lock_rw_unlock(&rrset->entry.lock); 951 } 952 return msg; 953 } 954 955 struct dns_msg* 956 dns_cache_lookup(struct module_env* env, 957 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 958 uint16_t flags, struct regional* region, struct regional* scratch, 959 int no_partial, uint8_t* dpname, size_t dpnamelen) 960 { 961 struct lruhash_entry* e; 962 struct query_info k; 963 hashvalue_type h; 964 time_t now = *env->now; 965 struct ub_packed_rrset_key* rrset; 966 967 /* lookup first, this has both NXdomains and ANSWER responses */ 968 k.qname = qname; 969 k.qname_len = qnamelen; 970 k.qtype = qtype; 971 k.qclass = qclass; 972 k.local_alias = NULL; 973 h = query_info_hash(&k, flags); 974 e = slabhash_lookup(env->msg_cache, h, &k, 0); 975 if(e) { 976 struct msgreply_entry* key = (struct msgreply_entry*)e->key; 977 struct reply_info* data = (struct reply_info*)e->data; 978 struct dns_msg* msg = tomsg(env, &key->key, data, region, now, 0, 979 scratch); 980 if(msg) { 981 lock_rw_unlock(&e->lock); 982 return msg; 983 } 984 /* could be msg==NULL; due to TTL or not all rrsets available */ 985 lock_rw_unlock(&e->lock); 986 } 987 988 /* see if a DNAME exists. Checked for first, to enforce that DNAMEs 989 * are more important, the CNAME is resynthesized and thus 990 * consistent with the DNAME */ 991 if(!no_partial && 992 (rrset=find_closest_of_type(env, qname, qnamelen, qclass, now, 993 LDNS_RR_TYPE_DNAME, 1, 0, NULL, 0))) { 994 /* synthesize a DNAME+CNAME message based on this */ 995 enum sec_status sec_status = sec_status_unchecked; 996 struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k, 997 &sec_status); 998 if(msg) { 999 struct ub_packed_rrset_key* cname_rrset; 1000 lock_rw_unlock(&rrset->entry.lock); 1001 /* now, after unlocking the DNAME rrset lock, 1002 * check the sec_status, and see if we need to look 1003 * up the CNAME record associated before it can 1004 * be used */ 1005 /* normally, only secure DNAMEs allowed from cache*/ 1006 if(sec_status == sec_status_secure) 1007 return msg; 1008 /* but if we have a CNAME cached with this name, then we 1009 * have previously already allowed this name to pass. 1010 * the next cache lookup is going to fetch that CNAME itself, 1011 * but it is better to have the (unsigned)DNAME + CNAME in 1012 * that case */ 1013 cname_rrset = rrset_cache_lookup( 1014 env->rrset_cache, qname, qnamelen, 1015 LDNS_RR_TYPE_CNAME, qclass, 0, now, 0); 1016 if(cname_rrset) { 1017 /* CNAME already synthesized by 1018 * synth_dname_msg routine, so we can 1019 * straight up return the msg */ 1020 lock_rw_unlock(&cname_rrset->entry.lock); 1021 return msg; 1022 } 1023 } else { 1024 lock_rw_unlock(&rrset->entry.lock); 1025 } 1026 } 1027 1028 /* see if we have CNAME for this domain, 1029 * but not for DS records (which are part of the parent) */ 1030 if(!no_partial && qtype != LDNS_RR_TYPE_DS && 1031 (rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen, 1032 LDNS_RR_TYPE_CNAME, qclass, 0, now, 0))) { 1033 uint8_t* wc = NULL; 1034 size_t wl; 1035 /* if the rrset is not a wildcard expansion, with wcname */ 1036 /* because, if we return that CNAME rrset on its own, it is 1037 * missing the NSEC or NSEC3 proof */ 1038 if(!(val_rrset_wildcard(rrset, &wc, &wl) && wc != NULL)) { 1039 struct dns_msg* msg = rrset_msg(rrset, region, now, &k); 1040 if(msg) { 1041 lock_rw_unlock(&rrset->entry.lock); 1042 return msg; 1043 } 1044 } 1045 lock_rw_unlock(&rrset->entry.lock); 1046 } 1047 1048 /* construct DS, DNSKEY messages from rrset cache. */ 1049 if((qtype == LDNS_RR_TYPE_DS || qtype == LDNS_RR_TYPE_DNSKEY) && 1050 (rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen, 1051 qtype, qclass, 0, now, 0))) { 1052 /* if the rrset is from the additional section, and the 1053 * signatures have fallen off, then do not synthesize a msg 1054 * instead, allow a full query for signed results to happen. 1055 * Forego all rrset data from additional section, because 1056 * some signatures may not be present and cause validation 1057 * failure. 1058 */ 1059 struct packed_rrset_data *d = (struct packed_rrset_data*) 1060 rrset->entry.data; 1061 if(d->trust != rrset_trust_add_noAA && 1062 d->trust != rrset_trust_add_AA && 1063 (qtype == LDNS_RR_TYPE_DS || 1064 (d->trust != rrset_trust_auth_noAA 1065 && d->trust != rrset_trust_auth_AA) )) { 1066 struct dns_msg* msg = rrset_msg(rrset, region, now, &k); 1067 if(msg) { 1068 lock_rw_unlock(&rrset->entry.lock); 1069 return msg; 1070 } 1071 } 1072 lock_rw_unlock(&rrset->entry.lock); 1073 } 1074 1075 /* stop downwards cache search on NXDOMAIN. 1076 * Empty nonterminals are NOERROR, so an NXDOMAIN for foo 1077 * means bla.foo also does not exist. The DNSSEC proofs are 1078 * the same. We search upwards for NXDOMAINs. */ 1079 if(env->cfg->harden_below_nxdomain) { 1080 while(!dname_is_root(k.qname)) { 1081 if(dpname && dpnamelen 1082 && !dname_strict_subdomain_c(k.qname, dpname)) 1083 break; /* no synth nxdomain above the stub */ 1084 dname_remove_label(&k.qname, &k.qname_len); 1085 h = query_info_hash(&k, flags); 1086 e = slabhash_lookup(env->msg_cache, h, &k, 0); 1087 if(!e && k.qtype != LDNS_RR_TYPE_A && 1088 env->cfg->qname_minimisation) { 1089 k.qtype = LDNS_RR_TYPE_A; 1090 h = query_info_hash(&k, flags); 1091 e = slabhash_lookup(env->msg_cache, h, &k, 0); 1092 } 1093 if(e) { 1094 struct reply_info* data = (struct reply_info*)e->data; 1095 struct dns_msg* msg; 1096 if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN 1097 && data->security == sec_status_secure 1098 && (data->an_numrrsets == 0 || 1099 ntohs(data->rrsets[0]->rk.type) != LDNS_RR_TYPE_CNAME) 1100 && (msg=tomsg(env, &k, data, region, now, 0, scratch))) { 1101 lock_rw_unlock(&e->lock); 1102 msg->qinfo.qname=qname; 1103 msg->qinfo.qname_len=qnamelen; 1104 /* check that DNSSEC really works out */ 1105 msg->rep->security = sec_status_unchecked; 1106 iter_scrub_nxdomain(msg); 1107 return msg; 1108 } 1109 lock_rw_unlock(&e->lock); 1110 } 1111 k.qtype = qtype; 1112 } 1113 } 1114 1115 /* fill common RR types for ANY response to avoid requery */ 1116 if(qtype == LDNS_RR_TYPE_ANY) { 1117 return fill_any(env, qname, qnamelen, qtype, qclass, region); 1118 } 1119 1120 return NULL; 1121 } 1122 1123 int 1124 dns_cache_store(struct module_env* env, struct query_info* msgqinf, 1125 struct reply_info* msgrep, int is_referral, time_t leeway, int pside, 1126 struct regional* region, uint32_t flags, time_t qstarttime, 1127 int is_valrec) 1128 { 1129 struct reply_info* rep = NULL; 1130 if(SERVE_EXPIRED) { 1131 /* We are serving expired records. Before caching, check if a 1132 * useful expired record exists. */ 1133 struct msgreply_entry* e = msg_cache_lookup(env, 1134 msgqinf->qname, msgqinf->qname_len, msgqinf->qtype, 1135 msgqinf->qclass, flags, 0, 1); 1136 if(e) { 1137 struct reply_info* cached = e->entry.data; 1138 if(TTL_IS_EXPIRED(cached->ttl, *env->now) 1139 && reply_info_could_use_expired(cached, *env->now) 1140 /* If we are validating make sure only 1141 * validating modules can update such messages. 1142 * In that case don't cache it and let a 1143 * subsequent module handle the caching. For 1144 * example, the iterator should not replace an 1145 * expired secure answer with a fresh unchecked 1146 * one and let the validator manage caching. */ 1147 && cached->security != sec_status_bogus 1148 && (env->need_to_validate && 1149 msgrep->security == sec_status_unchecked) 1150 /* Exceptions to that rule are: 1151 * o recursions that don't need validation but 1152 * need to update the cache for coherence 1153 * (delegation information while iterating, 1154 * DNSKEY and DS lookups from validator) 1155 * o explicit RRSIG queries that are not 1156 * validated. */ 1157 && !is_valrec 1158 && msgqinf->qtype != LDNS_RR_TYPE_RRSIG) { 1159 if((int)FLAGS_GET_RCODE(msgrep->flags) != 1160 LDNS_RCODE_NOERROR && 1161 (int)FLAGS_GET_RCODE(msgrep->flags) != 1162 LDNS_RCODE_NXDOMAIN) { 1163 /* The current response has an 1164 * erroneous rcode. Adjust norec time 1165 * so that additional lookups are not 1166 * performed for some time. */ 1167 verbose(VERB_ALGO, "set " 1168 "serve-expired-norec-ttl for " 1169 "response in cache"); 1170 cached->serve_expired_norec_ttl = 1171 NORR_TTL + *env->now; 1172 if(env->cfg->serve_expired_ttl_reset && 1173 cached->serve_expired_ttl 1174 < *env->now + 1175 env->cfg->serve_expired_ttl) { 1176 /* Reset serve-expired-ttl for 1177 * valid response in cache. */ 1178 verbose(VERB_ALGO, "reset " 1179 "serve-expired-ttl " 1180 "for response in cache"); 1181 cached->serve_expired_ttl = 1182 *env->now + 1183 env->cfg->serve_expired_ttl; 1184 } 1185 } 1186 verbose(VERB_ALGO, "a validated expired entry " 1187 "could be overwritten, skip caching " 1188 "the new message at this stage"); 1189 lock_rw_unlock(&e->entry.lock); 1190 return 1; 1191 } 1192 lock_rw_unlock(&e->entry.lock); 1193 } 1194 } 1195 /* alloc, malloc properly (not in region, like msg is) */ 1196 rep = reply_info_copy(msgrep, env->alloc, NULL); 1197 if(!rep) 1198 return 0; 1199 /* ttl must be relative ;i.e. 0..86400 not time(0)+86400. 1200 * the env->now is added to message and RRsets in this routine. */ 1201 /* the leeway is used to invalidate other rrsets earlier */ 1202 if(is_referral) { 1203 /* store rrsets */ 1204 struct rrset_ref ref; 1205 size_t i; 1206 for(i=0; i<rep->rrset_count; i++) { 1207 packed_rrset_ttl_add((struct packed_rrset_data*) 1208 rep->rrsets[i]->entry.data, *env->now); 1209 ref.key = rep->rrsets[i]; 1210 ref.id = rep->rrsets[i]->id; 1211 /*ignore ret: it was in the cache, ref updated */ 1212 /* no leeway for typeNS */ 1213 (void)rrset_cache_update(env->rrset_cache, &ref, 1214 env->alloc, 1215 ((ntohs(ref.key->rk.type)==LDNS_RR_TYPE_NS 1216 && !pside) ? qstarttime:*env->now + leeway)); 1217 } 1218 reply_info_delete(rep, NULL); 1219 return 1; 1220 } else { 1221 /* store msg, and rrsets */ 1222 struct query_info qinf; 1223 hashvalue_type h; 1224 1225 qinf = *msgqinf; 1226 qinf.qname = memdup(msgqinf->qname, msgqinf->qname_len); 1227 if(!qinf.qname) { 1228 reply_info_parsedelete(rep, env->alloc); 1229 return 0; 1230 } 1231 /* fixup flags to be sensible for a reply based on the cache */ 1232 /* this module means that RA is available. It is an answer QR. 1233 * Not AA from cache. Not CD in cache (depends on client bit). */ 1234 rep->flags |= (BIT_RA | BIT_QR); 1235 rep->flags &= ~(BIT_AA | BIT_CD); 1236 h = query_info_hash(&qinf, (uint16_t)flags); 1237 dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep, 1238 flags, region, qstarttime); 1239 /* qname is used inside query_info_entrysetup, and set to 1240 * NULL. If it has not been used, free it. free(0) is safe. */ 1241 free(qinf.qname); 1242 } 1243 return 1; 1244 } 1245 1246 int 1247 dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, 1248 time_t adjust, uint16_t flags) 1249 { 1250 struct msgreply_entry* msg; 1251 msg = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len, 1252 qinfo->qtype, qinfo->qclass, flags, *env->now, 1); 1253 if(msg) { 1254 struct reply_info* rep = (struct reply_info*)msg->entry.data; 1255 if(rep) { 1256 rep->prefetch_ttl += adjust; 1257 lock_rw_unlock(&msg->entry.lock); 1258 return 1; 1259 } 1260 lock_rw_unlock(&msg->entry.lock); 1261 } 1262 return 0; 1263 } 1264