1 /* 2 * services/localzone.c - local zones authority service. 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /** 37 * \file 38 * 39 * This file contains functions to enable local zone authority service. 40 */ 41 #include "config.h" 42 #include "services/localzone.h" 43 #include "sldns/str2wire.h" 44 #include "sldns/sbuffer.h" 45 #include "util/regional.h" 46 #include "util/config_file.h" 47 #include "util/data/dname.h" 48 #include "util/data/packed_rrset.h" 49 #include "util/data/msgencode.h" 50 #include "util/net_help.h" 51 #include "util/netevent.h" 52 #include "util/data/msgreply.h" 53 #include "util/data/msgparse.h" 54 #include "util/as112.h" 55 56 struct local_zones* 57 local_zones_create(void) 58 { 59 struct local_zones* zones = (struct local_zones*)calloc(1, 60 sizeof(*zones)); 61 if(!zones) 62 return NULL; 63 rbtree_init(&zones->ztree, &local_zone_cmp); 64 lock_rw_init(&zones->lock); 65 lock_protect(&zones->lock, &zones->ztree, sizeof(zones->ztree)); 66 /* also lock protects the rbnode's in struct local_zone */ 67 return zones; 68 } 69 70 /** helper traverse to delete zones */ 71 static void 72 lzdel(rbnode_t* n, void* ATTR_UNUSED(arg)) 73 { 74 struct local_zone* z = (struct local_zone*)n->key; 75 local_zone_delete(z); 76 } 77 78 void 79 local_zones_delete(struct local_zones* zones) 80 { 81 if(!zones) 82 return; 83 lock_rw_destroy(&zones->lock); 84 /* walk through zones and delete them all */ 85 traverse_postorder(&zones->ztree, lzdel, NULL); 86 free(zones); 87 } 88 89 void 90 local_zone_delete(struct local_zone* z) 91 { 92 if(!z) 93 return; 94 lock_rw_destroy(&z->lock); 95 regional_destroy(z->region); 96 free(z->name); 97 free(z->taglist); 98 free(z); 99 } 100 101 int 102 local_zone_cmp(const void* z1, const void* z2) 103 { 104 /* first sort on class, so that hierarchy can be maintained within 105 * a class */ 106 struct local_zone* a = (struct local_zone*)z1; 107 struct local_zone* b = (struct local_zone*)z2; 108 int m; 109 if(a->dclass != b->dclass) { 110 if(a->dclass < b->dclass) 111 return -1; 112 return 1; 113 } 114 return dname_lab_cmp(a->name, a->namelabs, b->name, b->namelabs, &m); 115 } 116 117 int 118 local_data_cmp(const void* d1, const void* d2) 119 { 120 struct local_data* a = (struct local_data*)d1; 121 struct local_data* b = (struct local_data*)d2; 122 int m; 123 return dname_canon_lab_cmp(a->name, a->namelabs, b->name, 124 b->namelabs, &m); 125 } 126 127 /* form wireformat from text format domain name */ 128 int 129 parse_dname(const char* str, uint8_t** res, size_t* len, int* labs) 130 { 131 *res = sldns_str2wire_dname(str, len); 132 *labs = 0; 133 if(!*res) { 134 log_err("cannot parse name %s", str); 135 return 0; 136 } 137 *labs = dname_count_size_labels(*res, len); 138 return 1; 139 } 140 141 /** create a new localzone */ 142 static struct local_zone* 143 local_zone_create(uint8_t* nm, size_t len, int labs, 144 enum localzone_type t, uint16_t dclass) 145 { 146 struct local_zone* z = (struct local_zone*)calloc(1, sizeof(*z)); 147 if(!z) { 148 return NULL; 149 } 150 z->node.key = z; 151 z->dclass = dclass; 152 z->type = t; 153 z->name = nm; 154 z->namelen = len; 155 z->namelabs = labs; 156 lock_rw_init(&z->lock); 157 z->region = regional_create(); 158 if(!z->region) { 159 free(z); 160 return NULL; 161 } 162 rbtree_init(&z->data, &local_data_cmp); 163 lock_protect(&z->lock, &z->parent, sizeof(*z)-sizeof(rbnode_t)); 164 /* also the zones->lock protects node, parent, name*, class */ 165 return z; 166 } 167 168 /** enter a new zone with allocated dname returns with WRlock */ 169 static struct local_zone* 170 lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len, 171 int labs, enum localzone_type t, uint16_t c) 172 { 173 struct local_zone* z = local_zone_create(nm, len, labs, t, c); 174 if(!z) { 175 free(nm); 176 log_err("out of memory"); 177 return NULL; 178 } 179 180 /* add to rbtree */ 181 lock_rw_wrlock(&zones->lock); 182 lock_rw_wrlock(&z->lock); 183 if(!rbtree_insert(&zones->ztree, &z->node)) { 184 log_warn("duplicate local-zone"); 185 lock_rw_unlock(&z->lock); 186 local_zone_delete(z); 187 /* find the correct zone, so not an error for duplicate */ 188 z = local_zones_find(zones, nm, len, labs, c); 189 lock_rw_wrlock(&z->lock); 190 lock_rw_unlock(&zones->lock); 191 return z; 192 } 193 lock_rw_unlock(&zones->lock); 194 return z; 195 } 196 197 /** enter a new zone */ 198 static struct local_zone* 199 lz_enter_zone(struct local_zones* zones, const char* name, const char* type, 200 uint16_t dclass) 201 { 202 struct local_zone* z; 203 enum localzone_type t; 204 uint8_t* nm; 205 size_t len; 206 int labs; 207 if(!parse_dname(name, &nm, &len, &labs)) { 208 log_err("bad zone name %s %s", name, type); 209 return NULL; 210 } 211 if(!local_zone_str2type(type, &t)) { 212 log_err("bad lz_enter_zone type %s %s", name, type); 213 free(nm); 214 return NULL; 215 } 216 if(!(z=lz_enter_zone_dname(zones, nm, len, labs, t, dclass))) { 217 log_err("could not enter zone %s %s", name, type); 218 return NULL; 219 } 220 return z; 221 } 222 223 /** return name and class and rdata of rr; parses string */ 224 static int 225 get_rr_content(const char* str, uint8_t** nm, uint16_t* type, 226 uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len, 227 uint8_t** rdata, size_t* rdata_len) 228 { 229 size_t dname_len = 0; 230 int e = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600, 231 NULL, 0, NULL, 0); 232 if(e) { 233 log_err("error parsing local-data at %d: '%s': %s", 234 LDNS_WIREPARSE_OFFSET(e), str, 235 sldns_get_errorstr_parse(e)); 236 return 0; 237 } 238 *nm = memdup(rr, dname_len); 239 if(!*nm) { 240 log_err("out of memory"); 241 return 0; 242 } 243 *dclass = sldns_wirerr_get_class(rr, len, dname_len); 244 *type = sldns_wirerr_get_type(rr, len, dname_len); 245 *ttl = (time_t)sldns_wirerr_get_ttl(rr, len, dname_len); 246 *rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len); 247 *rdata_len = sldns_wirerr_get_rdatalen(rr, len, dname_len)+2; 248 return 1; 249 } 250 251 /** return name and class of rr; parses string */ 252 static int 253 get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass) 254 { 255 uint8_t rr[LDNS_RR_BUF_SIZE]; 256 size_t len = sizeof(rr), dname_len = 0; 257 int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600, 258 NULL, 0, NULL, 0); 259 if(s != 0) { 260 log_err("error parsing local-data at %d '%s': %s", 261 LDNS_WIREPARSE_OFFSET(s), str, 262 sldns_get_errorstr_parse(s)); 263 return 0; 264 } 265 *nm = memdup(rr, dname_len); 266 *dclass = sldns_wirerr_get_class(rr, len, dname_len); 267 if(!*nm) { 268 log_err("out of memory"); 269 return 0; 270 } 271 return 1; 272 } 273 274 /** 275 * Find an rrset in local data structure. 276 * @param data: local data domain name structure. 277 * @param type: type to look for (host order). 278 * @return rrset pointer or NULL if not found. 279 */ 280 static struct local_rrset* 281 local_data_find_type(struct local_data* data, uint16_t type) 282 { 283 struct local_rrset* p; 284 type = htons(type); 285 for(p = data->rrsets; p; p = p->next) { 286 if(p->rrset->rk.type == type) 287 return p; 288 } 289 return NULL; 290 } 291 292 /** check for RR duplicates */ 293 static int 294 rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len) 295 { 296 size_t i; 297 for(i=0; i<pd->count; i++) { 298 if(pd->rr_len[i] == rdata_len && 299 memcmp(pd->rr_data[i], rdata, rdata_len) == 0) 300 return 1; 301 } 302 return 0; 303 } 304 305 /** new local_rrset */ 306 static struct local_rrset* 307 new_local_rrset(struct regional* region, struct local_data* node, 308 uint16_t rrtype, uint16_t rrclass) 309 { 310 struct packed_rrset_data* pd; 311 struct local_rrset* rrset = (struct local_rrset*) 312 regional_alloc_zero(region, sizeof(*rrset)); 313 if(!rrset) { 314 log_err("out of memory"); 315 return NULL; 316 } 317 rrset->next = node->rrsets; 318 node->rrsets = rrset; 319 rrset->rrset = (struct ub_packed_rrset_key*) 320 regional_alloc_zero(region, sizeof(*rrset->rrset)); 321 if(!rrset->rrset) { 322 log_err("out of memory"); 323 return NULL; 324 } 325 rrset->rrset->entry.key = rrset->rrset; 326 pd = (struct packed_rrset_data*)regional_alloc_zero(region, 327 sizeof(*pd)); 328 if(!pd) { 329 log_err("out of memory"); 330 return NULL; 331 } 332 pd->trust = rrset_trust_prim_noglue; 333 pd->security = sec_status_insecure; 334 rrset->rrset->entry.data = pd; 335 rrset->rrset->rk.dname = node->name; 336 rrset->rrset->rk.dname_len = node->namelen; 337 rrset->rrset->rk.type = htons(rrtype); 338 rrset->rrset->rk.rrset_class = htons(rrclass); 339 return rrset; 340 } 341 342 /** insert RR into RRset data structure; Wastes a couple of bytes */ 343 static int 344 insert_rr(struct regional* region, struct packed_rrset_data* pd, 345 uint8_t* rdata, size_t rdata_len, time_t ttl) 346 { 347 size_t* oldlen = pd->rr_len; 348 time_t* oldttl = pd->rr_ttl; 349 uint8_t** olddata = pd->rr_data; 350 351 /* add RR to rrset */ 352 pd->count++; 353 pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count); 354 pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count); 355 pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count); 356 if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) { 357 log_err("out of memory"); 358 return 0; 359 } 360 if(pd->count > 1) { 361 memcpy(pd->rr_len+1, oldlen, 362 sizeof(*pd->rr_len)*(pd->count-1)); 363 memcpy(pd->rr_ttl+1, oldttl, 364 sizeof(*pd->rr_ttl)*(pd->count-1)); 365 memcpy(pd->rr_data+1, olddata, 366 sizeof(*pd->rr_data)*(pd->count-1)); 367 } 368 pd->rr_len[0] = rdata_len; 369 pd->rr_ttl[0] = ttl; 370 pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len); 371 if(!pd->rr_data[0]) { 372 log_err("out of memory"); 373 return 0; 374 } 375 return 1; 376 } 377 378 /** find a data node by exact name */ 379 static struct local_data* 380 lz_find_node(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs) 381 { 382 struct local_data key; 383 key.node.key = &key; 384 key.name = nm; 385 key.namelen = nmlen; 386 key.namelabs = nmlabs; 387 return (struct local_data*)rbtree_search(&z->data, &key.node); 388 } 389 390 /** find a node, create it if not and all its empty nonterminal parents */ 391 static int 392 lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen, 393 int nmlabs, struct local_data** res) 394 { 395 struct local_data* ld = lz_find_node(z, nm, nmlen, nmlabs); 396 if(!ld) { 397 /* create a domain name to store rr. */ 398 ld = (struct local_data*)regional_alloc_zero(z->region, 399 sizeof(*ld)); 400 if(!ld) { 401 log_err("out of memory adding local data"); 402 return 0; 403 } 404 ld->node.key = ld; 405 ld->name = regional_alloc_init(z->region, nm, nmlen); 406 if(!ld->name) { 407 log_err("out of memory"); 408 return 0; 409 } 410 ld->namelen = nmlen; 411 ld->namelabs = nmlabs; 412 if(!rbtree_insert(&z->data, &ld->node)) { 413 log_assert(0); /* duplicate name */ 414 } 415 /* see if empty nonterminals need to be created */ 416 if(nmlabs > z->namelabs) { 417 dname_remove_label(&nm, &nmlen); 418 if(!lz_find_create_node(z, nm, nmlen, nmlabs-1, res)) 419 return 0; 420 } 421 } 422 *res = ld; 423 return 1; 424 } 425 426 /** enter data RR into auth zone */ 427 static int 428 lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) 429 { 430 uint8_t* nm; 431 size_t nmlen; 432 int nmlabs; 433 struct local_data* node; 434 struct local_rrset* rrset; 435 struct packed_rrset_data* pd; 436 uint16_t rrtype = 0, rrclass = 0; 437 time_t ttl = 0; 438 uint8_t rr[LDNS_RR_BUF_SIZE]; 439 uint8_t* rdata; 440 size_t rdata_len; 441 if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr), 442 &rdata, &rdata_len)) { 443 log_err("bad local-data: %s", rrstr); 444 return 0; 445 } 446 log_assert(z->dclass == rrclass); 447 if(z->type == local_zone_redirect && 448 query_dname_compare(z->name, nm) != 0) { 449 log_err("local-data in redirect zone must reside at top of zone" 450 ", not at %s", rrstr); 451 free(nm); 452 return 0; 453 } 454 nmlabs = dname_count_size_labels(nm, &nmlen); 455 if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) { 456 free(nm); 457 return 0; 458 } 459 log_assert(node); 460 free(nm); 461 462 rrset = local_data_find_type(node, rrtype); 463 if(!rrset) { 464 rrset = new_local_rrset(z->region, node, rrtype, rrclass); 465 if(!rrset) 466 return 0; 467 if(query_dname_compare(node->name, z->name) == 0) { 468 if(rrtype == LDNS_RR_TYPE_NSEC) 469 rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX; 470 if(rrtype == LDNS_RR_TYPE_SOA) 471 z->soa = rrset->rrset; 472 } 473 } 474 pd = (struct packed_rrset_data*)rrset->rrset->entry.data; 475 log_assert(rrset && pd); 476 477 /* check for duplicate RR */ 478 if(rr_is_duplicate(pd, rdata, rdata_len)) { 479 verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr); 480 return 1; 481 } 482 return insert_rr(z->region, pd, rdata, rdata_len, ttl); 483 } 484 485 /** enter a data RR into auth data; a zone for it must exist */ 486 static int 487 lz_enter_rr_str(struct local_zones* zones, const char* rr) 488 { 489 uint8_t* rr_name; 490 uint16_t rr_class; 491 size_t len; 492 int labs; 493 struct local_zone* z; 494 int r; 495 if(!get_rr_nameclass(rr, &rr_name, &rr_class)) { 496 log_err("bad rr %s", rr); 497 return 0; 498 } 499 labs = dname_count_size_labels(rr_name, &len); 500 lock_rw_rdlock(&zones->lock); 501 z = local_zones_lookup(zones, rr_name, len, labs, rr_class); 502 if(!z) { 503 lock_rw_unlock(&zones->lock); 504 fatal_exit("internal error: no zone for rr %s", rr); 505 } 506 lock_rw_wrlock(&z->lock); 507 lock_rw_unlock(&zones->lock); 508 free(rr_name); 509 r = lz_enter_rr_into_zone(z, rr); 510 lock_rw_unlock(&z->lock); 511 return r; 512 } 513 514 /** enter tagstring into zone */ 515 static int 516 lz_enter_zone_tag(struct local_zones* zones, char* zname, uint8_t* list, 517 size_t len, uint16_t rr_class) 518 { 519 uint8_t dname[LDNS_MAX_DOMAINLEN+1]; 520 size_t dname_len = sizeof(dname); 521 int dname_labs, r = 0; 522 struct local_zone* z; 523 524 if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) { 525 log_err("cannot parse zone name in local-zone-tag: %s", zname); 526 return 0; 527 } 528 dname_labs = dname_count_labels(dname); 529 530 lock_rw_rdlock(&zones->lock); 531 z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class); 532 if(!z) { 533 lock_rw_unlock(&zones->lock); 534 log_err("no local-zone for tag %s", zname); 535 return 0; 536 } 537 lock_rw_wrlock(&z->lock); 538 lock_rw_unlock(&zones->lock); 539 free(z->taglist); 540 z->taglist = memdup(list, len); 541 z->taglen = len; 542 if(z->taglist) 543 r = 1; 544 lock_rw_unlock(&z->lock); 545 return r; 546 } 547 548 /** enter override into zone */ 549 static int 550 lz_enter_override(struct local_zones* zones, char* zname, char* netblock, 551 char* type, uint16_t rr_class) 552 { 553 uint8_t dname[LDNS_MAX_DOMAINLEN+1]; 554 size_t dname_len = sizeof(dname); 555 int dname_labs; 556 struct sockaddr_storage addr; 557 int net; 558 socklen_t addrlen; 559 struct local_zone* z; 560 enum localzone_type t; 561 562 /* parse zone name */ 563 if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) { 564 log_err("cannot parse zone name in local-zone-override: %s %s", 565 zname, netblock); 566 return 0; 567 } 568 dname_labs = dname_count_labels(dname); 569 570 /* parse netblock */ 571 if(!netblockstrtoaddr(netblock, UNBOUND_DNS_PORT, &addr, &addrlen, 572 &net)) { 573 log_err("cannot parse netblock in local-zone-override: %s %s", 574 zname, netblock); 575 return 0; 576 } 577 578 /* parse zone type */ 579 if(!local_zone_str2type(type, &t)) { 580 log_err("cannot parse type in local-zone-override: %s %s %s", 581 zname, netblock, type); 582 return 0; 583 } 584 585 /* find localzone entry */ 586 lock_rw_rdlock(&zones->lock); 587 z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class); 588 if(!z) { 589 lock_rw_unlock(&zones->lock); 590 log_err("no local-zone for local-zone-override %s", zname); 591 return 0; 592 } 593 lock_rw_wrlock(&z->lock); 594 lock_rw_unlock(&zones->lock); 595 596 /* create netblock addr_tree if not present yet */ 597 if(!z->override_tree) { 598 z->override_tree = (struct rbtree_t*)regional_alloc_zero( 599 z->region, sizeof(*z->override_tree)); 600 if(!z->override_tree) { 601 lock_rw_unlock(&z->lock); 602 log_err("out of memory"); 603 return 0; 604 } 605 addr_tree_init(z->override_tree); 606 } 607 /* add new elem to tree */ 608 if(z->override_tree) { 609 struct local_zone_override* n; 610 n = (struct local_zone_override*)regional_alloc_zero( 611 z->region, sizeof(*n)); 612 if(!n) { 613 lock_rw_unlock(&z->lock); 614 log_err("out of memory"); 615 return 0; 616 } 617 n->type = t; 618 if(!addr_tree_insert(z->override_tree, 619 (struct addr_tree_node*)n, &addr, addrlen, net)) { 620 lock_rw_unlock(&z->lock); 621 log_err("duplicate local-zone-override %s %s", 622 zname, netblock); 623 return 1; 624 } 625 } 626 627 lock_rw_unlock(&z->lock); 628 return 1; 629 } 630 631 /** parse local-zone: statements */ 632 static int 633 lz_enter_zones(struct local_zones* zones, struct config_file* cfg) 634 { 635 struct config_str2list* p; 636 struct local_zone* z; 637 for(p = cfg->local_zones; p; p = p->next) { 638 if(!(z=lz_enter_zone(zones, p->str, p->str2, 639 LDNS_RR_CLASS_IN))) 640 return 0; 641 lock_rw_unlock(&z->lock); 642 } 643 return 1; 644 } 645 646 /** lookup a zone in rbtree; exact match only; SLOW due to parse */ 647 static int 648 lz_exists(struct local_zones* zones, const char* name) 649 { 650 struct local_zone z; 651 z.node.key = &z; 652 z.dclass = LDNS_RR_CLASS_IN; 653 if(!parse_dname(name, &z.name, &z.namelen, &z.namelabs)) { 654 log_err("bad name %s", name); 655 return 0; 656 } 657 lock_rw_rdlock(&zones->lock); 658 if(rbtree_search(&zones->ztree, &z.node)) { 659 lock_rw_unlock(&zones->lock); 660 free(z.name); 661 return 1; 662 } 663 lock_rw_unlock(&zones->lock); 664 free(z.name); 665 return 0; 666 } 667 668 /** lookup a zone in cfg->nodefault list */ 669 static int 670 lz_nodefault(struct config_file* cfg, const char* name) 671 { 672 struct config_strlist* p; 673 size_t len = strlen(name); 674 if(len == 0) return 0; 675 if(name[len-1] == '.') len--; 676 677 for(p = cfg->local_zones_nodefault; p; p = p->next) { 678 /* compare zone name, lowercase, compare without ending . */ 679 if(strncasecmp(p->str, name, len) == 0 && 680 (strlen(p->str) == len || (strlen(p->str)==len+1 && 681 p->str[len] == '.'))) 682 return 1; 683 } 684 return 0; 685 } 686 687 /** enter AS112 default zone */ 688 static int 689 add_as112_default(struct local_zones* zones, struct config_file* cfg, 690 const char* name) 691 { 692 struct local_zone* z; 693 char str[1024]; /* known long enough */ 694 if(lz_exists(zones, name) || lz_nodefault(cfg, name)) 695 return 1; /* do not enter default content */ 696 if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN))) 697 return 0; 698 snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. " 699 "nobody.invalid. 1 3600 1200 604800 10800", name); 700 if(!lz_enter_rr_into_zone(z, str)) { 701 lock_rw_unlock(&z->lock); 702 return 0; 703 } 704 snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name); 705 if(!lz_enter_rr_into_zone(z, str)) { 706 lock_rw_unlock(&z->lock); 707 return 0; 708 } 709 lock_rw_unlock(&z->lock); 710 return 1; 711 } 712 713 /** enter default zones */ 714 static int 715 lz_enter_defaults(struct local_zones* zones, struct config_file* cfg) 716 { 717 struct local_zone* z; 718 const char** zstr; 719 720 /* this list of zones is from RFC 6303 and RFC 7686 */ 721 722 /* block localhost level zones first, then onion and later the LAN zones */ 723 724 /* localhost. zone */ 725 if(!lz_exists(zones, "localhost.") && 726 !lz_nodefault(cfg, "localhost.")) { 727 if(!(z=lz_enter_zone(zones, "localhost.", "static", 728 LDNS_RR_CLASS_IN)) || 729 !lz_enter_rr_into_zone(z, 730 "localhost. 10800 IN NS localhost.") || 731 !lz_enter_rr_into_zone(z, 732 "localhost. 10800 IN SOA localhost. nobody.invalid. " 733 "1 3600 1200 604800 10800") || 734 !lz_enter_rr_into_zone(z, 735 "localhost. 10800 IN A 127.0.0.1") || 736 !lz_enter_rr_into_zone(z, 737 "localhost. 10800 IN AAAA ::1")) { 738 log_err("out of memory adding default zone"); 739 if(z) { lock_rw_unlock(&z->lock); } 740 return 0; 741 } 742 lock_rw_unlock(&z->lock); 743 } 744 /* reverse ip4 zone */ 745 if(!lz_exists(zones, "127.in-addr.arpa.") && 746 !lz_nodefault(cfg, "127.in-addr.arpa.")) { 747 if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static", 748 LDNS_RR_CLASS_IN)) || 749 !lz_enter_rr_into_zone(z, 750 "127.in-addr.arpa. 10800 IN NS localhost.") || 751 !lz_enter_rr_into_zone(z, 752 "127.in-addr.arpa. 10800 IN SOA localhost. " 753 "nobody.invalid. 1 3600 1200 604800 10800") || 754 !lz_enter_rr_into_zone(z, 755 "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) { 756 log_err("out of memory adding default zone"); 757 if(z) { lock_rw_unlock(&z->lock); } 758 return 0; 759 } 760 lock_rw_unlock(&z->lock); 761 } 762 /* reverse ip6 zone */ 763 if(!lz_exists(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") && 764 !lz_nodefault(cfg, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.")) { 765 if(!(z=lz_enter_zone(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", "static", 766 LDNS_RR_CLASS_IN)) || 767 !lz_enter_rr_into_zone(z, 768 "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost.") || 769 !lz_enter_rr_into_zone(z, 770 "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. " 771 "nobody.invalid. 1 3600 1200 604800 10800") || 772 !lz_enter_rr_into_zone(z, 773 "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.")) { 774 log_err("out of memory adding default zone"); 775 if(z) { lock_rw_unlock(&z->lock); } 776 return 0; 777 } 778 lock_rw_unlock(&z->lock); 779 } 780 /* onion. zone (RFC 7686) */ 781 if(!lz_exists(zones, "onion.") && 782 !lz_nodefault(cfg, "onion.")) { 783 if(!(z=lz_enter_zone(zones, "onion.", "static", 784 LDNS_RR_CLASS_IN)) || 785 !lz_enter_rr_into_zone(z, 786 "onion. 10800 IN NS localhost.") || 787 !lz_enter_rr_into_zone(z, 788 "onion. 10800 IN SOA localhost. nobody.invalid. " 789 "1 3600 1200 604800 10800")) { 790 log_err("out of memory adding default zone"); 791 if(z) { lock_rw_unlock(&z->lock); } 792 return 0; 793 } 794 lock_rw_unlock(&z->lock); 795 } 796 797 /* block AS112 zones, unless asked not to */ 798 if(!cfg->unblock_lan_zones) { 799 for(zstr = as112_zones; *zstr; zstr++) { 800 if(!add_as112_default(zones, cfg, *zstr)) { 801 log_err("out of memory adding default zone"); 802 return 0; 803 } 804 } 805 } 806 return 1; 807 } 808 809 /** parse local-zone-override: statements */ 810 static int 811 lz_enter_overrides(struct local_zones* zones, struct config_file* cfg) 812 { 813 struct config_str3list* p; 814 for(p = cfg->local_zone_overrides; p; p = p->next) { 815 if(!lz_enter_override(zones, p->str, p->str2, p->str3, 816 LDNS_RR_CLASS_IN)) 817 return 0; 818 } 819 return 1; 820 } 821 822 /** setup parent pointers, so that a lookup can be done for closest match */ 823 static void 824 init_parents(struct local_zones* zones) 825 { 826 struct local_zone* node, *prev = NULL, *p; 827 int m; 828 lock_rw_wrlock(&zones->lock); 829 RBTREE_FOR(node, struct local_zone*, &zones->ztree) { 830 lock_rw_wrlock(&node->lock); 831 node->parent = NULL; 832 if(!prev || prev->dclass != node->dclass) { 833 prev = node; 834 lock_rw_unlock(&node->lock); 835 continue; 836 } 837 (void)dname_lab_cmp(prev->name, prev->namelabs, node->name, 838 node->namelabs, &m); /* we know prev is smaller */ 839 /* sort order like: . com. bla.com. zwb.com. net. */ 840 /* find the previous, or parent-parent-parent */ 841 for(p = prev; p; p = p->parent) 842 /* looking for name with few labels, a parent */ 843 if(p->namelabs <= m) { 844 /* ==: since prev matched m, this is closest*/ 845 /* <: prev matches more, but is not a parent, 846 * this one is a (grand)parent */ 847 node->parent = p; 848 break; 849 } 850 prev = node; 851 852 if(node->override_tree) 853 addr_tree_init_parents(node->override_tree); 854 lock_rw_unlock(&node->lock); 855 } 856 lock_rw_unlock(&zones->lock); 857 } 858 859 /** enter implicit transparent zone for local-data: without local-zone: */ 860 static int 861 lz_setup_implicit(struct local_zones* zones, struct config_file* cfg) 862 { 863 /* walk over all items that have no parent zone and find 864 * the name that covers them all (could be the root) and 865 * add that as a transparent zone */ 866 struct config_strlist* p; 867 int have_name = 0; 868 int have_other_classes = 0; 869 uint16_t dclass = 0; 870 uint8_t* nm = 0; 871 size_t nmlen = 0; 872 int nmlabs = 0; 873 int match = 0; /* number of labels match count */ 874 875 init_parents(zones); /* to enable local_zones_lookup() */ 876 for(p = cfg->local_data; p; p = p->next) { 877 uint8_t* rr_name; 878 uint16_t rr_class; 879 size_t len; 880 int labs; 881 if(!get_rr_nameclass(p->str, &rr_name, &rr_class)) { 882 log_err("Bad local-data RR %s", p->str); 883 return 0; 884 } 885 labs = dname_count_size_labels(rr_name, &len); 886 lock_rw_rdlock(&zones->lock); 887 if(!local_zones_lookup(zones, rr_name, len, labs, rr_class)) { 888 if(!have_name) { 889 dclass = rr_class; 890 nm = rr_name; 891 nmlen = len; 892 nmlabs = labs; 893 match = labs; 894 have_name = 1; 895 } else { 896 int m; 897 if(rr_class != dclass) { 898 /* process other classes later */ 899 free(rr_name); 900 have_other_classes = 1; 901 lock_rw_unlock(&zones->lock); 902 continue; 903 } 904 /* find smallest shared topdomain */ 905 (void)dname_lab_cmp(nm, nmlabs, 906 rr_name, labs, &m); 907 free(rr_name); 908 if(m < match) 909 match = m; 910 } 911 } else free(rr_name); 912 lock_rw_unlock(&zones->lock); 913 } 914 if(have_name) { 915 uint8_t* n2; 916 struct local_zone* z; 917 /* allocate zone of smallest shared topdomain to contain em */ 918 n2 = nm; 919 dname_remove_labels(&n2, &nmlen, nmlabs - match); 920 n2 = memdup(n2, nmlen); 921 free(nm); 922 if(!n2) { 923 log_err("out of memory"); 924 return 0; 925 } 926 log_nametypeclass(VERB_ALGO, "implicit transparent local-zone", 927 n2, 0, dclass); 928 if(!(z=lz_enter_zone_dname(zones, n2, nmlen, match, 929 local_zone_transparent, dclass))) { 930 return 0; 931 } 932 lock_rw_unlock(&z->lock); 933 } 934 if(have_other_classes) { 935 /* restart to setup other class */ 936 return lz_setup_implicit(zones, cfg); 937 } 938 return 1; 939 } 940 941 /** enter local-zone-tag info */ 942 static int 943 lz_enter_zone_tags(struct local_zones* zones, struct config_file* cfg) 944 { 945 struct config_strbytelist* p; 946 int c = 0; 947 for(p = cfg->local_zone_tags; p; p = p->next) { 948 if(!lz_enter_zone_tag(zones, p->str, p->str2, p->str2len, 949 LDNS_RR_CLASS_IN)) 950 return 0; 951 c++; 952 } 953 if(c) verbose(VERB_ALGO, "applied tags to %d local zones", c); 954 return 1; 955 } 956 957 /** enter auth data */ 958 static int 959 lz_enter_data(struct local_zones* zones, struct config_file* cfg) 960 { 961 struct config_strlist* p; 962 for(p = cfg->local_data; p; p = p->next) { 963 if(!lz_enter_rr_str(zones, p->str)) 964 return 0; 965 } 966 return 1; 967 } 968 969 /** free memory from config */ 970 static void 971 lz_freeup_cfg(struct config_file* cfg) 972 { 973 config_deldblstrlist(cfg->local_zones); 974 cfg->local_zones = NULL; 975 config_delstrlist(cfg->local_zones_nodefault); 976 cfg->local_zones_nodefault = NULL; 977 config_delstrlist(cfg->local_data); 978 cfg->local_data = NULL; 979 } 980 981 int 982 local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg) 983 { 984 /* create zones from zone statements. */ 985 if(!lz_enter_zones(zones, cfg)) { 986 return 0; 987 } 988 /* apply default zones+content (unless disabled, or overridden) */ 989 if(!lz_enter_defaults(zones, cfg)) { 990 return 0; 991 } 992 /* enter local zone overrides */ 993 if(!lz_enter_overrides(zones, cfg)) { 994 return 0; 995 } 996 /* create implicit transparent zone from data. */ 997 if(!lz_setup_implicit(zones, cfg)) { 998 return 0; 999 } 1000 1001 /* setup parent ptrs for lookup during data entry */ 1002 init_parents(zones); 1003 /* insert local zone tags */ 1004 if(!lz_enter_zone_tags(zones, cfg)) { 1005 return 0; 1006 } 1007 /* insert local data */ 1008 if(!lz_enter_data(zones, cfg)) { 1009 return 0; 1010 } 1011 /* freeup memory from cfg struct. */ 1012 lz_freeup_cfg(cfg); 1013 return 1; 1014 } 1015 1016 struct local_zone* 1017 local_zones_lookup(struct local_zones* zones, 1018 uint8_t* name, size_t len, int labs, uint16_t dclass) 1019 { 1020 return local_zones_tags_lookup(zones, name, len, labs, 1021 dclass, NULL, 0, 1); 1022 } 1023 1024 struct local_zone* 1025 local_zones_tags_lookup(struct local_zones* zones, 1026 uint8_t* name, size_t len, int labs, uint16_t dclass, 1027 uint8_t* taglist, size_t taglen, int ignoretags) 1028 { 1029 rbnode_t* res = NULL; 1030 struct local_zone *result; 1031 struct local_zone key; 1032 int m; 1033 key.node.key = &key; 1034 key.dclass = dclass; 1035 key.name = name; 1036 key.namelen = len; 1037 key.namelabs = labs; 1038 rbtree_find_less_equal(&zones->ztree, &key, &res); 1039 result = (struct local_zone*)res; 1040 /* exact or smaller element (or no element) */ 1041 if(!result || result->dclass != dclass) 1042 return NULL; 1043 /* count number of labels matched */ 1044 (void)dname_lab_cmp(result->name, result->namelabs, key.name, 1045 key.namelabs, &m); 1046 while(result) { /* go up until qname is zone or subdomain of zone */ 1047 if(result->namelabs <= m) 1048 if(ignoretags || !result->taglist || 1049 taglist_intersect(result->taglist, 1050 result->taglen, taglist, taglen)) 1051 break; 1052 result = result->parent; 1053 } 1054 return result; 1055 } 1056 1057 struct local_zone* 1058 local_zones_find(struct local_zones* zones, 1059 uint8_t* name, size_t len, int labs, uint16_t dclass) 1060 { 1061 struct local_zone key; 1062 key.node.key = &key; 1063 key.dclass = dclass; 1064 key.name = name; 1065 key.namelen = len; 1066 key.namelabs = labs; 1067 /* exact */ 1068 return (struct local_zone*)rbtree_search(&zones->ztree, &key); 1069 } 1070 1071 /** print all RRsets in local zone */ 1072 static void 1073 local_zone_out(struct local_zone* z) 1074 { 1075 struct local_data* d; 1076 struct local_rrset* p; 1077 RBTREE_FOR(d, struct local_data*, &z->data) { 1078 for(p = d->rrsets; p; p = p->next) { 1079 log_nametypeclass(0, "rrset", d->name, 1080 ntohs(p->rrset->rk.type), 1081 ntohs(p->rrset->rk.rrset_class)); 1082 } 1083 } 1084 } 1085 1086 void local_zones_print(struct local_zones* zones) 1087 { 1088 struct local_zone* z; 1089 lock_rw_rdlock(&zones->lock); 1090 log_info("number of auth zones %u", (unsigned)zones->ztree.count); 1091 RBTREE_FOR(z, struct local_zone*, &zones->ztree) { 1092 lock_rw_rdlock(&z->lock); 1093 switch(z->type) { 1094 case local_zone_deny: 1095 log_nametypeclass(0, "deny zone", 1096 z->name, 0, z->dclass); 1097 break; 1098 case local_zone_refuse: 1099 log_nametypeclass(0, "refuse zone", 1100 z->name, 0, z->dclass); 1101 break; 1102 case local_zone_redirect: 1103 log_nametypeclass(0, "redirect zone", 1104 z->name, 0, z->dclass); 1105 break; 1106 case local_zone_transparent: 1107 log_nametypeclass(0, "transparent zone", 1108 z->name, 0, z->dclass); 1109 break; 1110 case local_zone_typetransparent: 1111 log_nametypeclass(0, "typetransparent zone", 1112 z->name, 0, z->dclass); 1113 break; 1114 case local_zone_static: 1115 log_nametypeclass(0, "static zone", 1116 z->name, 0, z->dclass); 1117 break; 1118 case local_zone_inform: 1119 log_nametypeclass(0, "inform zone", 1120 z->name, 0, z->dclass); 1121 break; 1122 case local_zone_inform_deny: 1123 log_nametypeclass(0, "inform_deny zone", 1124 z->name, 0, z->dclass); 1125 break; 1126 case local_zone_always_transparent: 1127 log_nametypeclass(0, "always_transparent zone", 1128 z->name, 0, z->dclass); 1129 break; 1130 case local_zone_always_refuse: 1131 log_nametypeclass(0, "always_refuse zone", 1132 z->name, 0, z->dclass); 1133 break; 1134 case local_zone_always_nxdomain: 1135 log_nametypeclass(0, "always_nxdomain zone", 1136 z->name, 0, z->dclass); 1137 break; 1138 default: 1139 log_nametypeclass(0, "badtyped zone", 1140 z->name, 0, z->dclass); 1141 break; 1142 } 1143 local_zone_out(z); 1144 lock_rw_unlock(&z->lock); 1145 } 1146 lock_rw_unlock(&zones->lock); 1147 } 1148 1149 /** encode answer consisting of 1 rrset */ 1150 static int 1151 local_encode(struct query_info* qinfo, struct edns_data* edns, 1152 sldns_buffer* buf, struct regional* temp, 1153 struct ub_packed_rrset_key* rrset, int ansec, int rcode) 1154 { 1155 struct reply_info rep; 1156 uint16_t udpsize; 1157 /* make answer with time=0 for fixed TTL values */ 1158 memset(&rep, 0, sizeof(rep)); 1159 rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode); 1160 rep.qdcount = 1; 1161 if(ansec) 1162 rep.an_numrrsets = 1; 1163 else rep.ns_numrrsets = 1; 1164 rep.rrset_count = 1; 1165 rep.rrsets = &rrset; 1166 udpsize = edns->udp_size; 1167 edns->edns_version = EDNS_ADVERTISED_VERSION; 1168 edns->udp_size = EDNS_ADVERTISED_SIZE; 1169 edns->ext_rcode = 0; 1170 edns->bits &= EDNS_DO; 1171 if(!edns_opt_inplace_reply(edns, temp) || 1172 !reply_info_answer_encode(qinfo, &rep, 1173 *(uint16_t*)sldns_buffer_begin(buf), 1174 sldns_buffer_read_u16_at(buf, 2), 1175 buf, 0, 0, temp, udpsize, edns, 1176 (int)(edns->bits&EDNS_DO), 0)) 1177 error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, 1178 *(uint16_t*)sldns_buffer_begin(buf), 1179 sldns_buffer_read_u16_at(buf, 2), edns); 1180 return 1; 1181 } 1182 1183 /** find local data tag string match for the given type in the list */ 1184 static int 1185 find_tag_datas(struct query_info* qinfo, struct config_strlist* list, 1186 struct ub_packed_rrset_key* r, struct regional* temp, 1187 uint8_t* zname, size_t zlen) 1188 { 1189 struct config_strlist* p; 1190 char buf[65536]; 1191 uint8_t rr[LDNS_RR_BUF_SIZE]; 1192 size_t len; 1193 int res; 1194 struct packed_rrset_data* d; 1195 for(p=list; p; p=p->next) { 1196 len = sizeof(rr); 1197 /* does this element match the type? */ 1198 snprintf(buf, sizeof(buf), ". %s", p->str); 1199 res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, 1200 zname, zlen, NULL, 0); 1201 if(res != 0) 1202 /* parse errors are already checked before, in 1203 * acllist check_data, skip this for robustness */ 1204 continue; 1205 if(len < 1 /* . */ + 8 /* typeclassttl*/ + 2 /*rdatalen*/) 1206 continue; 1207 if(sldns_wirerr_get_type(rr, len, 1) != qinfo->qtype) 1208 continue; 1209 1210 /* do we have entries already? if not setup key */ 1211 if(r->rk.dname == NULL) { 1212 r->entry.key = r; 1213 r->rk.dname = qinfo->qname; 1214 r->rk.dname_len = qinfo->qname_len; 1215 r->rk.type = htons(qinfo->qtype); 1216 r->rk.rrset_class = htons(qinfo->qclass); 1217 r->rk.flags = 0; 1218 d = (struct packed_rrset_data*)regional_alloc_zero( 1219 temp, sizeof(struct packed_rrset_data) 1220 + sizeof(size_t) + sizeof(uint8_t*) + 1221 sizeof(time_t)); 1222 if(!d) return 0; /* out of memory */ 1223 r->entry.data = d; 1224 d->ttl = sldns_wirerr_get_ttl(rr, len, 1); 1225 d->rr_len = (size_t*)((uint8_t*)d + 1226 sizeof(struct packed_rrset_data)); 1227 d->rr_data = (uint8_t**)&(d->rr_len[1]); 1228 d->rr_ttl = (time_t*)&(d->rr_data[1]); 1229 } 1230 d = (struct packed_rrset_data*)r->entry.data; 1231 /* add entry to the data */ 1232 if(d->count != 0) { 1233 size_t* oldlen = d->rr_len; 1234 uint8_t** olddata = d->rr_data; 1235 time_t* oldttl = d->rr_ttl; 1236 /* increase arrays for lookup */ 1237 /* this is of course slow for very many records, 1238 * but most redirects are expected with few records */ 1239 d->rr_len = (size_t*)regional_alloc_zero(temp, 1240 (d->count+1)*sizeof(size_t)); 1241 d->rr_data = (uint8_t**)regional_alloc_zero(temp, 1242 (d->count+1)*sizeof(uint8_t*)); 1243 d->rr_ttl = (time_t*)regional_alloc_zero(temp, 1244 (d->count+1)*sizeof(time_t)); 1245 if(!d->rr_len || !d->rr_data || !d->rr_ttl) 1246 return 0; /* out of memory */ 1247 /* first one was allocated after struct d, but new 1248 * ones get their own array increment alloc, so 1249 * copy old content */ 1250 memmove(d->rr_len, oldlen, d->count*sizeof(size_t)); 1251 memmove(d->rr_data, olddata, d->count*sizeof(uint8_t*)); 1252 memmove(d->rr_ttl, oldttl, d->count*sizeof(time_t)); 1253 } 1254 1255 d->rr_len[d->count] = sldns_wirerr_get_rdatalen(rr, len, 1)+2; 1256 d->rr_ttl[d->count] = sldns_wirerr_get_ttl(rr, len, 1); 1257 d->rr_data[d->count] = regional_alloc_init(temp, 1258 sldns_wirerr_get_rdatawl(rr, len, 1), 1259 d->rr_len[d->count]); 1260 if(!d->rr_data[d->count]) 1261 if(!d) return 0; /* out of memory */ 1262 d->count++; 1263 } 1264 if(r->rk.dname) 1265 return 1; 1266 return 0; 1267 } 1268 1269 /** answer local data match */ 1270 static int 1271 local_data_answer(struct local_zone* z, struct query_info* qinfo, 1272 struct edns_data* edns, sldns_buffer* buf, struct regional* temp, 1273 int labs, struct local_data** ldp, enum localzone_type lz_type, 1274 int tag, struct config_strlist** tag_datas, size_t tag_datas_size, 1275 char** tagname, int num_tags) 1276 { 1277 struct local_data key; 1278 struct local_data* ld; 1279 struct local_rrset* lr; 1280 key.node.key = &key; 1281 key.name = qinfo->qname; 1282 key.namelen = qinfo->qname_len; 1283 key.namelabs = labs; 1284 if(lz_type == local_zone_redirect) { 1285 key.name = z->name; 1286 key.namelen = z->namelen; 1287 key.namelabs = z->namelabs; 1288 if(tag != -1 && (size_t)tag<tag_datas_size && tag_datas[tag]) { 1289 struct ub_packed_rrset_key r; 1290 memset(&r, 0, sizeof(r)); 1291 if(find_tag_datas(qinfo, tag_datas[tag], &r, temp, 1292 z->name, z->namelen)) { 1293 verbose(VERB_ALGO, "redirect with tag data [%d] %s", 1294 tag, (tag<num_tags?tagname[tag]:"null")); 1295 return local_encode(qinfo, edns, buf, temp, 1296 &r, 1, LDNS_RCODE_NOERROR); 1297 } 1298 } 1299 } 1300 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1301 *ldp = ld; 1302 if(!ld) { 1303 return 0; 1304 } 1305 lr = local_data_find_type(ld, qinfo->qtype); 1306 if(!lr) 1307 return 0; 1308 if(lz_type == local_zone_redirect) { 1309 /* convert rrset name to query name; like a wildcard */ 1310 struct ub_packed_rrset_key r = *lr->rrset; 1311 r.rk.dname = qinfo->qname; 1312 r.rk.dname_len = qinfo->qname_len; 1313 return local_encode(qinfo, edns, buf, temp, &r, 1, 1314 LDNS_RCODE_NOERROR); 1315 } 1316 return local_encode(qinfo, edns, buf, temp, lr->rrset, 1, 1317 LDNS_RCODE_NOERROR); 1318 } 1319 1320 /** 1321 * answer in case where no exact match is found 1322 * @param z: zone for query 1323 * @param qinfo: query 1324 * @param edns: edns from query 1325 * @param buf: buffer for answer. 1326 * @param temp: temp region for encoding 1327 * @param ld: local data, if NULL, no such name exists in localdata. 1328 * @param lz_type: type of the local zone 1329 * @return 1 if a reply is to be sent, 0 if not. 1330 */ 1331 static int 1332 lz_zone_answer(struct local_zone* z, struct query_info* qinfo, 1333 struct edns_data* edns, sldns_buffer* buf, struct regional* temp, 1334 struct local_data* ld, enum localzone_type lz_type) 1335 { 1336 if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) { 1337 /** no reply at all, signal caller by clearing buffer. */ 1338 sldns_buffer_clear(buf); 1339 sldns_buffer_flip(buf); 1340 return 1; 1341 } else if(lz_type == local_zone_refuse 1342 || lz_type == local_zone_always_refuse) { 1343 error_encode(buf, (LDNS_RCODE_REFUSED|BIT_AA), qinfo, 1344 *(uint16_t*)sldns_buffer_begin(buf), 1345 sldns_buffer_read_u16_at(buf, 2), edns); 1346 return 1; 1347 } else if(lz_type == local_zone_static || 1348 lz_type == local_zone_redirect || 1349 lz_type == local_zone_always_nxdomain) { 1350 /* for static, reply nodata or nxdomain 1351 * for redirect, reply nodata */ 1352 /* no additional section processing, 1353 * cname, dname or wildcard processing, 1354 * or using closest match for NSEC. 1355 * or using closest match for returning delegation downwards 1356 */ 1357 int rcode = (ld || lz_type == local_zone_redirect)? 1358 LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN; 1359 if(z->soa) 1360 return local_encode(qinfo, edns, buf, temp, 1361 z->soa, 0, rcode); 1362 error_encode(buf, (rcode|BIT_AA), qinfo, 1363 *(uint16_t*)sldns_buffer_begin(buf), 1364 sldns_buffer_read_u16_at(buf, 2), edns); 1365 return 1; 1366 } else if(lz_type == local_zone_typetransparent 1367 || lz_type == local_zone_always_transparent) { 1368 /* no NODATA or NXDOMAINS for this zone type */ 1369 return 0; 1370 } 1371 /* else lz_type == local_zone_transparent */ 1372 1373 /* if the zone is transparent and the name exists, but the type 1374 * does not, then we should make this noerror/nodata */ 1375 if(ld && ld->rrsets) { 1376 int rcode = LDNS_RCODE_NOERROR; 1377 if(z->soa) 1378 return local_encode(qinfo, edns, buf, temp, 1379 z->soa, 0, rcode); 1380 error_encode(buf, (rcode|BIT_AA), qinfo, 1381 *(uint16_t*)sldns_buffer_begin(buf), 1382 sldns_buffer_read_u16_at(buf, 2), edns); 1383 return 1; 1384 } 1385 1386 /* stop here, and resolve further on */ 1387 return 0; 1388 } 1389 1390 /** print log information for an inform zone query */ 1391 static void 1392 lz_inform_print(struct local_zone* z, struct query_info* qinfo, 1393 struct comm_reply* repinfo) 1394 { 1395 char ip[128], txt[512]; 1396 char zname[LDNS_MAX_DOMAINLEN+1]; 1397 uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); 1398 dname_str(z->name, zname); 1399 addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); 1400 snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip, 1401 (unsigned)port); 1402 log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); 1403 } 1404 1405 static enum localzone_type 1406 lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2, 1407 uint8_t *tagactions, size_t tagactionssize, enum localzone_type lzt, 1408 struct comm_reply* repinfo, struct rbtree_t* override_tree, int* tag, 1409 char** tagname, int num_tags) 1410 { 1411 size_t i, j; 1412 uint8_t tagmatch; 1413 struct local_zone_override* lzo; 1414 if(repinfo && override_tree) { 1415 lzo = (struct local_zone_override*)addr_tree_lookup( 1416 override_tree, &repinfo->addr, repinfo->addrlen); 1417 if(lzo && lzo->type) { 1418 verbose(VERB_ALGO, "local zone override to type %s", 1419 local_zone_type2str(lzo->type)); 1420 return lzo->type; 1421 } 1422 } 1423 if(!taglist || !taglist2) 1424 return lzt; 1425 for(i=0; i<taglen && i<taglen2; i++) { 1426 tagmatch = (taglist[i] & taglist2[i]); 1427 for(j=0; j<8 && tagmatch>0; j++) { 1428 if((tagmatch & 0x1)) { 1429 *tag = (int)(i*8+j); 1430 verbose(VERB_ALGO, "matched tag [%d] %s", 1431 *tag, (*tag<num_tags?tagname[*tag]:"null")); 1432 /* does this tag have a tag action? */ 1433 if(i*8+j < tagactionssize && tagactions 1434 && tagactions[i*8+j] != 0) { 1435 verbose(VERB_ALGO, "tag action [%d] %s to type %s", 1436 *tag, (*tag<num_tags?tagname[*tag]:"null"), 1437 local_zone_type2str( 1438 (enum localzone_type) 1439 tagactions[i*8+j])); 1440 return (enum localzone_type)tagactions[i*8+j]; 1441 } 1442 return lzt; 1443 } 1444 tagmatch >>= 1; 1445 } 1446 } 1447 return lzt; 1448 } 1449 1450 int 1451 local_zones_answer(struct local_zones* zones, struct query_info* qinfo, 1452 struct edns_data* edns, sldns_buffer* buf, struct regional* temp, 1453 struct comm_reply* repinfo, uint8_t* taglist, size_t taglen, 1454 uint8_t* tagactions, size_t tagactionssize, 1455 struct config_strlist** tag_datas, size_t tag_datas_size, 1456 char** tagname, int num_tags) 1457 { 1458 /* see if query is covered by a zone, 1459 * if so: - try to match (exact) local data 1460 * - look at zone type for negative response. */ 1461 int labs = dname_count_labels(qinfo->qname); 1462 struct local_data* ld = NULL; 1463 struct local_zone* z; 1464 enum localzone_type lzt; 1465 int r, tag = -1; 1466 lock_rw_rdlock(&zones->lock); 1467 z = local_zones_tags_lookup(zones, qinfo->qname, 1468 qinfo->qname_len, labs, qinfo->qclass, taglist, taglen, 0); 1469 if(!z) { 1470 lock_rw_unlock(&zones->lock); 1471 return 0; 1472 } 1473 lock_rw_rdlock(&z->lock); 1474 lock_rw_unlock(&zones->lock); 1475 1476 lzt = lz_type(taglist, taglen, z->taglist, z->taglen, tagactions, 1477 tagactionssize, z->type, repinfo, z->override_tree, &tag, 1478 tagname, num_tags); 1479 1480 if((lzt == local_zone_inform || lzt == local_zone_inform_deny) 1481 && repinfo) 1482 lz_inform_print(z, qinfo, repinfo); 1483 1484 if(lzt != local_zone_always_refuse && lzt != local_zone_always_transparent 1485 && lzt != local_zone_always_nxdomain 1486 && local_data_answer(z, qinfo, edns, buf, temp, labs, &ld, lzt, 1487 tag, tag_datas, tag_datas_size, tagname, num_tags)) { 1488 lock_rw_unlock(&z->lock); 1489 return 1; 1490 } 1491 r = lz_zone_answer(z, qinfo, edns, buf, temp, ld, lzt); 1492 lock_rw_unlock(&z->lock); 1493 return r; 1494 } 1495 1496 const char* local_zone_type2str(enum localzone_type t) 1497 { 1498 switch(t) { 1499 case local_zone_deny: return "deny"; 1500 case local_zone_refuse: return "refuse"; 1501 case local_zone_redirect: return "redirect"; 1502 case local_zone_transparent: return "transparent"; 1503 case local_zone_typetransparent: return "typetransparent"; 1504 case local_zone_static: return "static"; 1505 case local_zone_nodefault: return "nodefault"; 1506 case local_zone_inform: return "inform"; 1507 case local_zone_inform_deny: return "inform_deny"; 1508 case local_zone_always_transparent: return "always_transparent"; 1509 case local_zone_always_refuse: return "always_refuse"; 1510 case local_zone_always_nxdomain: return "always_nxdomain"; 1511 } 1512 return "badtyped"; 1513 } 1514 1515 int local_zone_str2type(const char* type, enum localzone_type* t) 1516 { 1517 if(strcmp(type, "deny") == 0) 1518 *t = local_zone_deny; 1519 else if(strcmp(type, "refuse") == 0) 1520 *t = local_zone_refuse; 1521 else if(strcmp(type, "static") == 0) 1522 *t = local_zone_static; 1523 else if(strcmp(type, "transparent") == 0) 1524 *t = local_zone_transparent; 1525 else if(strcmp(type, "typetransparent") == 0) 1526 *t = local_zone_typetransparent; 1527 else if(strcmp(type, "redirect") == 0) 1528 *t = local_zone_redirect; 1529 else if(strcmp(type, "inform") == 0) 1530 *t = local_zone_inform; 1531 else if(strcmp(type, "inform_deny") == 0) 1532 *t = local_zone_inform_deny; 1533 else if(strcmp(type, "always_transparent") == 0) 1534 *t = local_zone_always_transparent; 1535 else if(strcmp(type, "always_refuse") == 0) 1536 *t = local_zone_always_refuse; 1537 else if(strcmp(type, "always_nxdomain") == 0) 1538 *t = local_zone_always_nxdomain; 1539 else return 0; 1540 return 1; 1541 } 1542 1543 /** iterate over the kiddies of the given name and set their parent ptr */ 1544 static void 1545 set_kiddo_parents(struct local_zone* z, struct local_zone* match, 1546 struct local_zone* newp) 1547 { 1548 /* both zones and z are locked already */ 1549 /* in the sorted rbtree, the kiddies of z are located after z */ 1550 /* z must be present in the tree */ 1551 struct local_zone* p = z; 1552 p = (struct local_zone*)rbtree_next(&p->node); 1553 while(p!=(struct local_zone*)RBTREE_NULL && 1554 p->dclass == z->dclass && dname_strict_subdomain(p->name, 1555 p->namelabs, z->name, z->namelabs)) { 1556 /* update parent ptr */ 1557 /* only when matches with existing parent pointer, so that 1558 * deeper child structures are not touched, i.e. 1559 * update of x, and a.x, b.x, f.b.x, g.b.x, c.x, y 1560 * gets to update a.x, b.x and c.x */ 1561 lock_rw_wrlock(&p->lock); 1562 if(p->parent == match) 1563 p->parent = newp; 1564 lock_rw_unlock(&p->lock); 1565 p = (struct local_zone*)rbtree_next(&p->node); 1566 } 1567 } 1568 1569 struct local_zone* local_zones_add_zone(struct local_zones* zones, 1570 uint8_t* name, size_t len, int labs, uint16_t dclass, 1571 enum localzone_type tp) 1572 { 1573 /* create */ 1574 struct local_zone* z = local_zone_create(name, len, labs, tp, dclass); 1575 if(!z) { 1576 free(name); 1577 return NULL; 1578 } 1579 lock_rw_wrlock(&z->lock); 1580 1581 /* find the closest parent */ 1582 z->parent = local_zones_find(zones, name, len, labs, dclass); 1583 1584 /* insert into the tree */ 1585 if(!rbtree_insert(&zones->ztree, &z->node)) { 1586 /* duplicate entry! */ 1587 lock_rw_unlock(&z->lock); 1588 local_zone_delete(z); 1589 log_err("internal: duplicate entry in local_zones_add_zone"); 1590 return NULL; 1591 } 1592 1593 /* set parent pointers right */ 1594 set_kiddo_parents(z, z->parent, z); 1595 1596 lock_rw_unlock(&z->lock); 1597 return z; 1598 } 1599 1600 void local_zones_del_zone(struct local_zones* zones, struct local_zone* z) 1601 { 1602 /* fix up parents in tree */ 1603 lock_rw_wrlock(&z->lock); 1604 set_kiddo_parents(z, z, z->parent); 1605 1606 /* remove from tree */ 1607 (void)rbtree_delete(&zones->ztree, z); 1608 1609 /* delete the zone */ 1610 lock_rw_unlock(&z->lock); 1611 local_zone_delete(z); 1612 } 1613 1614 int 1615 local_zones_add_RR(struct local_zones* zones, const char* rr) 1616 { 1617 uint8_t* rr_name; 1618 uint16_t rr_class; 1619 size_t len; 1620 int labs; 1621 struct local_zone* z; 1622 int r; 1623 if(!get_rr_nameclass(rr, &rr_name, &rr_class)) { 1624 return 0; 1625 } 1626 labs = dname_count_size_labels(rr_name, &len); 1627 /* could first try readlock then get writelock if zone does not exist, 1628 * but we do not add enough RRs (from multiple threads) to optimize */ 1629 lock_rw_wrlock(&zones->lock); 1630 z = local_zones_lookup(zones, rr_name, len, labs, rr_class); 1631 if(!z) { 1632 z = local_zones_add_zone(zones, rr_name, len, labs, rr_class, 1633 local_zone_transparent); 1634 if(!z) { 1635 lock_rw_unlock(&zones->lock); 1636 return 0; 1637 } 1638 } else { 1639 free(rr_name); 1640 } 1641 lock_rw_wrlock(&z->lock); 1642 lock_rw_unlock(&zones->lock); 1643 r = lz_enter_rr_into_zone(z, rr); 1644 lock_rw_unlock(&z->lock); 1645 return r; 1646 } 1647 1648 /** returns true if the node is terminal so no deeper domain names exist */ 1649 static int 1650 is_terminal(struct local_data* d) 1651 { 1652 /* for empty nonterminals, the deeper domain names are sorted 1653 * right after them, so simply check the next name in the tree 1654 */ 1655 struct local_data* n = (struct local_data*)rbtree_next(&d->node); 1656 if(n == (struct local_data*)RBTREE_NULL) 1657 return 1; /* last in tree, no deeper node */ 1658 if(dname_strict_subdomain(n->name, n->namelabs, d->name, d->namelabs)) 1659 return 0; /* there is a deeper node */ 1660 return 1; 1661 } 1662 1663 /** delete empty terminals from tree when final data is deleted */ 1664 static void 1665 del_empty_term(struct local_zone* z, struct local_data* d, 1666 uint8_t* name, size_t len, int labs) 1667 { 1668 while(d && d->rrsets == NULL && is_terminal(d)) { 1669 /* is this empty nonterminal? delete */ 1670 /* note, no memory recycling in zone region */ 1671 (void)rbtree_delete(&z->data, d); 1672 1673 /* go up and to the next label */ 1674 if(dname_is_root(name)) 1675 return; 1676 dname_remove_label(&name, &len); 1677 labs--; 1678 d = lz_find_node(z, name, len, labs); 1679 } 1680 } 1681 1682 void local_zones_del_data(struct local_zones* zones, 1683 uint8_t* name, size_t len, int labs, uint16_t dclass) 1684 { 1685 /* find zone */ 1686 struct local_zone* z; 1687 struct local_data* d; 1688 lock_rw_rdlock(&zones->lock); 1689 z = local_zones_lookup(zones, name, len, labs, dclass); 1690 if(!z) { 1691 /* no such zone, we're done */ 1692 lock_rw_unlock(&zones->lock); 1693 return; 1694 } 1695 lock_rw_wrlock(&z->lock); 1696 lock_rw_unlock(&zones->lock); 1697 1698 /* find the domain */ 1699 d = lz_find_node(z, name, len, labs); 1700 if(d) { 1701 /* no memory recycling for zone deletions ... */ 1702 d->rrsets = NULL; 1703 /* did we delete the soa record ? */ 1704 if(query_dname_compare(d->name, z->name) == 0) 1705 z->soa = NULL; 1706 1707 /* cleanup the empty nonterminals for this name */ 1708 del_empty_term(z, d, name, len, labs); 1709 } 1710 1711 lock_rw_unlock(&z->lock); 1712 } 1713