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 /* insert NSEC into this zone's tree */ 942 neg_insert_data(neg, zone, rep->rrsets[i]); 943 } 944 if(zone->tree.count == 0) { 945 /* remove empty zone if inserts failed */ 946 neg_delete_zone(neg, zone); 947 } 948 lock_basic_unlock(&neg->lock); 949 } 950 951 /** 952 * Lookup closest data record. For NSEC denial. 953 * @param zone: zone to look in 954 * @param qname: name to look for. 955 * @param len: length of name 956 * @param labs: labels in name 957 * @param data: data element, exact or smaller or NULL 958 * @return true if exact match. 959 */ 960 static int neg_closest_data(struct val_neg_zone* zone, 961 uint8_t* qname, size_t len, int labs, struct val_neg_data** data) 962 { 963 struct val_neg_data key; 964 rbnode_type* r; 965 key.node.key = &key; 966 key.name = qname; 967 key.len = len; 968 key.labs = labs; 969 if(rbtree_find_less_equal(&zone->tree, &key, &r)) { 970 /* exact match */ 971 *data = (struct val_neg_data*)r; 972 return 1; 973 } else { 974 /* smaller match */ 975 *data = (struct val_neg_data*)r; 976 return 0; 977 } 978 } 979 980 void val_neg_addreferral(struct val_neg_cache* neg, struct reply_info* rep, 981 uint8_t* zone_name) 982 { 983 size_t i, need; 984 uint8_t* signer; 985 size_t signer_len; 986 uint16_t dclass; 987 struct val_neg_zone* zone; 988 /* no SOA in this message, find RRSIG over NSEC's signer name. 989 * note the NSEC records are maybe not validated yet */ 990 signer = reply_nsec_signer(rep, &signer_len, &dclass); 991 if(!signer) 992 return; 993 if(!dname_subdomain_c(signer, zone_name)) { 994 /* the signer is not in the bailiwick, throw it out */ 995 return; 996 } 997 998 log_nametypeclass(VERB_ALGO, "negcache insert referral ", 999 signer, LDNS_RR_TYPE_NS, dclass); 1000 1001 /* ask for enough space to store all of it */ 1002 need = calc_data_need(rep) + calc_zone_need(signer, signer_len); 1003 lock_basic_lock(&neg->lock); 1004 neg_make_space(neg, need); 1005 1006 /* find or create the zone entry */ 1007 zone = neg_find_zone(neg, signer, signer_len, dclass); 1008 if(!zone) { 1009 if(!(zone = neg_create_zone(neg, signer, signer_len, 1010 dclass))) { 1011 lock_basic_unlock(&neg->lock); 1012 log_err("out of memory adding negative zone"); 1013 return; 1014 } 1015 } 1016 val_neg_zone_take_inuse(zone); 1017 1018 /* insert the NSECs */ 1019 for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){ 1020 if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC && 1021 ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC3) 1022 continue; 1023 if(!dname_subdomain_c(rep->rrsets[i]->rk.dname, 1024 zone->name)) continue; 1025 /* insert NSEC into this zone's tree */ 1026 neg_insert_data(neg, zone, rep->rrsets[i]); 1027 } 1028 if(zone->tree.count == 0) { 1029 /* remove empty zone if inserts failed */ 1030 neg_delete_zone(neg, zone); 1031 } 1032 lock_basic_unlock(&neg->lock); 1033 } 1034 1035 /** 1036 * Check that an NSEC3 rrset does not have a type set. 1037 * None of the nsec3s in a hash-collision are allowed to have the type. 1038 * (since we do not know which one is the nsec3 looked at, flags, ..., we 1039 * ignore the cached item and let it bypass negative caching). 1040 * @param k: the nsec3 rrset to check. 1041 * @param t: type to check 1042 * @return true if no RRs have the type. 1043 */ 1044 static int nsec3_no_type(struct ub_packed_rrset_key* k, uint16_t t) 1045 { 1046 int count = (int)((struct packed_rrset_data*)k->entry.data)->count; 1047 int i; 1048 for(i=0; i<count; i++) 1049 if(nsec3_has_type(k, i, t)) 1050 return 0; 1051 return 1; 1052 } 1053 1054 /** 1055 * See if rrset exists in rrset cache. 1056 * If it does, the bit is checked, and if not expired, it is returned 1057 * allocated in region. 1058 * @param rrset_cache: rrset cache 1059 * @param qname: to lookup rrset name 1060 * @param qname_len: length of qname. 1061 * @param qtype: type of rrset to lookup, host order 1062 * @param qclass: class of rrset to lookup, host order 1063 * @param flags: flags for rrset to lookup 1064 * @param region: where to alloc result 1065 * @param checkbit: if true, a bit in the nsec typemap is checked for absence. 1066 * @param checktype: which bit to check 1067 * @param now: to check ttl against 1068 * @return rrset or NULL 1069 */ 1070 static struct ub_packed_rrset_key* 1071 grab_nsec(struct rrset_cache* rrset_cache, uint8_t* qname, size_t qname_len, 1072 uint16_t qtype, uint16_t qclass, uint32_t flags, 1073 struct regional* region, int checkbit, uint16_t checktype, 1074 time_t now) 1075 { 1076 struct ub_packed_rrset_key* r, *k = rrset_cache_lookup(rrset_cache, 1077 qname, qname_len, qtype, qclass, flags, now, 0); 1078 struct packed_rrset_data* d; 1079 if(!k) return NULL; 1080 d = k->entry.data; 1081 /* only secure or unchecked records that have signatures. */ 1082 if( ! ( d->security == sec_status_secure || 1083 (d->security == sec_status_unchecked && 1084 d->rrsig_count > 0) ) ) { 1085 lock_rw_unlock(&k->entry.lock); 1086 return NULL; 1087 } 1088 /* check if checktype is absent */ 1089 if(checkbit && ( 1090 (qtype == LDNS_RR_TYPE_NSEC && nsec_has_type(k, checktype)) || 1091 (qtype == LDNS_RR_TYPE_NSEC3 && !nsec3_no_type(k, checktype)) 1092 )) { 1093 lock_rw_unlock(&k->entry.lock); 1094 return NULL; 1095 } 1096 /* looks OK! copy to region and return it */ 1097 r = packed_rrset_copy_region(k, region, now); 1098 /* if it failed, we return the NULL */ 1099 lock_rw_unlock(&k->entry.lock); 1100 return r; 1101 } 1102 1103 /** 1104 * Get best NSEC record for qname. Might be matching, covering or totally 1105 * useless. 1106 * @param neg_cache: neg cache 1107 * @param qname: to lookup rrset name 1108 * @param qname_len: length of qname. 1109 * @param qclass: class of rrset to lookup, host order 1110 * @param rrset_cache: rrset cache 1111 * @param now: to check ttl against 1112 * @param region: where to alloc result 1113 * @return rrset or NULL 1114 */ 1115 static struct ub_packed_rrset_key* 1116 neg_find_nsec(struct val_neg_cache* neg_cache, uint8_t* qname, size_t qname_len, 1117 uint16_t qclass, struct rrset_cache* rrset_cache, time_t now, 1118 struct regional* region) 1119 { 1120 int labs; 1121 uint32_t flags; 1122 struct val_neg_zone* zone; 1123 struct val_neg_data* data; 1124 struct ub_packed_rrset_key* nsec; 1125 1126 labs = dname_count_labels(qname); 1127 lock_basic_lock(&neg_cache->lock); 1128 zone = neg_closest_zone_parent(neg_cache, qname, qname_len, labs, 1129 qclass); 1130 while(zone && !zone->in_use) 1131 zone = zone->parent; 1132 if(!zone) { 1133 lock_basic_unlock(&neg_cache->lock); 1134 return NULL; 1135 } 1136 1137 /* NSEC only for now */ 1138 if(zone->nsec3_hash) { 1139 lock_basic_unlock(&neg_cache->lock); 1140 return NULL; 1141 } 1142 1143 /* ignore return value, don't care if it is an exact or smaller match */ 1144 (void)neg_closest_data(zone, qname, qname_len, labs, &data); 1145 if(!data) { 1146 lock_basic_unlock(&neg_cache->lock); 1147 return NULL; 1148 } 1149 1150 /* ENT nodes are not in use, try the previous node. If the previous node 1151 * is not in use, we don't have an useful NSEC and give up. */ 1152 if(!data->in_use) { 1153 data = (struct val_neg_data*)rbtree_previous((rbnode_type*)data); 1154 if((rbnode_type*)data == RBTREE_NULL || !data->in_use) { 1155 lock_basic_unlock(&neg_cache->lock); 1156 return NULL; 1157 } 1158 } 1159 1160 flags = 0; 1161 if(query_dname_compare(data->name, zone->name) == 0) 1162 flags = PACKED_RRSET_NSEC_AT_APEX; 1163 1164 nsec = grab_nsec(rrset_cache, data->name, data->len, LDNS_RR_TYPE_NSEC, 1165 zone->dclass, flags, region, 0, 0, now); 1166 lock_basic_unlock(&neg_cache->lock); 1167 return nsec; 1168 } 1169 1170 /** find nsec3 closest encloser in neg cache */ 1171 static struct val_neg_data* 1172 neg_find_nsec3_ce(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len, 1173 int qlabs, sldns_buffer* buf, uint8_t* hashnc, size_t* nclen) 1174 { 1175 struct val_neg_data* data; 1176 uint8_t hashce[NSEC3_SHA_LEN]; 1177 uint8_t b32[257]; 1178 size_t celen, b32len; 1179 int hashmax = MAX_NSEC3_CALCULATIONS; 1180 if(qlabs > hashmax) { 1181 /* strip leading labels so the walk costs at most 1182 * MAX_NSEC3_CALCULATIONS hashes, mirroring val_nsec3.c */ 1183 while(qlabs > hashmax) { 1184 dname_remove_label(&qname, &qname_len); 1185 qlabs--; 1186 } 1187 } 1188 1189 *nclen = 0; 1190 while(qlabs > 0) { 1191 /* hash */ 1192 if(!(celen=nsec3_get_hashed(buf, qname, qname_len, 1193 zone->nsec3_hash, zone->nsec3_iter, zone->nsec3_salt, 1194 zone->nsec3_saltlen, hashce, sizeof(hashce)))) 1195 return NULL; 1196 if(!(b32len=nsec3_hash_to_b32(hashce, celen, zone->name, 1197 zone->len, b32, sizeof(b32)))) 1198 return NULL; 1199 1200 /* lookup (exact match only) */ 1201 data = neg_find_data(zone, b32, b32len, zone->labs+1); 1202 if(data && data->in_use) { 1203 /* found ce match! */ 1204 return data; 1205 } 1206 1207 *nclen = celen; 1208 memmove(hashnc, hashce, celen); 1209 dname_remove_label(&qname, &qname_len); 1210 qlabs --; 1211 } 1212 return NULL; 1213 } 1214 1215 /** check nsec3 parameters on nsec3 rrset with current zone values */ 1216 static int 1217 neg_params_ok(struct val_neg_zone* zone, struct ub_packed_rrset_key* rrset) 1218 { 1219 int h; 1220 uint8_t* s; 1221 size_t slen, it; 1222 if(!nsec3_get_params(rrset, 0, &h, &it, &s, &slen)) 1223 return 0; 1224 return (h == zone->nsec3_hash && it == zone->nsec3_iter && 1225 slen == zone->nsec3_saltlen && 1226 (slen != 0 && zone->nsec3_salt && s 1227 && memcmp(zone->nsec3_salt, s, slen) == 0)); 1228 } 1229 1230 /** get next closer for nsec3 proof */ 1231 static struct ub_packed_rrset_key* 1232 neg_nsec3_getnc(struct val_neg_zone* zone, uint8_t* hashnc, size_t nclen, 1233 struct rrset_cache* rrset_cache, struct regional* region, 1234 time_t now, uint8_t* b32, size_t maxb32) 1235 { 1236 struct ub_packed_rrset_key* nc_rrset; 1237 struct val_neg_data* data; 1238 size_t b32len; 1239 1240 if(!(b32len=nsec3_hash_to_b32(hashnc, nclen, zone->name, 1241 zone->len, b32, maxb32))) 1242 return NULL; 1243 (void)neg_closest_data(zone, b32, b32len, zone->labs+1, &data); 1244 if(!data && zone->tree.count != 0) { 1245 /* could be before the first entry ; return the last 1246 * entry (possibly the rollover nsec3 at end) */ 1247 data = (struct val_neg_data*)rbtree_last(&zone->tree); 1248 } 1249 while(data && !data->in_use) 1250 data = data->parent; 1251 if(!data) 1252 return NULL; 1253 /* got a data element in tree, grab it */ 1254 nc_rrset = grab_nsec(rrset_cache, data->name, data->len, 1255 LDNS_RR_TYPE_NSEC3, zone->dclass, 0, region, 0, 0, now); 1256 if(!nc_rrset) 1257 return NULL; 1258 if(!neg_params_ok(zone, nc_rrset)) 1259 return NULL; 1260 return nc_rrset; 1261 } 1262 1263 /** neg cache nsec3 proof procedure*/ 1264 static struct dns_msg* 1265 neg_nsec3_proof_ds(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len, 1266 int qlabs, sldns_buffer* buf, struct rrset_cache* rrset_cache, 1267 struct regional* region, time_t now, uint8_t* topname) 1268 { 1269 struct dns_msg* msg; 1270 struct val_neg_data* data; 1271 uint8_t hashnc[NSEC3_SHA_LEN]; 1272 size_t nclen; 1273 struct ub_packed_rrset_key* ce_rrset, *nc_rrset; 1274 struct nsec3_cached_hash c; 1275 uint8_t nc_b32[257]; 1276 1277 /* for NSEC3 ; determine the closest encloser for which we 1278 * can find an exact match. Remember the hashed lower name, 1279 * since that is the one we need a closest match for. 1280 * If we find a match straight away, then it becomes NODATA. 1281 * Otherwise, NXDOMAIN or if OPTOUT, an insecure delegation. 1282 * Also check that parameters are the same on closest encloser 1283 * and on closest match. 1284 */ 1285 if(!zone->nsec3_hash) 1286 return NULL; /* not nsec3 zone */ 1287 1288 if(!topname && qlabs > zone->labs + 1) 1289 return NULL; /* iterator caller; opt-out proof would be discarded 1290 * at the !topname check below anyway. 1291 * The qlabs check allows the exact-match for 1292 * the one-label-below-zone case. */ 1293 1294 if(!(data=neg_find_nsec3_ce(zone, qname, qname_len, qlabs, buf, 1295 hashnc, &nclen))) { 1296 return NULL; 1297 } 1298 1299 /* grab the ce rrset */ 1300 ce_rrset = grab_nsec(rrset_cache, data->name, data->len, 1301 LDNS_RR_TYPE_NSEC3, zone->dclass, 0, region, 1, 1302 LDNS_RR_TYPE_DS, now); 1303 if(!ce_rrset) 1304 return NULL; 1305 if(!neg_params_ok(zone, ce_rrset)) 1306 return NULL; 1307 1308 if(nclen == 0) { 1309 /* exact match, just check the type bits */ 1310 /* need: -SOA, -DS, +NS */ 1311 if(nsec3_has_type(ce_rrset, 0, LDNS_RR_TYPE_SOA) || 1312 nsec3_has_type(ce_rrset, 0, LDNS_RR_TYPE_DS) || 1313 !nsec3_has_type(ce_rrset, 0, LDNS_RR_TYPE_NS)) 1314 return NULL; 1315 if(!(msg = dns_msg_create(qname, qname_len, 1316 LDNS_RR_TYPE_DS, zone->dclass, region, 1))) 1317 return NULL; 1318 /* The cache response means recursion is available. */ 1319 msg->rep->flags |= BIT_RA; 1320 /* TTL reduced in grab_nsec */ 1321 if(!dns_msg_authadd(msg, region, ce_rrset, 0)) 1322 return NULL; 1323 return msg; 1324 } 1325 1326 /* optout is not allowed without knowing the trust-anchor in use, 1327 * otherwise the optout could spoof away that anchor */ 1328 if(!topname) 1329 return NULL; 1330 1331 /* if there is no exact match, it must be in an optout span 1332 * (an existing DS implies an NSEC3 must exist) */ 1333 nc_rrset = neg_nsec3_getnc(zone, hashnc, nclen, rrset_cache, 1334 region, now, nc_b32, sizeof(nc_b32)); 1335 if(!nc_rrset) 1336 return NULL; 1337 if(!neg_params_ok(zone, nc_rrset)) 1338 return NULL; 1339 if(!nsec3_has_optout(nc_rrset, 0)) 1340 return NULL; 1341 c.hash = hashnc; 1342 c.hash_len = nclen; 1343 c.b32 = nc_b32+1; 1344 c.b32_len = (size_t)nc_b32[0]; 1345 if(nsec3_covers(zone->name, &c, nc_rrset, 0, buf)) { 1346 /* nc_rrset covers the next closer name. 1347 * ce_rrset equals a closer encloser. 1348 * nc_rrset is optout. 1349 * No need to check wildcard for type DS */ 1350 /* capacity=3: ce + nc + soa(if needed) */ 1351 if(!(msg = dns_msg_create(qname, qname_len, 1352 LDNS_RR_TYPE_DS, zone->dclass, region, 3))) 1353 return NULL; 1354 /* The cache response means recursion is available. */ 1355 msg->rep->flags |= BIT_RA; 1356 /* now=0 because TTL was reduced in grab_nsec */ 1357 if(!dns_msg_authadd(msg, region, ce_rrset, 0)) 1358 return NULL; 1359 if(!dns_msg_authadd(msg, region, nc_rrset, 0)) 1360 return NULL; 1361 return msg; 1362 } 1363 return NULL; 1364 } 1365 1366 /** 1367 * Add SOA record for external responses. 1368 * @param rrset_cache: to look into. 1369 * @param now: current time. 1370 * @param region: where to perform the allocation 1371 * @param msg: current msg with NSEC. 1372 * @param zone: val_neg_zone if we have one. 1373 * @return false on lookup or alloc failure. 1374 */ 1375 static int add_soa(struct rrset_cache* rrset_cache, time_t now, 1376 struct regional* region, struct dns_msg* msg, struct val_neg_zone* zone) 1377 { 1378 struct ub_packed_rrset_key* soa; 1379 uint8_t* nm; 1380 size_t nmlen; 1381 uint16_t dclass; 1382 if(zone) { 1383 nm = zone->name; 1384 nmlen = zone->len; 1385 dclass = zone->dclass; 1386 } else { 1387 /* Assumes the signer is the zone SOA to add */ 1388 nm = reply_nsec_signer(msg->rep, &nmlen, &dclass); 1389 if(!nm) 1390 return 0; 1391 } 1392 soa = rrset_cache_lookup(rrset_cache, nm, nmlen, LDNS_RR_TYPE_SOA, 1393 dclass, PACKED_RRSET_SOA_NEG, now, 0); 1394 if(!soa) 1395 return 0; 1396 if(!dns_msg_authadd(msg, region, soa, now)) { 1397 lock_rw_unlock(&soa->entry.lock); 1398 return 0; 1399 } 1400 lock_rw_unlock(&soa->entry.lock); 1401 return 1; 1402 } 1403 1404 struct dns_msg* 1405 val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo, 1406 struct regional* region, struct rrset_cache* rrset_cache, 1407 sldns_buffer* buf, time_t now, int addsoa, uint8_t* topname, 1408 struct config_file* cfg) 1409 { 1410 struct dns_msg* msg; 1411 struct ub_packed_rrset_key* nsec; /* qname matching/covering nsec */ 1412 struct ub_packed_rrset_key* wcrr; /* wildcard record or nsec */ 1413 uint8_t* nodata_wc = NULL; 1414 uint8_t* ce = NULL; 1415 size_t ce_len; 1416 uint8_t wc_ce[LDNS_MAX_DOMAINLEN+3]; 1417 struct query_info wc_qinfo; 1418 struct ub_packed_rrset_key* cache_wc; 1419 struct packed_rrset_data* wcrr_data; 1420 int rcode = LDNS_RCODE_NOERROR; 1421 uint8_t* zname; 1422 size_t zname_len; 1423 int zname_labs; 1424 struct val_neg_zone* zone; 1425 1426 /* only for DS queries when aggressive use of NSEC is disabled */ 1427 if(qinfo->qtype != LDNS_RR_TYPE_DS && !cfg->aggressive_nsec) 1428 return NULL; 1429 log_assert(!topname || dname_subdomain_c(qinfo->qname, topname)); 1430 1431 /* Get best available NSEC for qname */ 1432 nsec = neg_find_nsec(neg, qinfo->qname, qinfo->qname_len, qinfo->qclass, 1433 rrset_cache, now, region); 1434 1435 /* Matching NSEC, use to generate No Data answer. Not creating answers 1436 * yet for No Data proven using wildcard. */ 1437 if(nsec && nsec_proves_nodata(nsec, qinfo, &nodata_wc) && !nodata_wc) { 1438 /* do not create nodata answers for qtype ANY, it is a query 1439 * type, not an rrtype to disprove. Nameerrors are useful for 1440 * qtype ANY, in the else branch. */ 1441 if(qinfo->qtype == LDNS_RR_TYPE_ANY) 1442 return NULL; 1443 if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len, 1444 qinfo->qtype, qinfo->qclass, region, 2))) 1445 return NULL; 1446 /* The cache response means recursion is available. */ 1447 msg->rep->flags |= BIT_RA; 1448 if(!dns_msg_authadd(msg, region, nsec, 0)) 1449 return NULL; 1450 if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL)) 1451 return NULL; 1452 1453 lock_basic_lock(&neg->lock); 1454 neg->num_neg_cache_noerror++; 1455 lock_basic_unlock(&neg->lock); 1456 return msg; 1457 } else if(nsec && val_nsec_proves_name_error(nsec, qinfo->qname)) { 1458 if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len, 1459 qinfo->qtype, qinfo->qclass, region, 3))) 1460 return NULL; 1461 /* The cache response means recursion is available. */ 1462 msg->rep->flags |= BIT_RA; 1463 if(!(ce = nsec_closest_encloser(qinfo->qname, nsec))) 1464 return NULL; 1465 dname_count_size_labels(ce, &ce_len); 1466 1467 /* No extra extra NSEC required if both nameerror qname and 1468 * nodata *.ce. are proven already. */ 1469 if(!nodata_wc || query_dname_compare(nodata_wc, ce) != 0) { 1470 /* Qname proven non existing, get wildcard record for 1471 * QTYPE or NSEC covering or matching wildcard. */ 1472 1473 /* Num labels in ce is always smaller than in qname, 1474 * therefore adding the wildcard label cannot overflow 1475 * buffer. */ 1476 wc_ce[0] = 1; 1477 wc_ce[1] = (uint8_t)'*'; 1478 memmove(wc_ce+2, ce, ce_len); 1479 wc_qinfo.qname = wc_ce; 1480 wc_qinfo.qname_len = ce_len + 2; 1481 wc_qinfo.qtype = qinfo->qtype; 1482 1483 1484 if((cache_wc = rrset_cache_lookup(rrset_cache, wc_qinfo.qname, 1485 wc_qinfo.qname_len, wc_qinfo.qtype, 1486 qinfo->qclass, 0/*flags*/, now, 0/*read only*/))) { 1487 /* Synthesize wildcard answer */ 1488 wcrr_data = (struct packed_rrset_data*)cache_wc->entry.data; 1489 if(!(wcrr_data->security == sec_status_secure || 1490 (wcrr_data->security == sec_status_unchecked && 1491 wcrr_data->rrsig_count > 0))) { 1492 lock_rw_unlock(&cache_wc->entry.lock); 1493 return NULL; 1494 } 1495 if(!(wcrr = packed_rrset_copy_region(cache_wc, 1496 region, now))) { 1497 lock_rw_unlock(&cache_wc->entry.lock); 1498 return NULL; 1499 }; 1500 lock_rw_unlock(&cache_wc->entry.lock); 1501 wcrr->rk.dname = qinfo->qname; 1502 wcrr->rk.dname_len = qinfo->qname_len; 1503 if(!dns_msg_ansadd(msg, region, wcrr, 0)) 1504 return NULL; 1505 /* No SOA needed for wildcard synthesised 1506 * answer. */ 1507 addsoa = 0; 1508 } else { 1509 /* Get wildcard NSEC for possible non existence 1510 * proof */ 1511 if(!(wcrr = neg_find_nsec(neg, wc_qinfo.qname, 1512 wc_qinfo.qname_len, qinfo->qclass, 1513 rrset_cache, now, region))) 1514 return NULL; 1515 1516 nodata_wc = NULL; 1517 if(val_nsec_proves_name_error(wcrr, wc_ce)) 1518 rcode = LDNS_RCODE_NXDOMAIN; 1519 else if(!nsec_proves_nodata(wcrr, &wc_qinfo, 1520 &nodata_wc) || nodata_wc) 1521 /* &nodata_wc shouldn't be set, wc_qinfo 1522 * already contains wildcard domain. */ 1523 /* NSEC doesn't prove anything for 1524 * wildcard. */ 1525 return NULL; 1526 if(query_dname_compare(wcrr->rk.dname, 1527 nsec->rk.dname) != 0) 1528 if(!dns_msg_authadd(msg, region, wcrr, 0)) 1529 return NULL; 1530 } 1531 } 1532 1533 if(!dns_msg_authadd(msg, region, nsec, 0)) 1534 return NULL; 1535 if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL)) 1536 return NULL; 1537 1538 /* Increment statistic counters */ 1539 lock_basic_lock(&neg->lock); 1540 if(rcode == LDNS_RCODE_NOERROR) 1541 neg->num_neg_cache_noerror++; 1542 else if(rcode == LDNS_RCODE_NXDOMAIN) 1543 neg->num_neg_cache_nxdomain++; 1544 lock_basic_unlock(&neg->lock); 1545 1546 FLAGS_SET_RCODE(msg->rep->flags, rcode); 1547 return msg; 1548 } 1549 1550 /* No aggressive use of NSEC3 for now, only proceed for DS types. */ 1551 if(qinfo->qtype != LDNS_RR_TYPE_DS){ 1552 return NULL; 1553 } 1554 /* check NSEC3 neg cache for type DS */ 1555 /* need to look one zone higher for DS type */ 1556 zname = qinfo->qname; 1557 zname_len = qinfo->qname_len; 1558 dname_remove_label(&zname, &zname_len); 1559 zname_labs = dname_count_labels(zname); 1560 1561 /* lookup closest zone */ 1562 lock_basic_lock(&neg->lock); 1563 zone = neg_closest_zone_parent(neg, zname, zname_len, zname_labs, 1564 qinfo->qclass); 1565 while(zone && !zone->in_use) 1566 zone = zone->parent; 1567 /* check that the zone is not too high up so that we do not pick data 1568 * out of a zone that is above the last-seen key (or trust-anchor). */ 1569 if(zone && topname) { 1570 if(!dname_subdomain_c(zone->name, topname)) 1571 zone = NULL; 1572 } 1573 if(!zone) { 1574 lock_basic_unlock(&neg->lock); 1575 return NULL; 1576 } 1577 1578 msg = neg_nsec3_proof_ds(zone, qinfo->qname, qinfo->qname_len, 1579 zname_labs+1, buf, rrset_cache, region, now, topname); 1580 if(msg && addsoa && !add_soa(rrset_cache, now, region, msg, zone)) { 1581 lock_basic_unlock(&neg->lock); 1582 return NULL; 1583 } 1584 lock_basic_unlock(&neg->lock); 1585 return msg; 1586 } 1587 1588 void 1589 val_neg_adjust_size(struct val_neg_cache* neg, size_t max) 1590 { 1591 lock_basic_lock(&neg->lock); 1592 neg->max = max; 1593 neg_make_space(neg, 0); 1594 lock_basic_unlock(&neg->lock); 1595 } 1596