1 /* 2 * validator/val_neg.c - validator aggressive negative caching functions. 3 * 4 * Copyright (c) 2008, 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 helper functions for the validator module. 40 * The functions help with aggressive negative caching. 41 * This creates new denials of existence, and proofs for absence of types 42 * from cached NSEC records. 43 */ 44 #include "config.h" 45 #ifdef HAVE_OPENSSL_SSL_H 46 #include <openssl/ssl.h> 47 #define NSEC3_SHA_LEN SHA_DIGEST_LENGTH 48 #else 49 #define NSEC3_SHA_LEN 20 50 #endif 51 #include "validator/val_neg.h" 52 #include "validator/val_nsec.h" 53 #include "validator/val_nsec3.h" 54 #include "validator/val_utils.h" 55 #include "util/data/dname.h" 56 #include "util/data/msgreply.h" 57 #include "util/log.h" 58 #include "util/net_help.h" 59 #include "util/config_file.h" 60 #include "services/cache/rrset.h" 61 #include "services/cache/dns.h" 62 #include "sldns/rrdef.h" 63 #include "sldns/sbuffer.h" 64 65 /** 66 * The maximum salt length that the negative cache is willing to use. 67 * Larger salt increases the computation time, while recommendations are 68 * for zero salt length for zones. 69 */ 70 #define MAX_SALT_LENGTH 64 71 72 int val_neg_data_compare(const void* a, const void* b) 73 { 74 struct val_neg_data* x = (struct val_neg_data*)a; 75 struct val_neg_data* y = (struct val_neg_data*)b; 76 int m; 77 return dname_canon_lab_cmp(x->name, x->labs, y->name, y->labs, &m); 78 } 79 80 int val_neg_zone_compare(const void* a, const void* b) 81 { 82 struct val_neg_zone* x = (struct val_neg_zone*)a; 83 struct val_neg_zone* y = (struct val_neg_zone*)b; 84 int m; 85 if(x->dclass != y->dclass) { 86 if(x->dclass < y->dclass) 87 return -1; 88 return 1; 89 } 90 return dname_canon_lab_cmp(x->name, x->labs, y->name, y->labs, &m); 91 } 92 93 struct val_neg_cache* val_neg_create(struct config_file* cfg, size_t maxiter) 94 { 95 struct val_neg_cache* neg = (struct val_neg_cache*)calloc(1, 96 sizeof(*neg)); 97 if(!neg) { 98 log_err("Could not create neg cache: out of memory"); 99 return NULL; 100 } 101 neg->nsec3_max_iter = maxiter; 102 neg->max = 1024*1024; /* 1 M is thousands of entries */ 103 if(cfg) neg->max = cfg->neg_cache_size; 104 rbtree_init(&neg->tree, &val_neg_zone_compare); 105 lock_basic_init(&neg->lock); 106 lock_protect(&neg->lock, neg, sizeof(*neg)); 107 return neg; 108 } 109 110 size_t val_neg_get_mem(struct val_neg_cache* neg) 111 { 112 size_t result; 113 lock_basic_lock(&neg->lock); 114 result = sizeof(*neg) + neg->use; 115 lock_basic_unlock(&neg->lock); 116 return result; 117 } 118 119 /** clear datas on cache deletion */ 120 static void 121 neg_clear_datas(rbnode_type* n, void* ATTR_UNUSED(arg)) 122 { 123 struct val_neg_data* d = (struct val_neg_data*)n; 124 free(d->name); 125 free(d); 126 } 127 128 /** clear zones on cache deletion */ 129 static void 130 neg_clear_zones(rbnode_type* n, void* ATTR_UNUSED(arg)) 131 { 132 struct val_neg_zone* z = (struct val_neg_zone*)n; 133 /* delete all the rrset entries in the tree */ 134 traverse_postorder(&z->tree, &neg_clear_datas, NULL); 135 free(z->nsec3_salt); 136 free(z->name); 137 free(z); 138 } 139 140 void neg_cache_delete(struct val_neg_cache* neg) 141 { 142 if(!neg) return; 143 lock_basic_destroy(&neg->lock); 144 /* delete all the zones in the tree */ 145 traverse_postorder(&neg->tree, &neg_clear_zones, NULL); 146 free(neg); 147 } 148 149 /** 150 * Put data element at the front of the LRU list. 151 * @param neg: negative cache with LRU start and end. 152 * @param data: this data is fronted. 153 */ 154 static void neg_lru_front(struct val_neg_cache* neg, 155 struct val_neg_data* data) 156 { 157 data->prev = NULL; 158 data->next = neg->first; 159 if(!neg->first) 160 neg->last = data; 161 else neg->first->prev = data; 162 neg->first = data; 163 } 164 165 /** 166 * Remove data element from LRU list. 167 * @param neg: negative cache with LRU start and end. 168 * @param data: this data is removed from the list. 169 */ 170 static void neg_lru_remove(struct val_neg_cache* neg, 171 struct val_neg_data* data) 172 { 173 if(data->prev) 174 data->prev->next = data->next; 175 else neg->first = data->next; 176 if(data->next) 177 data->next->prev = data->prev; 178 else neg->last = data->prev; 179 } 180 181 /** 182 * Touch LRU for data element, put it at the start of the LRU list. 183 * @param neg: negative cache with LRU start and end. 184 * @param data: this data is used. 185 */ 186 static void neg_lru_touch(struct val_neg_cache* neg, 187 struct val_neg_data* data) 188 { 189 if(data == neg->first) 190 return; /* nothing to do */ 191 /* remove from current lru position */ 192 neg_lru_remove(neg, data); 193 /* add at front */ 194 neg_lru_front(neg, data); 195 } 196 197 /** 198 * Delete a zone element from the negative cache. 199 * May delete other zone elements to keep tree coherent, or 200 * only mark the element as 'not in use'. 201 * @param neg: negative cache. 202 * @param z: zone element to delete. 203 */ 204 static void neg_delete_zone(struct val_neg_cache* neg, struct val_neg_zone* z) 205 { 206 struct val_neg_zone* p, *np; 207 if(!z) return; 208 log_assert(z->in_use); 209 log_assert(z->count > 0); 210 z->in_use = 0; 211 212 /* go up the tree and reduce counts */ 213 p = z; 214 while(p) { 215 log_assert(p->count > 0); 216 p->count --; 217 p = p->parent; 218 } 219 220 /* remove zones with zero count */ 221 p = z; 222 while(p && p->count == 0) { 223 np = p->parent; 224 (void)rbtree_delete(&neg->tree, &p->node); 225 neg->use -= p->len + sizeof(*p); 226 free(p->nsec3_salt); 227 free(p->name); 228 free(p); 229 p = np; 230 } 231 } 232 233 void neg_delete_data(struct val_neg_cache* neg, struct val_neg_data* el) 234 { 235 struct val_neg_zone* z; 236 struct val_neg_data* p, *np; 237 if(!el) return; 238 z = el->zone; 239 log_assert(el->in_use); 240 log_assert(el->count > 0); 241 el->in_use = 0; 242 243 /* remove it from the lru list */ 244 neg_lru_remove(neg, el); 245 log_assert(neg->first != el && neg->last != el); 246 247 /* go up the tree and reduce counts */ 248 p = el; 249 while(p) { 250 log_assert(p->count > 0); 251 p->count --; 252 p = p->parent; 253 } 254 255 /* delete 0 count items from tree */ 256 p = el; 257 while(p && p->count == 0) { 258 np = p->parent; 259 (void)rbtree_delete(&z->tree, &p->node); 260 neg->use -= p->len + sizeof(*p); 261 free(p->name); 262 free(p); 263 p = np; 264 } 265 266 /* check if the zone is now unused */ 267 if(z->tree.count == 0) { 268 neg_delete_zone(neg, z); 269 } 270 } 271 272 /** 273 * Create more space in negative cache 274 * The oldest elements are deleted until enough space is present. 275 * Empty zones are deleted. 276 * @param neg: negative cache. 277 * @param need: how many bytes are needed. 278 */ 279 static void neg_make_space(struct val_neg_cache* neg, size_t need) 280 { 281 /* delete elements until enough space or its empty */ 282 while(neg->last && neg->max < neg->use + need) { 283 neg_delete_data(neg, neg->last); 284 } 285 } 286 287 struct val_neg_zone* neg_find_zone(struct val_neg_cache* neg, 288 uint8_t* nm, size_t len, uint16_t dclass) 289 { 290 struct val_neg_zone lookfor; 291 struct val_neg_zone* result; 292 lookfor.node.key = &lookfor; 293 lookfor.name = nm; 294 lookfor.len = len; 295 lookfor.labs = dname_count_labels(lookfor.name); 296 lookfor.dclass = dclass; 297 298 result = (struct val_neg_zone*) 299 rbtree_search(&neg->tree, lookfor.node.key); 300 return result; 301 } 302 303 /** 304 * Find the given data 305 * @param zone: negative zone 306 * @param nm: what to look for. 307 * @param len: length of nm 308 * @param labs: labels in nm 309 * @return data or NULL if not found. 310 */ 311 static struct val_neg_data* neg_find_data(struct val_neg_zone* zone, 312 uint8_t* nm, size_t len, int labs) 313 { 314 struct val_neg_data lookfor; 315 struct val_neg_data* result; 316 lookfor.node.key = &lookfor; 317 lookfor.name = nm; 318 lookfor.len = len; 319 lookfor.labs = labs; 320 321 result = (struct val_neg_data*) 322 rbtree_search(&zone->tree, lookfor.node.key); 323 return result; 324 } 325 326 /** 327 * Calculate space needed for the data and all its parents 328 * @param rep: NSEC entries. 329 * @return size. 330 */ 331 static size_t calc_data_need(struct reply_info* rep) 332 { 333 uint8_t* d; 334 size_t i, len, res = 0; 335 336 for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) { 337 if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC) { 338 d = rep->rrsets[i]->rk.dname; 339 len = rep->rrsets[i]->rk.dname_len; 340 res = sizeof(struct val_neg_data) + len; 341 while(!dname_is_root(d)) { 342 log_assert(len > 1); /* not root label */ 343 dname_remove_label(&d, &len); 344 res += sizeof(struct val_neg_data) + len; 345 } 346 } 347 } 348 return res; 349 } 350 351 /** 352 * Calculate space needed for zone and all its parents 353 * @param d: name of zone 354 * @param len: length of name 355 * @return size. 356 */ 357 static size_t calc_zone_need(uint8_t* d, size_t len) 358 { 359 size_t res = sizeof(struct val_neg_zone) + len; 360 while(!dname_is_root(d)) { 361 log_assert(len > 1); /* not root label */ 362 dname_remove_label(&d, &len); 363 res += sizeof(struct val_neg_zone) + len; 364 } 365 return res; 366 } 367 368 /** 369 * Find closest existing parent zone of the given name. 370 * @param neg: negative cache. 371 * @param nm: name to look for 372 * @param nm_len: length of nm 373 * @param labs: labelcount of nm. 374 * @param qclass: class. 375 * @return the zone or NULL if none found. 376 */ 377 static struct val_neg_zone* neg_closest_zone_parent(struct val_neg_cache* neg, 378 uint8_t* nm, size_t nm_len, int labs, uint16_t qclass) 379 { 380 struct val_neg_zone key; 381 struct val_neg_zone* result; 382 rbnode_type* res = NULL; 383 key.node.key = &key; 384 key.name = nm; 385 key.len = nm_len; 386 key.labs = labs; 387 key.dclass = qclass; 388 if(rbtree_find_less_equal(&neg->tree, &key, &res)) { 389 /* exact match */ 390 result = (struct val_neg_zone*)res; 391 } else { 392 /* smaller element (or no element) */ 393 int m; 394 result = (struct val_neg_zone*)res; 395 if(!result || result->dclass != qclass) 396 return NULL; 397 /* count number of labels matched */ 398 (void)dname_lab_cmp(result->name, result->labs, key.name, 399 key.labs, &m); 400 while(result) { /* go up until qname is subdomain of stub */ 401 if(result->labs <= m) 402 break; 403 result = result->parent; 404 } 405 } 406 return result; 407 } 408 409 /** 410 * Find closest existing parent data for the given name. 411 * @param zone: to look in. 412 * @param nm: name to look for 413 * @param nm_len: length of nm 414 * @param labs: labelcount of nm. 415 * @return the data or NULL if none found. 416 */ 417 static struct val_neg_data* neg_closest_data_parent( 418 struct val_neg_zone* zone, uint8_t* nm, size_t nm_len, int labs) 419 { 420 struct val_neg_data key; 421 struct val_neg_data* result; 422 rbnode_type* res = NULL; 423 key.node.key = &key; 424 key.name = nm; 425 key.len = nm_len; 426 key.labs = labs; 427 if(rbtree_find_less_equal(&zone->tree, &key, &res)) { 428 /* exact match */ 429 result = (struct val_neg_data*)res; 430 } else { 431 /* smaller element (or no element) */ 432 int m; 433 result = (struct val_neg_data*)res; 434 if(!result) 435 return NULL; 436 /* count number of labels matched */ 437 (void)dname_lab_cmp(result->name, result->labs, key.name, 438 key.labs, &m); 439 while(result) { /* go up until qname is subdomain of stub */ 440 if(result->labs <= m) 441 break; 442 result = result->parent; 443 } 444 } 445 return result; 446 } 447 448 /** 449 * Create a single zone node 450 * @param nm: name for zone (copied) 451 * @param nm_len: length of name 452 * @param labs: labels in name. 453 * @param dclass: class of zone, host order. 454 * @return new zone or NULL on failure 455 */ 456 static struct val_neg_zone* neg_setup_zone_node( 457 uint8_t* nm, size_t nm_len, int labs, uint16_t dclass) 458 { 459 struct val_neg_zone* zone = 460 (struct val_neg_zone*)calloc(1, sizeof(*zone)); 461 if(!zone) { 462 return NULL; 463 } 464 zone->node.key = zone; 465 zone->name = memdup(nm, nm_len); 466 if(!zone->name) { 467 free(zone); 468 return NULL; 469 } 470 zone->len = nm_len; 471 zone->labs = labs; 472 zone->dclass = dclass; 473 474 rbtree_init(&zone->tree, &val_neg_data_compare); 475 return zone; 476 } 477 478 /** 479 * Create a linked list of parent zones, starting at longname ending on 480 * the parent (can be NULL, creates to the root). 481 * @param nm: name for lowest in chain 482 * @param nm_len: length of name 483 * @param labs: labels in name. 484 * @param dclass: class of zone. 485 * @param parent: NULL for to root, else so it fits under here. 486 * @return zone; a chain of zones and their parents up to the parent. 487 * or NULL on malloc failure 488 */ 489 static struct val_neg_zone* neg_zone_chain( 490 uint8_t* nm, size_t nm_len, int labs, uint16_t dclass, 491 struct val_neg_zone* parent) 492 { 493 int i; 494 int tolabs = parent?parent->labs:0; 495 struct val_neg_zone* zone, *prev = NULL, *first = NULL; 496 497 /* create the new subtree, i is labelcount of current creation */ 498 /* this creates a 'first' to z->parent=NULL list of zones */ 499 for(i=labs; i!=tolabs; i--) { 500 /* create new item */ 501 zone = neg_setup_zone_node(nm, nm_len, i, dclass); 502 if(!zone) { 503 /* need to delete other allocations in this routine!*/ 504 struct val_neg_zone* p=first, *np; 505 while(p) { 506 np = p->parent; 507 free(p->name); 508 free(p); 509 p = np; 510 } 511 return NULL; 512 } 513 if(i == labs) { 514 first = zone; 515 } else { 516 prev->parent = zone; 517 } 518 /* prepare for next name */ 519 prev = zone; 520 dname_remove_label(&nm, &nm_len); 521 } 522 return first; 523 } 524 525 void val_neg_zone_take_inuse(struct val_neg_zone* zone) 526 { 527 if(!zone->in_use) { 528 struct val_neg_zone* p; 529 zone->in_use = 1; 530 /* increase usage count of all parents */ 531 for(p=zone; p; p = p->parent) { 532 p->count++; 533 } 534 } 535 } 536 537 struct val_neg_zone* neg_create_zone(struct val_neg_cache* neg, 538 uint8_t* nm, size_t nm_len, uint16_t dclass) 539 { 540 struct val_neg_zone* zone; 541 struct val_neg_zone* parent; 542 struct val_neg_zone* p, *np; 543 int labs = dname_count_labels(nm); 544 545 /* find closest enclosing parent zone that (still) exists */ 546 parent = neg_closest_zone_parent(neg, nm, nm_len, labs, dclass); 547 if(parent && query_dname_compare(parent->name, nm) == 0) 548 return parent; /* already exists, weird */ 549 /* if parent exists, it is in use */ 550 log_assert(!parent || parent->count > 0); 551 zone = neg_zone_chain(nm, nm_len, labs, dclass, parent); 552 if(!zone) { 553 return NULL; 554 } 555 556 /* insert the list of zones into the tree */ 557 p = zone; 558 while(p) { 559 np = p->parent; 560 /* mem use */ 561 neg->use += sizeof(struct val_neg_zone) + p->len; 562 /* insert in tree */ 563 (void)rbtree_insert(&neg->tree, &p->node); 564 /* last one needs proper parent pointer */ 565 if(np == NULL) 566 p->parent = parent; 567 p = np; 568 } 569 return zone; 570 } 571 572 /** find zone name of message, returns the SOA record */ 573 static struct ub_packed_rrset_key* reply_find_soa(struct reply_info* rep) 574 { 575 size_t i; 576 for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){ 577 if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_SOA) 578 return rep->rrsets[i]; 579 } 580 return NULL; 581 } 582 583 /** see if the reply has NSEC records worthy of caching */ 584 static int reply_has_nsec(struct reply_info* rep) 585 { 586 size_t i; 587 struct packed_rrset_data* d; 588 if(rep->security != sec_status_secure) 589 return 0; 590 for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){ 591 if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC) { 592 d = (struct packed_rrset_data*)rep->rrsets[i]-> 593 entry.data; 594 if(d->security == sec_status_secure) 595 return 1; 596 } 597 } 598 return 0; 599 } 600 601 602 /** 603 * Create single node of data element. 604 * @param nm: name (copied) 605 * @param nm_len: length of name 606 * @param labs: labels in name. 607 * @return element with name nm, or NULL malloc failure. 608 */ 609 static struct val_neg_data* neg_setup_data_node( 610 uint8_t* nm, size_t nm_len, int labs) 611 { 612 struct val_neg_data* el; 613 el = (struct val_neg_data*)calloc(1, sizeof(*el)); 614 if(!el) { 615 return NULL; 616 } 617 el->node.key = el; 618 el->name = memdup(nm, nm_len); 619 if(!el->name) { 620 free(el); 621 return NULL; 622 } 623 el->len = nm_len; 624 el->labs = labs; 625 return el; 626 } 627 628 /** 629 * Create chain of data element and parents 630 * @param nm: name 631 * @param nm_len: length of name 632 * @param labs: labels in name. 633 * @param parent: up to where to make, if NULL up to root label. 634 * @return lowest element with name nm, or NULL malloc failure. 635 */ 636 static struct val_neg_data* neg_data_chain( 637 uint8_t* nm, size_t nm_len, int labs, struct val_neg_data* parent) 638 { 639 int i; 640 int tolabs = parent?parent->labs:0; 641 struct val_neg_data* el, *first = NULL, *prev = NULL; 642 643 /* create the new subtree, i is labelcount of current creation */ 644 /* this creates a 'first' to z->parent=NULL list of zones */ 645 for(i=labs; i!=tolabs; i--) { 646 /* create new item */ 647 el = neg_setup_data_node(nm, nm_len, i); 648 if(!el) { 649 /* need to delete other allocations in this routine!*/ 650 struct val_neg_data* p = first, *np; 651 while(p) { 652 np = p->parent; 653 free(p->name); 654 free(p); 655 p = np; 656 } 657 return NULL; 658 } 659 if(i == labs) { 660 first = el; 661 } else { 662 prev->parent = el; 663 } 664 665 /* prepare for next name */ 666 prev = el; 667 dname_remove_label(&nm, &nm_len); 668 } 669 return first; 670 } 671 672 /** 673 * Remove NSEC records between start and end points. 674 * By walking the tree, the tree is sorted canonically. 675 * @param neg: negative cache. 676 * @param zone: the zone 677 * @param el: element to start walking at. 678 * @param nsec: the nsec record with the end point 679 */ 680 static void wipeout(struct val_neg_cache* neg, struct val_neg_zone* zone, 681 struct val_neg_data* el, struct ub_packed_rrset_key* nsec) 682 { 683 struct packed_rrset_data* d = (struct packed_rrset_data*)nsec-> 684 entry.data; 685 uint8_t* end; 686 size_t end_len; 687 int end_labs, m; 688 rbnode_type* walk, *next; 689 struct val_neg_data* cur; 690 uint8_t buf[257]; 691 /* get endpoint */ 692 if(!d || d->count == 0 || d->rr_len[0] < 2+1) 693 return; 694 if(ntohs(nsec->rk.type) == LDNS_RR_TYPE_NSEC) { 695 end = d->rr_data[0]+2; 696 end_len = dname_valid(end, d->rr_len[0]-2); 697 end_labs = dname_count_labels(end); 698 } else { 699 /* NSEC3 */ 700 if(!nsec3_get_nextowner_b32(nsec, 0, buf, sizeof(buf))) 701 return; 702 end = buf; 703 end_labs = dname_count_size_labels(end, &end_len); 704 } 705 706 /* sanity check, both owner and end must be below the zone apex */ 707 if(!dname_subdomain_c(el->name, zone->name) || 708 !dname_subdomain_c(end, zone->name)) 709 return; 710 711 /* detect end of zone NSEC ; wipe until the end of zone */ 712 if(query_dname_compare(end, zone->name) == 0) { 713 end = NULL; 714 } 715 716 walk = rbtree_next(&el->node); 717 while(walk && walk != RBTREE_NULL) { 718 cur = (struct val_neg_data*)walk; 719 /* sanity check: must be larger than start */ 720 if(dname_canon_lab_cmp(cur->name, cur->labs, 721 el->name, el->labs, &m) <= 0) { 722 /* r == 0 skip original record. */ 723 /* r < 0 too small! */ 724 walk = rbtree_next(walk); 725 continue; 726 } 727 /* stop at endpoint, also data at empty nonterminals must be 728 * removed (no NSECs there) so everything between 729 * start and end */ 730 if(end && dname_canon_lab_cmp(cur->name, cur->labs, 731 end, end_labs, &m) >= 0) { 732 break; 733 } 734 /* this element has to be deleted, but we cannot do it 735 * now, because we are walking the tree still ... */ 736 /* get the next element: */ 737 next = rbtree_next(walk); 738 /* now delete the original element, this may trigger 739 * rbtree rebalances, but really, the next element is 740 * the one we need. 741 * But it may trigger delete of other data and the 742 * entire zone. However, if that happens, this is done 743 * by deleting the *parents* of the element for deletion, 744 * and maybe also the entire zone if it is empty. 745 * But parents are smaller in canonical compare, thus, 746 * if a larger element exists, then it is not a parent, 747 * it cannot get deleted, the zone cannot get empty. 748 * If the next==NULL, then zone can be empty. */ 749 if(cur->in_use) 750 neg_delete_data(neg, cur); 751 walk = next; 752 } 753 } 754 755 void neg_insert_data(struct val_neg_cache* neg, 756 struct val_neg_zone* zone, struct ub_packed_rrset_key* nsec) 757 { 758 struct packed_rrset_data* d; 759 struct val_neg_data* parent; 760 struct val_neg_data* el; 761 uint8_t* nm = nsec->rk.dname; 762 size_t nm_len = nsec->rk.dname_len; 763 int labs = dname_count_labels(nsec->rk.dname); 764 765 d = (struct packed_rrset_data*)nsec->entry.data; 766 if( !(d->security == sec_status_secure || 767 (d->security == sec_status_unchecked && d->rrsig_count > 0))) 768 return; 769 log_nametypeclass(VERB_ALGO, "negcache rr", 770 nsec->rk.dname, ntohs(nsec->rk.type), 771 ntohs(nsec->rk.rrset_class)); 772 773 /* find closest enclosing parent data that (still) exists */ 774 parent = neg_closest_data_parent(zone, nm, nm_len, labs); 775 if(parent && query_dname_compare(parent->name, nm) == 0) { 776 /* perfect match already exists */ 777 log_assert(parent->count > 0); 778 el = parent; 779 } else { 780 struct val_neg_data* p, *np; 781 782 /* create subtree for perfect match */ 783 /* if parent exists, it is in use */ 784 log_assert(!parent || parent->count > 0); 785 786 el = neg_data_chain(nm, nm_len, labs, parent); 787 if(!el) { 788 log_err("out of memory inserting NSEC negative cache"); 789 return; 790 } 791 el->in_use = 0; /* set on below */ 792 793 /* insert the list of zones into the tree */ 794 p = el; 795 while(p) { 796 np = p->parent; 797 /* mem use */ 798 neg->use += sizeof(struct val_neg_data) + p->len; 799 /* insert in tree */ 800 p->zone = zone; 801 (void)rbtree_insert(&zone->tree, &p->node); 802 /* last one needs proper parent pointer */ 803 if(np == NULL) 804 p->parent = parent; 805 p = np; 806 } 807 } 808 809 if(!el->in_use) { 810 struct val_neg_data* p; 811 812 el->in_use = 1; 813 /* increase usage count of all parents */ 814 for(p=el; p; p = p->parent) { 815 p->count++; 816 } 817 818 neg_lru_front(neg, el); 819 } else { 820 /* in use, bring to front, lru */ 821 neg_lru_touch(neg, el); 822 } 823 824 /* if nsec3 store last used parameters */ 825 if(ntohs(nsec->rk.type) == LDNS_RR_TYPE_NSEC3) { 826 int h; 827 uint8_t* s; 828 size_t slen, it; 829 if(nsec3_get_params(nsec, 0, &h, &it, &s, &slen) && 830 it <= neg->nsec3_max_iter && 831 (h != zone->nsec3_hash || it != zone->nsec3_iter || 832 slen != zone->nsec3_saltlen || 833 (slen != 0 && zone->nsec3_salt && s 834 && memcmp(zone->nsec3_salt, s, slen) != 0))) { 835 836 if(slen > MAX_SALT_LENGTH) { 837 /* RFC 9276 s3.1: operators SHOULD NOT use a salt; large 838 * salts inflate per-hash block count. Decline to cache. */ 839 return; 840 } else if(slen > 0) { 841 uint8_t* sa = memdup(s, slen); 842 if(sa) { 843 free(zone->nsec3_salt); 844 zone->nsec3_salt = sa; 845 zone->nsec3_saltlen = slen; 846 zone->nsec3_iter = it; 847 zone->nsec3_hash = h; 848 } 849 } else { 850 free(zone->nsec3_salt); 851 zone->nsec3_salt = NULL; 852 zone->nsec3_saltlen = 0; 853 zone->nsec3_iter = it; 854 zone->nsec3_hash = h; 855 } 856 } 857 } 858 859 /* wipe out the cache items between NSEC start and end */ 860 wipeout(neg, zone, el, nsec); 861 } 862 863 /** see if the reply has signed NSEC records and return the signer */ 864 static uint8_t* reply_nsec_signer(struct reply_info* rep, size_t* signer_len, 865 uint16_t* dclass) 866 { 867 size_t i; 868 struct packed_rrset_data* d; 869 uint8_t* s; 870 for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){ 871 if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC || 872 ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC3) { 873 d = (struct packed_rrset_data*)rep->rrsets[i]-> 874 entry.data; 875 /* return first signer name of first NSEC */ 876 if(d->rrsig_count != 0) { 877 val_find_rrset_signer(rep->rrsets[i], 878 &s, signer_len); 879 if(s && *signer_len) { 880 *dclass = ntohs(rep->rrsets[i]-> 881 rk.rrset_class); 882 return s; 883 } 884 } 885 } 886 } 887 return 0; 888 } 889 890 void val_neg_addreply(struct val_neg_cache* neg, struct reply_info* rep) 891 { 892 size_t i, need; 893 struct ub_packed_rrset_key* soa; 894 uint8_t* dname = NULL; 895 size_t dname_len; 896 uint16_t rrset_class; 897 struct val_neg_zone* zone; 898 /* see if secure nsecs inside */ 899 if(!reply_has_nsec(rep)) 900 return; 901 /* find the zone name in message */ 902 if((soa = reply_find_soa(rep))) { 903 dname = soa->rk.dname; 904 dname_len = soa->rk.dname_len; 905 rrset_class = ntohs(soa->rk.rrset_class); 906 } 907 else { 908 /* No SOA in positive (wildcard) answer. Use signer from the 909 * validated answer RRsets' signature. */ 910 if(!(dname = reply_nsec_signer(rep, &dname_len, &rrset_class))) 911 return; 912 } 913 914 log_nametypeclass(VERB_ALGO, "negcache insert for zone", 915 dname, LDNS_RR_TYPE_SOA, rrset_class); 916 917 /* ask for enough space to store all of it */ 918 need = calc_data_need(rep) + 919 calc_zone_need(dname, dname_len); 920 lock_basic_lock(&neg->lock); 921 neg_make_space(neg, need); 922 923 /* find or create the zone entry */ 924 zone = neg_find_zone(neg, dname, dname_len, rrset_class); 925 if(!zone) { 926 if(!(zone = neg_create_zone(neg, dname, dname_len, 927 rrset_class))) { 928 lock_basic_unlock(&neg->lock); 929 log_err("out of memory adding negative zone"); 930 return; 931 } 932 } 933 val_neg_zone_take_inuse(zone); 934 935 /* insert the NSECs */ 936 for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){ 937 if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC) 938 continue; 939 if(!dname_subdomain_c(rep->rrsets[i]->rk.dname, 940 zone->name)) continue; 941 if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC && 942 !nsec_nextowner_subdomain(rep->rrsets[i], zone->name)) { 943 continue; /* nextowner not in zone */ 944 } 945 /* insert NSEC into this zone's tree */ 946 neg_insert_data(neg, zone, rep->rrsets[i]); 947 } 948 if(zone->tree.count == 0) { 949 /* remove empty zone if inserts failed */ 950 neg_delete_zone(neg, zone); 951 } 952 lock_basic_unlock(&neg->lock); 953 } 954 955 /** 956 * Lookup closest data record. For NSEC denial. 957 * @param zone: zone to look in 958 * @param qname: name to look for. 959 * @param len: length of name 960 * @param labs: labels in name 961 * @param data: data element, exact or smaller or NULL 962 * @return true if exact match. 963 */ 964 static int neg_closest_data(struct val_neg_zone* zone, 965 uint8_t* qname, size_t len, int labs, struct val_neg_data** data) 966 { 967 struct val_neg_data key; 968 rbnode_type* r; 969 key.node.key = &key; 970 key.name = qname; 971 key.len = len; 972 key.labs = labs; 973 if(rbtree_find_less_equal(&zone->tree, &key, &r)) { 974 /* exact match */ 975 *data = (struct val_neg_data*)r; 976 return 1; 977 } else { 978 /* smaller match */ 979 *data = (struct val_neg_data*)r; 980 return 0; 981 } 982 } 983 984 void val_neg_addreferral(struct val_neg_cache* neg, struct reply_info* rep, 985 uint8_t* zone_name) 986 { 987 size_t i, need; 988 uint8_t* signer; 989 size_t signer_len; 990 uint16_t dclass; 991 struct val_neg_zone* zone; 992 /* no SOA in this message, find RRSIG over NSEC's signer name. 993 * note the NSEC records are maybe not validated yet */ 994 signer = reply_nsec_signer(rep, &signer_len, &dclass); 995 if(!signer) 996 return; 997 if(!dname_subdomain_c(signer, zone_name)) { 998 /* the signer is not in the bailiwick, throw it out */ 999 return; 1000 } 1001 1002 log_nametypeclass(VERB_ALGO, "negcache insert referral ", 1003 signer, LDNS_RR_TYPE_NS, dclass); 1004 1005 /* ask for enough space to store all of it */ 1006 need = calc_data_need(rep) + calc_zone_need(signer, signer_len); 1007 lock_basic_lock(&neg->lock); 1008 neg_make_space(neg, need); 1009 1010 /* find or create the zone entry */ 1011 zone = neg_find_zone(neg, signer, signer_len, dclass); 1012 if(!zone) { 1013 if(!(zone = neg_create_zone(neg, signer, signer_len, 1014 dclass))) { 1015 lock_basic_unlock(&neg->lock); 1016 log_err("out of memory adding negative zone"); 1017 return; 1018 } 1019 } 1020 val_neg_zone_take_inuse(zone); 1021 1022 /* insert the NSECs */ 1023 for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){ 1024 if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC && 1025 ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC3) 1026 continue; 1027 if(!dname_subdomain_c(rep->rrsets[i]->rk.dname, 1028 zone->name)) continue; 1029 if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC && 1030 !nsec_nextowner_subdomain(rep->rrsets[i], zone->name)) { 1031 continue; /* nextowner not in zone */ 1032 } 1033 /* insert NSEC into this zone's tree */ 1034 neg_insert_data(neg, zone, rep->rrsets[i]); 1035 } 1036 if(zone->tree.count == 0) { 1037 /* remove empty zone if inserts failed */ 1038 neg_delete_zone(neg, zone); 1039 } 1040 lock_basic_unlock(&neg->lock); 1041 } 1042 1043 /** 1044 * Check that an NSEC3 rrset does not have a type set. 1045 * None of the nsec3s in a hash-collision are allowed to have the type. 1046 * (since we do not know which one is the nsec3 looked at, flags, ..., we 1047 * ignore the cached item and let it bypass negative caching). 1048 * @param k: the nsec3 rrset to check. 1049 * @param t: type to check 1050 * @return true if no RRs have the type. 1051 */ 1052 static int nsec3_no_type(struct ub_packed_rrset_key* k, uint16_t t) 1053 { 1054 int count = (int)((struct packed_rrset_data*)k->entry.data)->count; 1055 int i; 1056 for(i=0; i<count; i++) 1057 if(nsec3_has_type(k, i, t)) 1058 return 0; 1059 return 1; 1060 } 1061 1062 /** 1063 * See if rrset exists in rrset cache. 1064 * If it does, the bit is checked, and if not expired, it is returned 1065 * allocated in region. 1066 * @param rrset_cache: rrset cache 1067 * @param qname: to lookup rrset name 1068 * @param qname_len: length of qname. 1069 * @param qtype: type of rrset to lookup, host order 1070 * @param qclass: class of rrset to lookup, host order 1071 * @param flags: flags for rrset to lookup 1072 * @param region: where to alloc result 1073 * @param checkbit: if true, a bit in the nsec typemap is checked for absence. 1074 * @param checktype: which bit to check 1075 * @param now: to check ttl against 1076 * @return rrset or NULL 1077 */ 1078 static struct ub_packed_rrset_key* 1079 grab_nsec(struct rrset_cache* rrset_cache, uint8_t* qname, size_t qname_len, 1080 uint16_t qtype, uint16_t qclass, uint32_t flags, 1081 struct regional* region, int checkbit, uint16_t checktype, 1082 time_t now) 1083 { 1084 struct ub_packed_rrset_key* r, *k = rrset_cache_lookup(rrset_cache, 1085 qname, qname_len, qtype, qclass, flags, now, 0); 1086 struct packed_rrset_data* d; 1087 if(!k) return NULL; 1088 d = k->entry.data; 1089 /* only secure or unchecked records that have signatures. */ 1090 if( ! ( d->security == sec_status_secure || 1091 (d->security == sec_status_unchecked && 1092 d->rrsig_count > 0) ) ) { 1093 lock_rw_unlock(&k->entry.lock); 1094 return NULL; 1095 } 1096 /* check if checktype is absent */ 1097 if(checkbit && ( 1098 (qtype == LDNS_RR_TYPE_NSEC && nsec_has_type(k, checktype)) || 1099 (qtype == LDNS_RR_TYPE_NSEC3 && !nsec3_no_type(k, checktype)) 1100 )) { 1101 lock_rw_unlock(&k->entry.lock); 1102 return NULL; 1103 } 1104 /* looks OK! copy to region and return it */ 1105 r = packed_rrset_copy_region(k, region, now); 1106 /* if it failed, we return the NULL */ 1107 lock_rw_unlock(&k->entry.lock); 1108 return r; 1109 } 1110 1111 /** 1112 * Get best NSEC record for qname. Might be matching, covering or totally 1113 * useless. 1114 * @param neg_cache: neg cache 1115 * @param qname: to lookup rrset name 1116 * @param qname_len: length of qname. 1117 * @param qclass: class of rrset to lookup, host order 1118 * @param rrset_cache: rrset cache 1119 * @param now: to check ttl against 1120 * @param region: where to alloc result 1121 * @param topname: do not look higher than this name, so that the 1122 * result cannot be taken from a zone above the current trust anchor. 1123 * @return rrset or NULL 1124 */ 1125 static struct ub_packed_rrset_key* 1126 neg_find_nsec(struct val_neg_cache* neg_cache, uint8_t* qname, size_t qname_len, 1127 uint16_t qclass, struct rrset_cache* rrset_cache, time_t now, 1128 struct regional* region, uint8_t* topname) 1129 { 1130 int labs; 1131 uint32_t flags; 1132 struct val_neg_zone* zone; 1133 struct val_neg_data* data; 1134 struct ub_packed_rrset_key* nsec; 1135 1136 labs = dname_count_labels(qname); 1137 lock_basic_lock(&neg_cache->lock); 1138 zone = neg_closest_zone_parent(neg_cache, qname, qname_len, labs, 1139 qclass); 1140 while(zone && !zone->in_use) 1141 zone = zone->parent; 1142 if(!zone) { 1143 lock_basic_unlock(&neg_cache->lock); 1144 return NULL; 1145 } 1146 if(topname && !dname_subdomain_c(zone->name, topname)) { 1147 /* Reject NSEC not within trust anchor's bailiwick */ 1148 lock_basic_unlock(&neg_cache->lock); 1149 return NULL; 1150 } 1151 1152 /* NSEC only for now */ 1153 if(zone->nsec3_hash) { 1154 lock_basic_unlock(&neg_cache->lock); 1155 return NULL; 1156 } 1157 1158 /* ignore return value, don't care if it is an exact or smaller match */ 1159 (void)neg_closest_data(zone, qname, qname_len, labs, &data); 1160 if(!data) { 1161 lock_basic_unlock(&neg_cache->lock); 1162 return NULL; 1163 } 1164 1165 /* ENT nodes are not in use, try the previous node. If the previous node 1166 * is not in use, we don't have an useful NSEC and give up. */ 1167 if(!data->in_use) { 1168 data = (struct val_neg_data*)rbtree_previous((rbnode_type*)data); 1169 if((rbnode_type*)data == RBTREE_NULL || !data->in_use) { 1170 lock_basic_unlock(&neg_cache->lock); 1171 return NULL; 1172 } 1173 } 1174 1175 flags = 0; 1176 if(query_dname_compare(data->name, zone->name) == 0) 1177 flags = PACKED_RRSET_NSEC_AT_APEX; 1178 1179 nsec = grab_nsec(rrset_cache, data->name, data->len, LDNS_RR_TYPE_NSEC, 1180 zone->dclass, flags, region, 0, 0, now); 1181 lock_basic_unlock(&neg_cache->lock); 1182 return nsec; 1183 } 1184 1185 /** find nsec3 closest encloser in neg cache */ 1186 static struct val_neg_data* 1187 neg_find_nsec3_ce(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len, 1188 int qlabs, sldns_buffer* buf, uint8_t* hashnc, size_t* nclen) 1189 { 1190 struct val_neg_data* data; 1191 uint8_t hashce[NSEC3_SHA_LEN]; 1192 uint8_t b32[257]; 1193 size_t celen, b32len; 1194 int hashmax = MAX_NSEC3_CALCULATIONS; 1195 if(qlabs > hashmax) { 1196 /* strip leading labels so the walk costs at most 1197 * MAX_NSEC3_CALCULATIONS hashes, mirroring val_nsec3.c */ 1198 while(qlabs > hashmax) { 1199 dname_remove_label(&qname, &qname_len); 1200 qlabs--; 1201 } 1202 } 1203 1204 *nclen = 0; 1205 while(qlabs > 0) { 1206 /* hash */ 1207 if(!(celen=nsec3_get_hashed(buf, qname, qname_len, 1208 zone->nsec3_hash, zone->nsec3_iter, zone->nsec3_salt, 1209 zone->nsec3_saltlen, hashce, sizeof(hashce)))) 1210 return NULL; 1211 if(!(b32len=nsec3_hash_to_b32(hashce, celen, zone->name, 1212 zone->len, b32, sizeof(b32)))) 1213 return NULL; 1214 1215 /* lookup (exact match only) */ 1216 data = neg_find_data(zone, b32, b32len, zone->labs+1); 1217 if(data && data->in_use) { 1218 /* found ce match! */ 1219 return data; 1220 } 1221 1222 *nclen = celen; 1223 memmove(hashnc, hashce, celen); 1224 dname_remove_label(&qname, &qname_len); 1225 qlabs --; 1226 } 1227 return NULL; 1228 } 1229 1230 /** check nsec3 parameters on nsec3 rrset with current zone values */ 1231 static int 1232 neg_params_ok(struct val_neg_zone* zone, struct ub_packed_rrset_key* rrset) 1233 { 1234 int h; 1235 uint8_t* s; 1236 size_t slen, it; 1237 if(!nsec3_get_params(rrset, 0, &h, &it, &s, &slen)) 1238 return 0; 1239 return (h == zone->nsec3_hash && it == zone->nsec3_iter && 1240 slen == zone->nsec3_saltlen && 1241 (slen == 0 || (slen != 0 && zone->nsec3_salt && s 1242 && memcmp(zone->nsec3_salt, s, slen) == 0))); 1243 } 1244 1245 /** get next closer for nsec3 proof */ 1246 static struct ub_packed_rrset_key* 1247 neg_nsec3_getnc(struct val_neg_zone* zone, uint8_t* hashnc, size_t nclen, 1248 struct rrset_cache* rrset_cache, struct regional* region, 1249 time_t now, uint8_t* b32, size_t maxb32) 1250 { 1251 struct ub_packed_rrset_key* nc_rrset; 1252 struct val_neg_data* data; 1253 size_t b32len; 1254 1255 if(!(b32len=nsec3_hash_to_b32(hashnc, nclen, zone->name, 1256 zone->len, b32, maxb32))) 1257 return NULL; 1258 (void)neg_closest_data(zone, b32, b32len, zone->labs+1, &data); 1259 if(!data && zone->tree.count != 0) { 1260 /* could be before the first entry ; return the last 1261 * entry (possibly the rollover nsec3 at end) */ 1262 data = (struct val_neg_data*)rbtree_last(&zone->tree); 1263 } 1264 while(data && !data->in_use) 1265 data = data->parent; 1266 if(!data) 1267 return NULL; 1268 /* got a data element in tree, grab it */ 1269 nc_rrset = grab_nsec(rrset_cache, data->name, data->len, 1270 LDNS_RR_TYPE_NSEC3, zone->dclass, 0, region, 0, 0, now); 1271 if(!nc_rrset) 1272 return NULL; 1273 if(!neg_params_ok(zone, nc_rrset)) 1274 return NULL; 1275 return nc_rrset; 1276 } 1277 1278 /** neg cache nsec3 proof procedure*/ 1279 static struct dns_msg* 1280 neg_nsec3_proof_ds(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len, 1281 int qlabs, sldns_buffer* buf, struct rrset_cache* rrset_cache, 1282 struct regional* region, time_t now, uint8_t* topname) 1283 { 1284 struct dns_msg* msg; 1285 struct val_neg_data* data; 1286 uint8_t hashnc[NSEC3_SHA_LEN]; 1287 size_t nclen; 1288 struct ub_packed_rrset_key* ce_rrset, *nc_rrset; 1289 struct nsec3_cached_hash c; 1290 uint8_t nc_b32[257]; 1291 1292 /* for NSEC3 ; determine the closest encloser for which we 1293 * can find an exact match. Remember the hashed lower name, 1294 * since that is the one we need a closest match for. 1295 * If we find a match straight away, then it becomes NODATA. 1296 * Otherwise, NXDOMAIN or if OPTOUT, an insecure delegation. 1297 * Also check that parameters are the same on closest encloser 1298 * and on closest match. 1299 */ 1300 if(!zone->nsec3_hash) 1301 return NULL; /* not nsec3 zone */ 1302 1303 if(!topname && qlabs > zone->labs + 1) 1304 return NULL; /* iterator caller; opt-out proof would be discarded 1305 * at the !topname check below anyway. 1306 * The qlabs check allows the exact-match for 1307 * the one-label-below-zone case. */ 1308 1309 if(!(data=neg_find_nsec3_ce(zone, qname, qname_len, qlabs, buf, 1310 hashnc, &nclen))) { 1311 return NULL; 1312 } 1313 1314 /* grab the ce rrset */ 1315 ce_rrset = grab_nsec(rrset_cache, data->name, data->len, 1316 LDNS_RR_TYPE_NSEC3, zone->dclass, 0, region, 1, 1317 LDNS_RR_TYPE_DS, now); 1318 if(!ce_rrset) 1319 return NULL; 1320 if(!neg_params_ok(zone, ce_rrset)) 1321 return NULL; 1322 1323 if(nclen == 0) { 1324 /* exact match, just check the type bits */ 1325 /* need: -SOA, -DS, +NS */ 1326 if(nsec3_has_type(ce_rrset, 0, LDNS_RR_TYPE_SOA) || 1327 nsec3_has_type(ce_rrset, 0, LDNS_RR_TYPE_DS) || 1328 !nsec3_has_type(ce_rrset, 0, LDNS_RR_TYPE_NS)) 1329 return NULL; 1330 if(!(msg = dns_msg_create(qname, qname_len, 1331 LDNS_RR_TYPE_DS, zone->dclass, region, 2))) /* ce + soa */ 1332 return NULL; 1333 /* The cache response means recursion is available. */ 1334 msg->rep->flags |= BIT_RA; 1335 /* TTL reduced in grab_nsec */ 1336 if(!dns_msg_authadd(msg, region, ce_rrset, 0)) 1337 return NULL; 1338 return msg; 1339 } 1340 1341 /* optout is not allowed without knowing the trust-anchor in use, 1342 * otherwise the optout could spoof away that anchor */ 1343 if(!topname) 1344 return NULL; 1345 1346 /* if there is no exact match, it must be in an optout span 1347 * (an existing DS implies an NSEC3 must exist) */ 1348 nc_rrset = neg_nsec3_getnc(zone, hashnc, nclen, rrset_cache, 1349 region, now, nc_b32, sizeof(nc_b32)); 1350 if(!nc_rrset) 1351 return NULL; 1352 if(!neg_params_ok(zone, nc_rrset)) 1353 return NULL; 1354 if(!nsec3_has_optout(nc_rrset, 0)) 1355 return NULL; 1356 c.hash = hashnc; 1357 c.hash_len = nclen; 1358 c.b32 = nc_b32+1; 1359 c.b32_len = (size_t)nc_b32[0]; 1360 if(nsec3_covers(zone->name, &c, nc_rrset, 0, buf)) { 1361 /* nc_rrset covers the next closer name. 1362 * ce_rrset equals a closer encloser. 1363 * nc_rrset is optout. 1364 * No need to check wildcard for type DS */ 1365 /* capacity=3: ce + nc + soa(if needed) */ 1366 if(!(msg = dns_msg_create(qname, qname_len, 1367 LDNS_RR_TYPE_DS, zone->dclass, region, 3))) 1368 return NULL; 1369 /* The cache response means recursion is available. */ 1370 msg->rep->flags |= BIT_RA; 1371 /* now=0 because TTL was reduced in grab_nsec */ 1372 if(!dns_msg_authadd(msg, region, ce_rrset, 0)) 1373 return NULL; 1374 if(!dns_msg_authadd(msg, region, nc_rrset, 0)) 1375 return NULL; 1376 return msg; 1377 } 1378 return NULL; 1379 } 1380 1381 /** 1382 * Add SOA record for external responses. 1383 * @param rrset_cache: to look into. 1384 * @param now: current time. 1385 * @param region: where to perform the allocation 1386 * @param msg: current msg with NSEC. 1387 * @param zone: val_neg_zone if we have one. 1388 * @return false on lookup or alloc failure. 1389 */ 1390 static int add_soa(struct rrset_cache* rrset_cache, time_t now, 1391 struct regional* region, struct dns_msg* msg, struct val_neg_zone* zone) 1392 { 1393 struct ub_packed_rrset_key* soa; 1394 uint8_t* nm; 1395 size_t nmlen; 1396 uint16_t dclass; 1397 if(zone) { 1398 nm = zone->name; 1399 nmlen = zone->len; 1400 dclass = zone->dclass; 1401 } else { 1402 /* Assumes the signer is the zone SOA to add */ 1403 nm = reply_nsec_signer(msg->rep, &nmlen, &dclass); 1404 if(!nm) 1405 return 0; 1406 } 1407 soa = rrset_cache_lookup(rrset_cache, nm, nmlen, LDNS_RR_TYPE_SOA, 1408 dclass, PACKED_RRSET_SOA_NEG, now, 0); 1409 if(!soa) 1410 return 0; 1411 if(!dns_msg_authadd(msg, region, soa, now)) { 1412 lock_rw_unlock(&soa->entry.lock); 1413 return 0; 1414 } 1415 lock_rw_unlock(&soa->entry.lock); 1416 return 1; 1417 } 1418 1419 struct dns_msg* 1420 val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo, 1421 struct regional* region, struct rrset_cache* rrset_cache, 1422 sldns_buffer* buf, time_t now, int addsoa, uint8_t* topname, 1423 struct config_file* cfg) 1424 { 1425 struct dns_msg* msg; 1426 struct ub_packed_rrset_key* nsec; /* qname matching/covering nsec */ 1427 struct ub_packed_rrset_key* wcrr; /* wildcard record or nsec */ 1428 uint8_t* nodata_wc = NULL; 1429 uint8_t* ce = NULL; 1430 size_t ce_len; 1431 uint8_t wc_ce[LDNS_MAX_DOMAINLEN+3]; 1432 struct query_info wc_qinfo; 1433 struct ub_packed_rrset_key* cache_wc; 1434 struct packed_rrset_data* wcrr_data; 1435 int rcode = LDNS_RCODE_NOERROR; 1436 uint8_t* zname; 1437 size_t zname_len; 1438 int zname_labs; 1439 struct val_neg_zone* zone; 1440 1441 /* only for DS queries when aggressive use of NSEC is disabled */ 1442 if(qinfo->qtype != LDNS_RR_TYPE_DS && !cfg->aggressive_nsec) 1443 return NULL; 1444 log_assert(!topname || dname_subdomain_c(qinfo->qname, topname)); 1445 1446 /* Get best available NSEC for qname */ 1447 nsec = neg_find_nsec(neg, qinfo->qname, qinfo->qname_len, qinfo->qclass, 1448 rrset_cache, now, region, topname); 1449 1450 /* Matching NSEC, use to generate No Data answer. Not creating answers 1451 * yet for No Data proven using wildcard. */ 1452 if(nsec && nsec_proves_nodata(nsec, qinfo, &nodata_wc) && !nodata_wc) { 1453 /* do not create nodata answers for qtype ANY, it is a query 1454 * type, not an rrtype to disprove. Nameerrors are useful for 1455 * qtype ANY, in the else branch. */ 1456 if(qinfo->qtype == LDNS_RR_TYPE_ANY) 1457 return NULL; 1458 if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len, 1459 qinfo->qtype, qinfo->qclass, region, 2))) 1460 return NULL; 1461 /* The cache response means recursion is available. */ 1462 msg->rep->flags |= BIT_RA; 1463 if(!dns_msg_authadd(msg, region, nsec, 0)) 1464 return NULL; 1465 if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL)) 1466 return NULL; 1467 1468 lock_basic_lock(&neg->lock); 1469 neg->num_neg_cache_noerror++; 1470 lock_basic_unlock(&neg->lock); 1471 return msg; 1472 } else if(nsec && val_nsec_proves_name_error(nsec, qinfo->qname)) { 1473 if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len, 1474 qinfo->qtype, qinfo->qclass, region, 3))) 1475 return NULL; 1476 /* The cache response means recursion is available. */ 1477 msg->rep->flags |= BIT_RA; 1478 if(!(ce = nsec_closest_encloser(qinfo->qname, nsec))) 1479 return NULL; 1480 dname_count_size_labels(ce, &ce_len); 1481 1482 /* No extra extra NSEC required if both nameerror qname and 1483 * nodata *.ce. are proven already. */ 1484 if(!nodata_wc || query_dname_compare(nodata_wc, ce) != 0) { 1485 /* Qname proven non existing, get wildcard record for 1486 * QTYPE or NSEC covering or matching wildcard. */ 1487 1488 /* Num labels in ce is always smaller than in qname, 1489 * therefore adding the wildcard label cannot overflow 1490 * buffer. */ 1491 wc_ce[0] = 1; 1492 wc_ce[1] = (uint8_t)'*'; 1493 memmove(wc_ce+2, ce, ce_len); 1494 wc_qinfo.qname = wc_ce; 1495 wc_qinfo.qname_len = ce_len + 2; 1496 wc_qinfo.qtype = qinfo->qtype; 1497 1498 1499 if((cache_wc = rrset_cache_lookup(rrset_cache, wc_qinfo.qname, 1500 wc_qinfo.qname_len, wc_qinfo.qtype, 1501 qinfo->qclass, 0/*flags*/, now, 0/*read only*/))) { 1502 /* Synthesize wildcard answer */ 1503 wcrr_data = (struct packed_rrset_data*)cache_wc->entry.data; 1504 if(!(wcrr_data->security == sec_status_secure || 1505 (wcrr_data->security == sec_status_unchecked && 1506 wcrr_data->rrsig_count > 0))) { 1507 lock_rw_unlock(&cache_wc->entry.lock); 1508 return NULL; 1509 } 1510 if(!(wcrr = packed_rrset_copy_region(cache_wc, 1511 region, now))) { 1512 lock_rw_unlock(&cache_wc->entry.lock); 1513 return NULL; 1514 }; 1515 lock_rw_unlock(&cache_wc->entry.lock); 1516 wcrr->rk.dname = qinfo->qname; 1517 wcrr->rk.dname_len = qinfo->qname_len; 1518 if(!dns_msg_ansadd(msg, region, wcrr, 0)) 1519 return NULL; 1520 /* No SOA needed for wildcard synthesised 1521 * answer. */ 1522 addsoa = 0; 1523 } else { 1524 /* Get wildcard NSEC for possible non existence 1525 * proof */ 1526 if(!(wcrr = neg_find_nsec(neg, wc_qinfo.qname, 1527 wc_qinfo.qname_len, qinfo->qclass, 1528 rrset_cache, now, region, topname))) 1529 return NULL; 1530 1531 nodata_wc = NULL; 1532 if(val_nsec_proves_name_error(wcrr, wc_ce)) 1533 rcode = LDNS_RCODE_NXDOMAIN; 1534 else if(!nsec_proves_nodata(wcrr, &wc_qinfo, 1535 &nodata_wc) || nodata_wc) 1536 /* &nodata_wc shouldn't be set, wc_qinfo 1537 * already contains wildcard domain. */ 1538 /* NSEC doesn't prove anything for 1539 * wildcard. */ 1540 return NULL; 1541 if(query_dname_compare(wcrr->rk.dname, 1542 nsec->rk.dname) != 0) 1543 if(!dns_msg_authadd(msg, region, wcrr, 0)) 1544 return NULL; 1545 } 1546 } 1547 1548 if(!dns_msg_authadd(msg, region, nsec, 0)) 1549 return NULL; 1550 if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL)) 1551 return NULL; 1552 1553 /* Increment statistic counters */ 1554 lock_basic_lock(&neg->lock); 1555 if(rcode == LDNS_RCODE_NOERROR) 1556 neg->num_neg_cache_noerror++; 1557 else if(rcode == LDNS_RCODE_NXDOMAIN) 1558 neg->num_neg_cache_nxdomain++; 1559 lock_basic_unlock(&neg->lock); 1560 1561 FLAGS_SET_RCODE(msg->rep->flags, rcode); 1562 return msg; 1563 } 1564 1565 /* No aggressive use of NSEC3 for now, only proceed for DS types. */ 1566 if(qinfo->qtype != LDNS_RR_TYPE_DS){ 1567 return NULL; 1568 } 1569 /* check NSEC3 neg cache for type DS */ 1570 /* need to look one zone higher for DS type */ 1571 zname = qinfo->qname; 1572 zname_len = qinfo->qname_len; 1573 dname_remove_label(&zname, &zname_len); 1574 zname_labs = dname_count_labels(zname); 1575 1576 /* lookup closest zone */ 1577 lock_basic_lock(&neg->lock); 1578 zone = neg_closest_zone_parent(neg, zname, zname_len, zname_labs, 1579 qinfo->qclass); 1580 while(zone && !zone->in_use) 1581 zone = zone->parent; 1582 /* check that the zone is not too high up so that we do not pick data 1583 * out of a zone that is above the last-seen key (or trust-anchor). */ 1584 if(zone && topname) { 1585 if(!dname_subdomain_c(zone->name, topname)) 1586 zone = NULL; 1587 } 1588 if(!zone) { 1589 lock_basic_unlock(&neg->lock); 1590 return NULL; 1591 } 1592 1593 msg = neg_nsec3_proof_ds(zone, qinfo->qname, qinfo->qname_len, 1594 zname_labs+1, buf, rrset_cache, region, now, topname); 1595 if(msg && addsoa && !add_soa(rrset_cache, now, region, msg, zone)) { 1596 lock_basic_unlock(&neg->lock); 1597 return NULL; 1598 } 1599 lock_basic_unlock(&neg->lock); 1600 return msg; 1601 } 1602 1603 void 1604 val_neg_adjust_size(struct val_neg_cache* neg, size_t max) 1605 { 1606 lock_basic_lock(&neg->lock); 1607 neg->max = max; 1608 neg_make_space(neg, 0); 1609 lock_basic_unlock(&neg->lock); 1610 } 1611