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 "util/regional.h" 45 #include "util/config_file.h" 46 #include "util/data/dname.h" 47 #include "util/data/packed_rrset.h" 48 #include "util/data/msgencode.h" 49 #include "util/net_help.h" 50 #include "util/netevent.h" 51 #include "util/data/msgreply.h" 52 #include "util/data/msgparse.h" 53 #include "util/as112.h" 54 55 /* maximum RRs in an RRset, to cap possible 'endless' list RRs. 56 * with 16 bytes for an A record, a 64K packet has about 4000 max */ 57 #define LOCALZONE_RRSET_COUNT_MAX 4096 58 59 struct local_zones* 60 local_zones_create(void) 61 { 62 struct local_zones* zones = (struct local_zones*)calloc(1, 63 sizeof(*zones)); 64 if(!zones) 65 return NULL; 66 rbtree_init(&zones->ztree, &local_zone_cmp); 67 lock_rw_init(&zones->lock); 68 lock_protect(&zones->lock, &zones->ztree, sizeof(zones->ztree)); 69 /* also lock protects the rbnode's in struct local_zone */ 70 return zones; 71 } 72 73 /** helper traverse to delete zones */ 74 static void 75 lzdel(rbnode_type* n, void* ATTR_UNUSED(arg)) 76 { 77 struct local_zone* z = (struct local_zone*)n->key; 78 local_zone_delete(z); 79 } 80 81 void 82 local_zones_delete(struct local_zones* zones) 83 { 84 if(!zones) 85 return; 86 lock_rw_destroy(&zones->lock); 87 /* walk through zones and delete them all */ 88 traverse_postorder(&zones->ztree, lzdel, NULL); 89 free(zones); 90 } 91 92 void 93 local_zone_delete(struct local_zone* z) 94 { 95 if(!z) 96 return; 97 lock_rw_destroy(&z->lock); 98 regional_destroy(z->region); 99 free(z->name); 100 free(z->taglist); 101 free(z); 102 } 103 104 int 105 local_zone_cmp(const void* z1, const void* z2) 106 { 107 /* first sort on class, so that hierarchy can be maintained within 108 * a class */ 109 struct local_zone* a = (struct local_zone*)z1; 110 struct local_zone* b = (struct local_zone*)z2; 111 int m; 112 if(a->dclass != b->dclass) { 113 if(a->dclass < b->dclass) 114 return -1; 115 return 1; 116 } 117 return dname_lab_cmp(a->name, a->namelabs, b->name, b->namelabs, &m); 118 } 119 120 int 121 local_data_cmp(const void* d1, const void* d2) 122 { 123 struct local_data* a = (struct local_data*)d1; 124 struct local_data* b = (struct local_data*)d2; 125 int m; 126 return dname_canon_lab_cmp(a->name, a->namelabs, b->name, 127 b->namelabs, &m); 128 } 129 130 /* form wireformat from text format domain name */ 131 int 132 parse_dname(const char* str, uint8_t** res, size_t* len, int* labs) 133 { 134 *res = sldns_str2wire_dname(str, len); 135 *labs = 0; 136 if(!*res) { 137 log_err("cannot parse name %s", str); 138 return 0; 139 } 140 *labs = dname_count_size_labels(*res, len); 141 return 1; 142 } 143 144 /** create a new localzone */ 145 static struct local_zone* 146 local_zone_create(uint8_t* nm, size_t len, int labs, 147 enum localzone_type t, uint16_t dclass) 148 { 149 struct local_zone* z = (struct local_zone*)calloc(1, sizeof(*z)); 150 if(!z) { 151 return NULL; 152 } 153 z->node.key = z; 154 z->dclass = dclass; 155 z->type = t; 156 z->name = nm; 157 z->namelen = len; 158 z->namelabs = labs; 159 lock_rw_init(&z->lock); 160 z->region = regional_create_nochunk(sizeof(struct regional)); 161 if(!z->region) { 162 free(z); 163 return NULL; 164 } 165 rbtree_init(&z->data, &local_data_cmp); 166 lock_protect(&z->lock, &z->parent, sizeof(*z)-sizeof(rbnode_type)); 167 /* also the zones->lock protects node, parent, name*, class */ 168 return z; 169 } 170 171 /** enter a new zone with allocated dname returns with WRlock */ 172 static struct local_zone* 173 lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len, 174 int labs, enum localzone_type t, uint16_t c) 175 { 176 struct local_zone* z = local_zone_create(nm, len, labs, t, c); 177 if(!z) { 178 free(nm); 179 log_err("out of memory"); 180 return NULL; 181 } 182 183 /* add to rbtree */ 184 lock_rw_wrlock(&zones->lock); 185 lock_rw_wrlock(&z->lock); 186 if(!rbtree_insert(&zones->ztree, &z->node)) { 187 struct local_zone* oldz; 188 char str[256]; 189 dname_str(nm, str); 190 log_warn("duplicate local-zone %s", str); 191 lock_rw_unlock(&z->lock); 192 /* save zone name locally before deallocation, 193 * otherwise, nm is gone if we zone_delete now. */ 194 oldz = z; 195 /* find the correct zone, so not an error for duplicate */ 196 z = local_zones_find(zones, nm, len, labs, c); 197 lock_rw_wrlock(&z->lock); 198 lock_rw_unlock(&zones->lock); 199 local_zone_delete(oldz); 200 return z; 201 } 202 lock_rw_unlock(&zones->lock); 203 return z; 204 } 205 206 /** enter a new zone */ 207 static struct local_zone* 208 lz_enter_zone(struct local_zones* zones, const char* name, const char* type, 209 uint16_t dclass) 210 { 211 struct local_zone* z; 212 enum localzone_type t; 213 uint8_t* nm; 214 size_t len; 215 int labs; 216 if(!parse_dname(name, &nm, &len, &labs)) { 217 log_err("bad zone name %s %s", name, type); 218 return NULL; 219 } 220 if(!local_zone_str2type(type, &t)) { 221 log_err("bad lz_enter_zone type %s %s", name, type); 222 free(nm); 223 return NULL; 224 } 225 if(!(z=lz_enter_zone_dname(zones, nm, len, labs, t, dclass))) { 226 log_err("could not enter zone %s %s", name, type); 227 return NULL; 228 } 229 return z; 230 } 231 232 int 233 rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type, 234 uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len, 235 uint8_t** rdata, size_t* rdata_len) 236 { 237 size_t dname_len = 0; 238 int e = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600, 239 NULL, 0, NULL, 0); 240 if(e) { 241 log_err("error parsing local-data at %d: '%s': %s", 242 LDNS_WIREPARSE_OFFSET(e), str, 243 sldns_get_errorstr_parse(e)); 244 return 0; 245 } 246 *nm = memdup(rr, dname_len); 247 if(!*nm) { 248 log_err("out of memory"); 249 return 0; 250 } 251 *dclass = sldns_wirerr_get_class(rr, len, dname_len); 252 *type = sldns_wirerr_get_type(rr, len, dname_len); 253 *ttl = (time_t)sldns_wirerr_get_ttl(rr, len, dname_len); 254 *rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len); 255 *rdata_len = sldns_wirerr_get_rdatalen(rr, len, dname_len)+2; 256 return 1; 257 } 258 259 /** return name and class of rr; parses string */ 260 static int 261 get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass, 262 uint16_t* dtype) 263 { 264 uint8_t rr[LDNS_RR_BUF_SIZE]; 265 size_t len = sizeof(rr), dname_len = 0; 266 int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600, 267 NULL, 0, NULL, 0); 268 if(s != 0) { 269 log_err("error parsing local-data at %d '%s': %s", 270 LDNS_WIREPARSE_OFFSET(s), str, 271 sldns_get_errorstr_parse(s)); 272 return 0; 273 } 274 *nm = memdup(rr, dname_len); 275 *dclass = sldns_wirerr_get_class(rr, len, dname_len); 276 *dtype = sldns_wirerr_get_type(rr, len, dname_len); 277 if(!*nm) { 278 log_err("out of memory"); 279 return 0; 280 } 281 return 1; 282 } 283 284 /** 285 * Find an rrset in local data structure. 286 * @param data: local data domain name structure. 287 * @param type: type to look for (host order). 288 * @param alias_ok: 1 if matching a non-exact, alias type such as CNAME is 289 * allowed. otherwise 0. 290 * @return rrset pointer or NULL if not found. 291 */ 292 static struct local_rrset* 293 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok) 294 { 295 struct local_rrset* p; 296 type = htons(type); 297 for(p = data->rrsets; p; p = p->next) { 298 if(p->rrset->rk.type == type) 299 return p; 300 if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) 301 return p; 302 } 303 return NULL; 304 } 305 306 /** check for RR duplicates */ 307 static int 308 rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len) 309 { 310 size_t i; 311 for(i=0; i<pd->count; i++) { 312 if(pd->rr_len[i] == rdata_len && 313 memcmp(pd->rr_data[i], rdata, rdata_len) == 0) 314 return 1; 315 } 316 return 0; 317 } 318 319 /** new local_rrset */ 320 static struct local_rrset* 321 new_local_rrset(struct regional* region, struct local_data* node, 322 uint16_t rrtype, uint16_t rrclass) 323 { 324 struct packed_rrset_data* pd; 325 struct local_rrset* rrset = (struct local_rrset*) 326 regional_alloc_zero(region, sizeof(*rrset)); 327 if(!rrset) { 328 log_err("out of memory"); 329 return NULL; 330 } 331 rrset->next = node->rrsets; 332 node->rrsets = rrset; 333 rrset->rrset = (struct ub_packed_rrset_key*) 334 regional_alloc_zero(region, sizeof(*rrset->rrset)); 335 if(!rrset->rrset) { 336 log_err("out of memory"); 337 return NULL; 338 } 339 rrset->rrset->entry.key = rrset->rrset; 340 pd = (struct packed_rrset_data*)regional_alloc_zero(region, 341 sizeof(*pd)); 342 if(!pd) { 343 log_err("out of memory"); 344 return NULL; 345 } 346 pd->trust = rrset_trust_prim_noglue; 347 pd->security = sec_status_insecure; 348 rrset->rrset->entry.data = pd; 349 rrset->rrset->rk.dname = node->name; 350 rrset->rrset->rk.dname_len = node->namelen; 351 rrset->rrset->rk.type = htons(rrtype); 352 rrset->rrset->rk.rrset_class = htons(rrclass); 353 return rrset; 354 } 355 356 /** insert RR into RRset data structure; Wastes a couple of bytes */ 357 int 358 rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd, 359 uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr) 360 { 361 size_t* oldlen = pd->rr_len; 362 time_t* oldttl = pd->rr_ttl; 363 uint8_t** olddata = pd->rr_data; 364 365 /* add RR to rrset */ 366 if(pd->count > LOCALZONE_RRSET_COUNT_MAX) { 367 log_warn("RRset '%s' has more than %d records, record ignored", 368 rrstr, LOCALZONE_RRSET_COUNT_MAX); 369 return 1; 370 } 371 pd->count++; 372 pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count); 373 pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count); 374 pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count); 375 if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) { 376 log_err("out of memory"); 377 return 0; 378 } 379 if(pd->count > 1) { 380 memcpy(pd->rr_len+1, oldlen, 381 sizeof(*pd->rr_len)*(pd->count-1)); 382 memcpy(pd->rr_ttl+1, oldttl, 383 sizeof(*pd->rr_ttl)*(pd->count-1)); 384 memcpy(pd->rr_data+1, olddata, 385 sizeof(*pd->rr_data)*(pd->count-1)); 386 } 387 pd->rr_len[0] = rdata_len; 388 pd->rr_ttl[0] = ttl; 389 pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len); 390 if(!pd->rr_data[0]) { 391 log_err("out of memory"); 392 return 0; 393 } 394 return 1; 395 } 396 397 /** Delete RR from local-zone RRset, wastes memory as the deleted RRs cannot be 398 * free'd (regionally alloc'd) */ 399 int 400 local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index) 401 { 402 log_assert(pd->count > 0); 403 if(index >= pd->count) { 404 log_warn("Trying to remove RR with out of bound index"); 405 return 0; 406 } 407 if(index + 1 < pd->count) { 408 /* not removing last element */ 409 size_t nexti = index + 1; 410 size_t num = pd->count - nexti; 411 memmove(pd->rr_len+index, pd->rr_len+nexti, sizeof(*pd->rr_len)*num); 412 memmove(pd->rr_ttl+index, pd->rr_ttl+nexti, sizeof(*pd->rr_ttl)*num); 413 memmove(pd->rr_data+index, pd->rr_data+nexti, sizeof(*pd->rr_data)*num); 414 } 415 pd->count--; 416 return 1; 417 } 418 419 struct local_data* 420 local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs) 421 { 422 struct local_data key; 423 key.node.key = &key; 424 key.name = nm; 425 key.namelen = nmlen; 426 key.namelabs = nmlabs; 427 return (struct local_data*)rbtree_search(&z->data, &key.node); 428 } 429 430 /** find a node, create it if not and all its empty nonterminal parents */ 431 static int 432 lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen, 433 int nmlabs, struct local_data** res) 434 { 435 struct local_data* ld = local_zone_find_data(z, nm, nmlen, nmlabs); 436 if(!ld) { 437 /* create a domain name to store rr. */ 438 ld = (struct local_data*)regional_alloc_zero(z->region, 439 sizeof(*ld)); 440 if(!ld) { 441 log_err("out of memory adding local data"); 442 return 0; 443 } 444 ld->node.key = ld; 445 ld->name = regional_alloc_init(z->region, nm, nmlen); 446 if(!ld->name) { 447 log_err("out of memory"); 448 return 0; 449 } 450 ld->namelen = nmlen; 451 ld->namelabs = nmlabs; 452 if(!rbtree_insert(&z->data, &ld->node)) { 453 log_assert(0); /* duplicate name */ 454 } 455 /* see if empty nonterminals need to be created */ 456 if(nmlabs > z->namelabs) { 457 dname_remove_label(&nm, &nmlen); 458 if(!lz_find_create_node(z, nm, nmlen, nmlabs-1, res)) 459 return 0; 460 } 461 } 462 *res = ld; 463 return 1; 464 } 465 466 /* Mark the SOA record for the zone. This only marks the SOA rrset; the data 467 * for the RR is entered later on local_zone_enter_rr() as with the other 468 * records. An artifical soa_negative record with a modified TTL (minimum of 469 * the TTL and the SOA.MINIMUM) is also created and marked for usage with 470 * negative answers and to avoid allocations during those answers. */ 471 static int 472 lz_mark_soa_for_zone(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset, 473 uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr) 474 { 475 struct packed_rrset_data* pd = (struct packed_rrset_data*) 476 regional_alloc_zero(z->region, sizeof(*pd)); 477 struct ub_packed_rrset_key* rrset_negative = (struct ub_packed_rrset_key*) 478 regional_alloc_zero(z->region, sizeof(*rrset_negative)); 479 time_t minimum; 480 if(!rrset_negative||!pd) { 481 log_err("out of memory"); 482 return 0; 483 } 484 /* Mark the original SOA record and then continue with the negative one. */ 485 z->soa = soa_rrset; 486 rrset_negative->entry.key = rrset_negative; 487 pd->trust = rrset_trust_prim_noglue; 488 pd->security = sec_status_insecure; 489 rrset_negative->entry.data = pd; 490 rrset_negative->rk.dname = soa_rrset->rk.dname; 491 rrset_negative->rk.dname_len = soa_rrset->rk.dname_len; 492 rrset_negative->rk.type = soa_rrset->rk.type; 493 rrset_negative->rk.rrset_class = soa_rrset->rk.rrset_class; 494 if(!rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr)) 495 return 0; 496 /* last 4 bytes are minimum ttl in network format */ 497 if(pd->count == 0 || pd->rr_len[0] < 2+4) 498 return 0; 499 minimum = (time_t)sldns_read_uint32(pd->rr_data[0]+(pd->rr_len[0]-4)); 500 minimum = ttl<minimum?ttl:minimum; 501 pd->ttl = minimum; 502 pd->rr_ttl[0] = minimum; 503 504 z->soa_negative = rrset_negative; 505 return 1; 506 } 507 508 int 509 local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen, 510 int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl, 511 uint8_t* rdata, size_t rdata_len, const char* rrstr) 512 { 513 struct local_data* node; 514 struct local_rrset* rrset; 515 struct packed_rrset_data* pd; 516 517 if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) { 518 return 0; 519 } 520 log_assert(node); 521 522 /* Reject it if we would end up having CNAME and other data (including 523 * another CNAME) for a redirect zone. */ 524 if((z->type == local_zone_redirect || 525 z->type == local_zone_inform_redirect) && node->rrsets) { 526 const char* othertype = NULL; 527 if (rrtype == LDNS_RR_TYPE_CNAME) 528 othertype = "other"; 529 else if (node->rrsets->rrset->rk.type == 530 htons(LDNS_RR_TYPE_CNAME)) { 531 othertype = "CNAME"; 532 } 533 if(othertype) { 534 log_err("local-data '%s' in redirect zone must not " 535 "coexist with %s local-data", rrstr, othertype); 536 return 0; 537 } 538 } 539 rrset = local_data_find_type(node, rrtype, 0); 540 if(!rrset) { 541 rrset = new_local_rrset(z->region, node, rrtype, rrclass); 542 if(!rrset) 543 return 0; 544 if(query_dname_compare(node->name, z->name) == 0) { 545 if(rrtype == LDNS_RR_TYPE_NSEC) 546 rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX; 547 if(rrtype == LDNS_RR_TYPE_SOA && 548 !lz_mark_soa_for_zone(z, rrset->rrset, rdata, rdata_len, ttl, 549 rrstr)) 550 return 0; 551 } 552 } 553 pd = (struct packed_rrset_data*)rrset->rrset->entry.data; 554 log_assert(rrset && pd); 555 556 /* check for duplicate RR */ 557 if(rr_is_duplicate(pd, rdata, rdata_len)) { 558 verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr); 559 return 1; 560 } 561 return rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr); 562 } 563 564 /** enter data RR into auth zone */ 565 static int 566 lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) 567 { 568 uint8_t* nm; 569 size_t nmlen; 570 int nmlabs, ret; 571 uint16_t rrtype = 0, rrclass = 0; 572 time_t ttl = 0; 573 uint8_t rr[LDNS_RR_BUF_SIZE]; 574 uint8_t* rdata; 575 size_t rdata_len; 576 if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, 577 sizeof(rr), &rdata, &rdata_len)) { 578 log_err("bad local-data: %s", rrstr); 579 return 0; 580 } 581 log_assert(z->dclass == rrclass); 582 if((z->type == local_zone_redirect || 583 z->type == local_zone_inform_redirect) && 584 query_dname_compare(z->name, nm) != 0) { 585 log_err("local-data in redirect zone must reside at top of zone" 586 ", not at %s", rrstr); 587 free(nm); 588 return 0; 589 } 590 nmlabs = dname_count_size_labels(nm, &nmlen); 591 ret = local_zone_enter_rr(z, nm, nmlen, nmlabs, rrtype, rrclass, ttl, 592 rdata, rdata_len, rrstr); 593 free(nm); 594 return ret; 595 } 596 597 /** enter a data RR into auth data; a zone for it must exist */ 598 static int 599 lz_enter_rr_str(struct local_zones* zones, const char* rr) 600 { 601 uint8_t* rr_name; 602 uint16_t rr_class, rr_type; 603 size_t len; 604 int labs; 605 struct local_zone* z; 606 int r; 607 if(!get_rr_nameclass(rr, &rr_name, &rr_class, &rr_type)) { 608 log_err("bad rr %s", rr); 609 return 0; 610 } 611 labs = dname_count_size_labels(rr_name, &len); 612 lock_rw_rdlock(&zones->lock); 613 z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type); 614 if(!z) { 615 lock_rw_unlock(&zones->lock); 616 fatal_exit("internal error: no zone for rr %s", rr); 617 } 618 lock_rw_wrlock(&z->lock); 619 lock_rw_unlock(&zones->lock); 620 free(rr_name); 621 r = lz_enter_rr_into_zone(z, rr); 622 lock_rw_unlock(&z->lock); 623 return r; 624 } 625 626 /** enter tagstring into zone */ 627 static int 628 lz_enter_zone_tag(struct local_zones* zones, char* zname, uint8_t* list, 629 size_t len, uint16_t rr_class) 630 { 631 uint8_t dname[LDNS_MAX_DOMAINLEN+1]; 632 size_t dname_len = sizeof(dname); 633 int dname_labs, r = 0; 634 struct local_zone* z; 635 636 if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) { 637 log_err("cannot parse zone name in local-zone-tag: %s", zname); 638 return 0; 639 } 640 dname_labs = dname_count_labels(dname); 641 642 lock_rw_rdlock(&zones->lock); 643 z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class); 644 if(!z) { 645 lock_rw_unlock(&zones->lock); 646 log_err("no local-zone for tag %s", zname); 647 return 0; 648 } 649 lock_rw_wrlock(&z->lock); 650 lock_rw_unlock(&zones->lock); 651 free(z->taglist); 652 z->taglist = memdup(list, len); 653 z->taglen = len; 654 if(z->taglist) 655 r = 1; 656 lock_rw_unlock(&z->lock); 657 return r; 658 } 659 660 /** enter override into zone */ 661 static int 662 lz_enter_override(struct local_zones* zones, char* zname, char* netblock, 663 char* type, uint16_t rr_class) 664 { 665 uint8_t dname[LDNS_MAX_DOMAINLEN+1]; 666 size_t dname_len = sizeof(dname); 667 int dname_labs; 668 struct sockaddr_storage addr; 669 int net; 670 socklen_t addrlen; 671 struct local_zone* z; 672 enum localzone_type t; 673 674 /* parse zone name */ 675 if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) { 676 log_err("cannot parse zone name in local-zone-override: %s %s", 677 zname, netblock); 678 return 0; 679 } 680 dname_labs = dname_count_labels(dname); 681 682 /* parse netblock */ 683 if(!netblockstrtoaddr(netblock, UNBOUND_DNS_PORT, &addr, &addrlen, 684 &net)) { 685 log_err("cannot parse netblock in local-zone-override: %s %s", 686 zname, netblock); 687 return 0; 688 } 689 690 /* parse zone type */ 691 if(!local_zone_str2type(type, &t)) { 692 log_err("cannot parse type in local-zone-override: %s %s %s", 693 zname, netblock, type); 694 return 0; 695 } 696 697 /* find localzone entry */ 698 lock_rw_rdlock(&zones->lock); 699 z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class); 700 if(!z) { 701 lock_rw_unlock(&zones->lock); 702 log_err("no local-zone for local-zone-override %s", zname); 703 return 0; 704 } 705 lock_rw_wrlock(&z->lock); 706 lock_rw_unlock(&zones->lock); 707 708 /* create netblock addr_tree if not present yet */ 709 if(!z->override_tree) { 710 z->override_tree = (struct rbtree_type*)regional_alloc_zero( 711 z->region, sizeof(*z->override_tree)); 712 if(!z->override_tree) { 713 lock_rw_unlock(&z->lock); 714 log_err("out of memory"); 715 return 0; 716 } 717 addr_tree_init(z->override_tree); 718 } 719 /* add new elem to tree */ 720 if(z->override_tree) { 721 struct local_zone_override* n; 722 n = (struct local_zone_override*)regional_alloc_zero( 723 z->region, sizeof(*n)); 724 if(!n) { 725 lock_rw_unlock(&z->lock); 726 log_err("out of memory"); 727 return 0; 728 } 729 n->type = t; 730 if(!addr_tree_insert(z->override_tree, 731 (struct addr_tree_node*)n, &addr, addrlen, net)) { 732 lock_rw_unlock(&z->lock); 733 log_err("duplicate local-zone-override %s %s", 734 zname, netblock); 735 return 1; 736 } 737 } 738 739 lock_rw_unlock(&z->lock); 740 return 1; 741 } 742 743 /** parse local-zone: statements */ 744 static int 745 lz_enter_zones(struct local_zones* zones, struct config_file* cfg) 746 { 747 struct config_str2list* p; 748 struct local_zone* z; 749 for(p = cfg->local_zones; p; p = p->next) { 750 if(!(z=lz_enter_zone(zones, p->str, p->str2, 751 LDNS_RR_CLASS_IN))) 752 return 0; 753 lock_rw_unlock(&z->lock); 754 } 755 return 1; 756 } 757 758 /** lookup a zone in rbtree; exact match only; SLOW due to parse */ 759 static int 760 lz_exists(struct local_zones* zones, const char* name) 761 { 762 struct local_zone z; 763 z.node.key = &z; 764 z.dclass = LDNS_RR_CLASS_IN; 765 if(!parse_dname(name, &z.name, &z.namelen, &z.namelabs)) { 766 log_err("bad name %s", name); 767 return 0; 768 } 769 lock_rw_rdlock(&zones->lock); 770 if(rbtree_search(&zones->ztree, &z.node)) { 771 lock_rw_unlock(&zones->lock); 772 free(z.name); 773 return 1; 774 } 775 lock_rw_unlock(&zones->lock); 776 free(z.name); 777 return 0; 778 } 779 780 /** lookup a zone in cfg->nodefault list */ 781 static int 782 lz_nodefault(struct config_file* cfg, const char* name) 783 { 784 struct config_strlist* p; 785 size_t len = strlen(name); 786 if(len == 0) return 0; 787 if(name[len-1] == '.') len--; 788 789 for(p = cfg->local_zones_nodefault; p; p = p->next) { 790 /* compare zone name, lowercase, compare without ending . */ 791 if(strncasecmp(p->str, name, len) == 0 && 792 (strlen(p->str) == len || (strlen(p->str)==len+1 && 793 p->str[len] == '.'))) 794 return 1; 795 } 796 return 0; 797 } 798 799 /** enter (AS112) empty default zone */ 800 static int 801 add_empty_default(struct local_zones* zones, struct config_file* cfg, 802 const char* name) 803 { 804 struct local_zone* z; 805 char str[1024]; /* known long enough */ 806 if(lz_exists(zones, name) || lz_nodefault(cfg, name)) 807 return 1; /* do not enter default content */ 808 if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN))) 809 return 0; 810 snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. " 811 "nobody.invalid. 1 3600 1200 604800 10800", name); 812 if(!lz_enter_rr_into_zone(z, str)) { 813 lock_rw_unlock(&z->lock); 814 return 0; 815 } 816 snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name); 817 if(!lz_enter_rr_into_zone(z, str)) { 818 lock_rw_unlock(&z->lock); 819 return 0; 820 } 821 lock_rw_unlock(&z->lock); 822 return 1; 823 } 824 825 /** enter default zones */ 826 int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg) 827 { 828 struct local_zone* z; 829 const char** zstr; 830 831 /* Do not add any default */ 832 if(cfg->local_zones_disable_default) 833 return 1; 834 835 /* this list of zones is from RFC 6303 and RFC 7686 */ 836 837 /* block localhost level zones first, then onion and later the LAN zones */ 838 839 /* localhost. zone */ 840 if(!lz_exists(zones, "localhost.") && 841 !lz_nodefault(cfg, "localhost.")) { 842 if(!(z=lz_enter_zone(zones, "localhost.", "redirect", 843 LDNS_RR_CLASS_IN)) || 844 !lz_enter_rr_into_zone(z, 845 "localhost. 10800 IN NS localhost.") || 846 !lz_enter_rr_into_zone(z, 847 "localhost. 10800 IN SOA localhost. nobody.invalid. " 848 "1 3600 1200 604800 10800") || 849 !lz_enter_rr_into_zone(z, 850 "localhost. 10800 IN A 127.0.0.1") || 851 !lz_enter_rr_into_zone(z, 852 "localhost. 10800 IN AAAA ::1")) { 853 log_err("out of memory adding default zone"); 854 if(z) { lock_rw_unlock(&z->lock); } 855 return 0; 856 } 857 lock_rw_unlock(&z->lock); 858 } 859 /* reverse ip4 zone */ 860 if(!lz_exists(zones, "127.in-addr.arpa.") && 861 !lz_nodefault(cfg, "127.in-addr.arpa.")) { 862 if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static", 863 LDNS_RR_CLASS_IN)) || 864 !lz_enter_rr_into_zone(z, 865 "127.in-addr.arpa. 10800 IN NS localhost.") || 866 !lz_enter_rr_into_zone(z, 867 "127.in-addr.arpa. 10800 IN SOA localhost. " 868 "nobody.invalid. 1 3600 1200 604800 10800") || 869 !lz_enter_rr_into_zone(z, 870 "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) { 871 log_err("out of memory adding default zone"); 872 if(z) { lock_rw_unlock(&z->lock); } 873 return 0; 874 } 875 lock_rw_unlock(&z->lock); 876 } 877 /* reverse ip6 zone */ 878 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.") && 879 !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.")) { 880 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", 881 LDNS_RR_CLASS_IN)) || 882 !lz_enter_rr_into_zone(z, 883 "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.") || 884 !lz_enter_rr_into_zone(z, 885 "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. " 886 "nobody.invalid. 1 3600 1200 604800 10800") || 887 !lz_enter_rr_into_zone(z, 888 "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.")) { 889 log_err("out of memory adding default zone"); 890 if(z) { lock_rw_unlock(&z->lock); } 891 return 0; 892 } 893 lock_rw_unlock(&z->lock); 894 } 895 /* onion. zone (RFC 7686) */ 896 if(!add_empty_default(zones, cfg, "onion.")) { 897 log_err("out of memory adding default zone"); 898 return 0; 899 } 900 /* test. zone (RFC 6761) */ 901 if(!add_empty_default(zones, cfg, "test.")) { 902 log_err("out of memory adding default zone"); 903 return 0; 904 } 905 /* invalid. zone (RFC 6761) */ 906 if(!add_empty_default(zones, cfg, "invalid.")) { 907 log_err("out of memory adding default zone"); 908 return 0; 909 } 910 /* block AS112 zones, unless asked not to */ 911 if(!cfg->unblock_lan_zones) { 912 for(zstr = as112_zones; *zstr; zstr++) { 913 if(!add_empty_default(zones, cfg, *zstr)) { 914 log_err("out of memory adding default zone"); 915 return 0; 916 } 917 } 918 } 919 return 1; 920 } 921 922 /** parse local-zone-override: statements */ 923 static int 924 lz_enter_overrides(struct local_zones* zones, struct config_file* cfg) 925 { 926 struct config_str3list* p; 927 for(p = cfg->local_zone_overrides; p; p = p->next) { 928 if(!lz_enter_override(zones, p->str, p->str2, p->str3, 929 LDNS_RR_CLASS_IN)) 930 return 0; 931 } 932 return 1; 933 } 934 935 /** setup parent pointers, so that a lookup can be done for closest match */ 936 static void 937 init_parents(struct local_zones* zones) 938 { 939 struct local_zone* node, *prev = NULL, *p; 940 int m; 941 lock_rw_wrlock(&zones->lock); 942 RBTREE_FOR(node, struct local_zone*, &zones->ztree) { 943 lock_rw_wrlock(&node->lock); 944 node->parent = NULL; 945 if(!prev || prev->dclass != node->dclass) { 946 prev = node; 947 lock_rw_unlock(&node->lock); 948 continue; 949 } 950 (void)dname_lab_cmp(prev->name, prev->namelabs, node->name, 951 node->namelabs, &m); /* we know prev is smaller */ 952 /* sort order like: . com. bla.com. zwb.com. net. */ 953 /* find the previous, or parent-parent-parent */ 954 for(p = prev; p; p = p->parent) 955 /* looking for name with few labels, a parent */ 956 if(p->namelabs <= m) { 957 /* ==: since prev matched m, this is closest*/ 958 /* <: prev matches more, but is not a parent, 959 * this one is a (grand)parent */ 960 node->parent = p; 961 break; 962 } 963 prev = node; 964 965 if(node->override_tree) 966 addr_tree_init_parents(node->override_tree); 967 lock_rw_unlock(&node->lock); 968 } 969 lock_rw_unlock(&zones->lock); 970 } 971 972 /** enter implicit transparent zone for local-data: without local-zone: */ 973 static int 974 lz_setup_implicit(struct local_zones* zones, struct config_file* cfg) 975 { 976 /* walk over all items that have no parent zone and find 977 * the name that covers them all (could be the root) and 978 * add that as a transparent zone */ 979 struct config_strlist* p; 980 int have_name = 0; 981 int have_other_classes = 0; 982 uint16_t dclass = 0; 983 uint8_t* nm = 0; 984 size_t nmlen = 0; 985 int nmlabs = 0; 986 int match = 0; /* number of labels match count */ 987 988 init_parents(zones); /* to enable local_zones_lookup() */ 989 for(p = cfg->local_data; p; p = p->next) { 990 uint8_t* rr_name; 991 uint16_t rr_class, rr_type; 992 size_t len; 993 int labs; 994 if(!get_rr_nameclass(p->str, &rr_name, &rr_class, &rr_type)) { 995 log_err("Bad local-data RR %s", p->str); 996 return 0; 997 } 998 labs = dname_count_size_labels(rr_name, &len); 999 lock_rw_rdlock(&zones->lock); 1000 if(!local_zones_lookup(zones, rr_name, len, labs, rr_class, 1001 rr_type)) { 1002 if(!have_name) { 1003 dclass = rr_class; 1004 nm = rr_name; 1005 nmlen = len; 1006 nmlabs = labs; 1007 match = labs; 1008 have_name = 1; 1009 } else { 1010 int m; 1011 if(rr_class != dclass) { 1012 /* process other classes later */ 1013 free(rr_name); 1014 have_other_classes = 1; 1015 lock_rw_unlock(&zones->lock); 1016 continue; 1017 } 1018 /* find smallest shared topdomain */ 1019 (void)dname_lab_cmp(nm, nmlabs, 1020 rr_name, labs, &m); 1021 free(rr_name); 1022 if(m < match) 1023 match = m; 1024 } 1025 } else free(rr_name); 1026 lock_rw_unlock(&zones->lock); 1027 } 1028 if(have_name) { 1029 uint8_t* n2; 1030 struct local_zone* z; 1031 /* allocate zone of smallest shared topdomain to contain em */ 1032 n2 = nm; 1033 dname_remove_labels(&n2, &nmlen, nmlabs - match); 1034 n2 = memdup(n2, nmlen); 1035 free(nm); 1036 if(!n2) { 1037 log_err("out of memory"); 1038 return 0; 1039 } 1040 log_nametypeclass(VERB_ALGO, "implicit transparent local-zone", 1041 n2, 0, dclass); 1042 if(!(z=lz_enter_zone_dname(zones, n2, nmlen, match, 1043 local_zone_transparent, dclass))) { 1044 return 0; 1045 } 1046 lock_rw_unlock(&z->lock); 1047 } 1048 if(have_other_classes) { 1049 /* restart to setup other class */ 1050 return lz_setup_implicit(zones, cfg); 1051 } 1052 return 1; 1053 } 1054 1055 /** enter local-zone-tag info */ 1056 static int 1057 lz_enter_zone_tags(struct local_zones* zones, struct config_file* cfg) 1058 { 1059 struct config_strbytelist* p; 1060 int c = 0; 1061 for(p = cfg->local_zone_tags; p; p = p->next) { 1062 if(!lz_enter_zone_tag(zones, p->str, p->str2, p->str2len, 1063 LDNS_RR_CLASS_IN)) 1064 return 0; 1065 c++; 1066 } 1067 if(c) verbose(VERB_ALGO, "applied tags to %d local zones", c); 1068 return 1; 1069 } 1070 1071 /** enter auth data */ 1072 static int 1073 lz_enter_data(struct local_zones* zones, struct config_file* cfg) 1074 { 1075 struct config_strlist* p; 1076 for(p = cfg->local_data; p; p = p->next) { 1077 if(!lz_enter_rr_str(zones, p->str)) 1078 return 0; 1079 } 1080 return 1; 1081 } 1082 1083 /** free memory from config */ 1084 static void 1085 lz_freeup_cfg(struct config_file* cfg) 1086 { 1087 config_deldblstrlist(cfg->local_zones); 1088 cfg->local_zones = NULL; 1089 config_delstrlist(cfg->local_zones_nodefault); 1090 cfg->local_zones_nodefault = NULL; 1091 config_delstrlist(cfg->local_data); 1092 cfg->local_data = NULL; 1093 } 1094 1095 int 1096 local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg) 1097 { 1098 /* create zones from zone statements. */ 1099 if(!lz_enter_zones(zones, cfg)) { 1100 return 0; 1101 } 1102 /* apply default zones+content (unless disabled, or overridden) */ 1103 if(!local_zone_enter_defaults(zones, cfg)) { 1104 return 0; 1105 } 1106 /* enter local zone overrides */ 1107 if(!lz_enter_overrides(zones, cfg)) { 1108 return 0; 1109 } 1110 /* create implicit transparent zone from data. */ 1111 if(!lz_setup_implicit(zones, cfg)) { 1112 return 0; 1113 } 1114 1115 /* setup parent ptrs for lookup during data entry */ 1116 init_parents(zones); 1117 /* insert local zone tags */ 1118 if(!lz_enter_zone_tags(zones, cfg)) { 1119 return 0; 1120 } 1121 /* insert local data */ 1122 if(!lz_enter_data(zones, cfg)) { 1123 return 0; 1124 } 1125 /* freeup memory from cfg struct. */ 1126 lz_freeup_cfg(cfg); 1127 return 1; 1128 } 1129 1130 struct local_zone* 1131 local_zones_lookup(struct local_zones* zones, 1132 uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype) 1133 { 1134 return local_zones_tags_lookup(zones, name, len, labs, 1135 dclass, dtype, NULL, 0, 1); 1136 } 1137 1138 struct local_zone* 1139 local_zones_tags_lookup(struct local_zones* zones, 1140 uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype, 1141 uint8_t* taglist, size_t taglen, int ignoretags) 1142 { 1143 rbnode_type* res = NULL; 1144 struct local_zone *result; 1145 struct local_zone key; 1146 int m; 1147 /* for type DS use a zone higher when on a zonecut */ 1148 if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) { 1149 dname_remove_label(&name, &len); 1150 labs--; 1151 } 1152 key.node.key = &key; 1153 key.dclass = dclass; 1154 key.name = name; 1155 key.namelen = len; 1156 key.namelabs = labs; 1157 rbtree_find_less_equal(&zones->ztree, &key, &res); 1158 result = (struct local_zone*)res; 1159 /* exact or smaller element (or no element) */ 1160 if(!result || result->dclass != dclass) 1161 return NULL; 1162 /* count number of labels matched */ 1163 (void)dname_lab_cmp(result->name, result->namelabs, key.name, 1164 key.namelabs, &m); 1165 while(result) { /* go up until qname is zone or subdomain of zone */ 1166 if(result->namelabs <= m) 1167 if(ignoretags || !result->taglist || 1168 taglist_intersect(result->taglist, 1169 result->taglen, taglist, taglen)) 1170 break; 1171 result = result->parent; 1172 } 1173 return result; 1174 } 1175 1176 struct local_zone* 1177 local_zones_find(struct local_zones* zones, 1178 uint8_t* name, size_t len, int labs, uint16_t dclass) 1179 { 1180 struct local_zone key; 1181 key.node.key = &key; 1182 key.dclass = dclass; 1183 key.name = name; 1184 key.namelen = len; 1185 key.namelabs = labs; 1186 /* exact */ 1187 return (struct local_zone*)rbtree_search(&zones->ztree, &key); 1188 } 1189 1190 struct local_zone* 1191 local_zones_find_le(struct local_zones* zones, 1192 uint8_t* name, size_t len, int labs, uint16_t dclass, 1193 int* exact) 1194 { 1195 struct local_zone key; 1196 rbnode_type *node; 1197 key.node.key = &key; 1198 key.dclass = dclass; 1199 key.name = name; 1200 key.namelen = len; 1201 key.namelabs = labs; 1202 *exact = rbtree_find_less_equal(&zones->ztree, &key, &node); 1203 return (struct local_zone*)node; 1204 } 1205 1206 /** print all RRsets in local zone */ 1207 static void 1208 local_zone_out(struct local_zone* z) 1209 { 1210 struct local_data* d; 1211 struct local_rrset* p; 1212 RBTREE_FOR(d, struct local_data*, &z->data) { 1213 for(p = d->rrsets; p; p = p->next) { 1214 log_nametypeclass(NO_VERBOSE, "rrset", d->name, 1215 ntohs(p->rrset->rk.type), 1216 ntohs(p->rrset->rk.rrset_class)); 1217 } 1218 } 1219 } 1220 1221 void local_zones_print(struct local_zones* zones) 1222 { 1223 struct local_zone* z; 1224 lock_rw_rdlock(&zones->lock); 1225 log_info("number of auth zones %u", (unsigned)zones->ztree.count); 1226 RBTREE_FOR(z, struct local_zone*, &zones->ztree) { 1227 char buf[64]; 1228 lock_rw_rdlock(&z->lock); 1229 snprintf(buf, sizeof(buf), "%s zone", 1230 local_zone_type2str(z->type)); 1231 log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass); 1232 local_zone_out(z); 1233 lock_rw_unlock(&z->lock); 1234 } 1235 lock_rw_unlock(&zones->lock); 1236 } 1237 1238 /** encode answer consisting of 1 rrset */ 1239 static int 1240 local_encode(struct query_info* qinfo, struct module_env* env, 1241 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1242 struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, 1243 int rcode) 1244 { 1245 struct reply_info rep; 1246 uint16_t udpsize; 1247 /* make answer with time=0 for fixed TTL values */ 1248 memset(&rep, 0, sizeof(rep)); 1249 rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode); 1250 rep.qdcount = 1; 1251 if(ansec) 1252 rep.an_numrrsets = 1; 1253 else rep.ns_numrrsets = 1; 1254 rep.rrset_count = 1; 1255 rep.rrsets = &rrset; 1256 udpsize = edns->udp_size; 1257 edns->edns_version = EDNS_ADVERTISED_VERSION; 1258 edns->udp_size = EDNS_ADVERTISED_SIZE; 1259 edns->ext_rcode = 0; 1260 edns->bits &= EDNS_DO; 1261 if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, 1262 repinfo, temp, env->now_tv) || !reply_info_answer_encode(qinfo, &rep, 1263 *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), 1264 buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) { 1265 error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, 1266 *(uint16_t*)sldns_buffer_begin(buf), 1267 sldns_buffer_read_u16_at(buf, 2), edns); 1268 } 1269 return 1; 1270 } 1271 1272 /** encode local error answer */ 1273 static void 1274 local_error_encode(struct query_info* qinfo, struct module_env* env, 1275 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1276 struct regional* temp, int rcode, int r) 1277 { 1278 edns->edns_version = EDNS_ADVERTISED_VERSION; 1279 edns->udp_size = EDNS_ADVERTISED_SIZE; 1280 edns->ext_rcode = 0; 1281 edns->bits &= EDNS_DO; 1282 1283 if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL, 1284 rcode, edns, repinfo, temp, env->now_tv)) 1285 edns->opt_list = NULL; 1286 error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf), 1287 sldns_buffer_read_u16_at(buf, 2), edns); 1288 } 1289 1290 /** find local data tag string match for the given type in the list */ 1291 int 1292 local_data_find_tag_datas(const struct query_info* qinfo, 1293 struct config_strlist* list, struct ub_packed_rrset_key* r, 1294 struct regional* temp) 1295 { 1296 struct config_strlist* p; 1297 char buf[65536]; 1298 uint8_t rr[LDNS_RR_BUF_SIZE]; 1299 size_t len; 1300 int res; 1301 struct packed_rrset_data* d; 1302 for(p=list; p; p=p->next) { 1303 uint16_t rdr_type; 1304 1305 len = sizeof(rr); 1306 /* does this element match the type? */ 1307 snprintf(buf, sizeof(buf), ". %s", p->str); 1308 res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, 1309 NULL, 0, NULL, 0); 1310 if(res != 0) 1311 /* parse errors are already checked before, in 1312 * acllist check_data, skip this for robustness */ 1313 continue; 1314 if(len < 1 /* . */ + 8 /* typeclassttl*/ + 2 /*rdatalen*/) 1315 continue; 1316 rdr_type = sldns_wirerr_get_type(rr, len, 1); 1317 if(rdr_type != qinfo->qtype && rdr_type != LDNS_RR_TYPE_CNAME) 1318 continue; 1319 1320 /* do we have entries already? if not setup key */ 1321 if(r->rk.dname == NULL) { 1322 r->entry.key = r; 1323 r->rk.dname = qinfo->qname; 1324 r->rk.dname_len = qinfo->qname_len; 1325 r->rk.type = htons(rdr_type); 1326 r->rk.rrset_class = htons(qinfo->qclass); 1327 r->rk.flags = 0; 1328 d = (struct packed_rrset_data*)regional_alloc_zero( 1329 temp, sizeof(struct packed_rrset_data) 1330 + sizeof(size_t) + sizeof(uint8_t*) + 1331 sizeof(time_t)); 1332 if(!d) return 0; /* out of memory */ 1333 r->entry.data = d; 1334 d->ttl = sldns_wirerr_get_ttl(rr, len, 1); 1335 d->rr_len = (size_t*)((uint8_t*)d + 1336 sizeof(struct packed_rrset_data)); 1337 d->rr_data = (uint8_t**)&(d->rr_len[1]); 1338 d->rr_ttl = (time_t*)&(d->rr_data[1]); 1339 } 1340 d = (struct packed_rrset_data*)r->entry.data; 1341 /* add entry to the data */ 1342 if(d->count != 0) { 1343 size_t* oldlen = d->rr_len; 1344 uint8_t** olddata = d->rr_data; 1345 time_t* oldttl = d->rr_ttl; 1346 /* increase arrays for lookup */ 1347 /* this is of course slow for very many records, 1348 * but most redirects are expected with few records */ 1349 d->rr_len = (size_t*)regional_alloc_zero(temp, 1350 (d->count+1)*sizeof(size_t)); 1351 d->rr_data = (uint8_t**)regional_alloc_zero(temp, 1352 (d->count+1)*sizeof(uint8_t*)); 1353 d->rr_ttl = (time_t*)regional_alloc_zero(temp, 1354 (d->count+1)*sizeof(time_t)); 1355 if(!d->rr_len || !d->rr_data || !d->rr_ttl) 1356 return 0; /* out of memory */ 1357 /* first one was allocated after struct d, but new 1358 * ones get their own array increment alloc, so 1359 * copy old content */ 1360 memmove(d->rr_len, oldlen, d->count*sizeof(size_t)); 1361 memmove(d->rr_data, olddata, d->count*sizeof(uint8_t*)); 1362 memmove(d->rr_ttl, oldttl, d->count*sizeof(time_t)); 1363 } 1364 1365 d->rr_len[d->count] = sldns_wirerr_get_rdatalen(rr, len, 1)+2; 1366 d->rr_ttl[d->count] = sldns_wirerr_get_ttl(rr, len, 1); 1367 d->rr_data[d->count] = regional_alloc_init(temp, 1368 sldns_wirerr_get_rdatawl(rr, len, 1), 1369 d->rr_len[d->count]); 1370 if(!d->rr_data[d->count]) 1371 return 0; /* out of memory */ 1372 d->count++; 1373 } 1374 if(r->rk.dname) 1375 return 1; 1376 return 0; 1377 } 1378 1379 static int 1380 find_tag_datas(struct query_info* qinfo, struct config_strlist* list, 1381 struct ub_packed_rrset_key* r, struct regional* temp) 1382 { 1383 int result = local_data_find_tag_datas(qinfo, list, r, temp); 1384 1385 /* If we've found a non-exact alias type of local data, make a shallow 1386 * copy of the RRset and remember it in qinfo to complete the alias 1387 * chain later. */ 1388 if(result && qinfo->qtype != LDNS_RR_TYPE_CNAME && 1389 r->rk.type == htons(LDNS_RR_TYPE_CNAME)) { 1390 qinfo->local_alias = 1391 regional_alloc_zero(temp, sizeof(struct local_rrset)); 1392 if(!qinfo->local_alias) 1393 return 0; /* out of memory */ 1394 qinfo->local_alias->rrset = 1395 regional_alloc_init(temp, r, sizeof(*r)); 1396 if(!qinfo->local_alias->rrset) 1397 return 0; /* out of memory */ 1398 } 1399 return result; 1400 } 1401 1402 int 1403 local_data_answer(struct local_zone* z, struct module_env* env, 1404 struct query_info* qinfo, struct edns_data* edns, 1405 struct comm_reply* repinfo, sldns_buffer* buf, 1406 struct regional* temp, int labs, struct local_data** ldp, 1407 enum localzone_type lz_type, int tag, struct config_strlist** tag_datas, 1408 size_t tag_datas_size, char** tagname, int num_tags) 1409 { 1410 struct local_data key; 1411 struct local_data* ld; 1412 struct local_rrset* lr; 1413 key.node.key = &key; 1414 key.name = qinfo->qname; 1415 key.namelen = qinfo->qname_len; 1416 key.namelabs = labs; 1417 if(lz_type == local_zone_redirect || 1418 lz_type == local_zone_inform_redirect) { 1419 key.name = z->name; 1420 key.namelen = z->namelen; 1421 key.namelabs = z->namelabs; 1422 if(tag != -1 && (size_t)tag<tag_datas_size && tag_datas[tag]) { 1423 struct ub_packed_rrset_key r; 1424 memset(&r, 0, sizeof(r)); 1425 if(find_tag_datas(qinfo, tag_datas[tag], &r, temp)) { 1426 verbose(VERB_ALGO, "redirect with tag data [%d] %s", 1427 tag, (tag<num_tags?tagname[tag]:"null")); 1428 1429 /* If we found a matching alias, we should 1430 * use it as part of the answer, but we can't 1431 * encode it until we complete the alias 1432 * chain. */ 1433 if(qinfo->local_alias) 1434 return 1; 1435 return local_encode(qinfo, env, edns, repinfo, buf, temp, 1436 &r, 1, LDNS_RCODE_NOERROR); 1437 } 1438 } 1439 } 1440 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1441 *ldp = ld; 1442 if(!ld) { 1443 return 0; 1444 } 1445 lr = local_data_find_type(ld, qinfo->qtype, 1); 1446 if(!lr) 1447 return 0; 1448 1449 /* Special case for alias matching. See local_data_answer(). */ 1450 if((lz_type == local_zone_redirect || 1451 lz_type == local_zone_inform_redirect) && 1452 qinfo->qtype != LDNS_RR_TYPE_CNAME && 1453 lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) { 1454 uint8_t* ctarget; 1455 size_t ctargetlen = 0; 1456 1457 qinfo->local_alias = 1458 regional_alloc_zero(temp, sizeof(struct local_rrset)); 1459 if(!qinfo->local_alias) 1460 return 0; /* out of memory */ 1461 qinfo->local_alias->rrset = regional_alloc_init( 1462 temp, lr->rrset, sizeof(*lr->rrset)); 1463 if(!qinfo->local_alias->rrset) 1464 return 0; /* out of memory */ 1465 qinfo->local_alias->rrset->rk.dname = qinfo->qname; 1466 qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; 1467 get_cname_target(lr->rrset, &ctarget, &ctargetlen); 1468 if(!ctargetlen) 1469 return 0; /* invalid cname */ 1470 if(dname_is_wild(ctarget)) { 1471 /* synthesize cname target */ 1472 struct packed_rrset_data* d; 1473 /* -3 for wildcard label and root label from qname */ 1474 size_t newtargetlen = qinfo->qname_len + ctargetlen - 3; 1475 1476 log_assert(ctargetlen >= 3); 1477 log_assert(qinfo->qname_len >= 1); 1478 1479 if(newtargetlen > LDNS_MAX_DOMAINLEN) { 1480 qinfo->local_alias = NULL; 1481 local_error_encode(qinfo, env, edns, repinfo, 1482 buf, temp, LDNS_RCODE_YXDOMAIN, 1483 (LDNS_RCODE_YXDOMAIN|BIT_AA)); 1484 return 1; 1485 } 1486 memset(&qinfo->local_alias->rrset->entry, 0, 1487 sizeof(qinfo->local_alias->rrset->entry)); 1488 qinfo->local_alias->rrset->entry.key = 1489 qinfo->local_alias->rrset; 1490 qinfo->local_alias->rrset->entry.hash = 1491 rrset_key_hash(&qinfo->local_alias->rrset->rk); 1492 d = (struct packed_rrset_data*)regional_alloc_zero(temp, 1493 sizeof(struct packed_rrset_data) + sizeof(size_t) + 1494 sizeof(uint8_t*) + sizeof(time_t) + sizeof(uint16_t) 1495 + newtargetlen); 1496 if(!d) 1497 return 0; /* out of memory */ 1498 qinfo->local_alias->rrset->entry.data = d; 1499 d->ttl = 0; /* 0 for synthesized CNAME TTL */ 1500 d->count = 1; 1501 d->rrsig_count = 0; 1502 d->trust = rrset_trust_ans_noAA; 1503 d->rr_len = (size_t*)((uint8_t*)d + 1504 sizeof(struct packed_rrset_data)); 1505 d->rr_len[0] = newtargetlen + sizeof(uint16_t); 1506 packed_rrset_ptr_fixup(d); 1507 d->rr_ttl[0] = d->ttl; 1508 sldns_write_uint16(d->rr_data[0], newtargetlen); 1509 /* write qname */ 1510 memmove(d->rr_data[0] + sizeof(uint16_t), qinfo->qname, 1511 qinfo->qname_len - 1); 1512 /* write cname target wilcard wildcard label */ 1513 memmove(d->rr_data[0] + sizeof(uint16_t) + 1514 qinfo->qname_len - 1, ctarget + 2, 1515 ctargetlen - 2); 1516 } 1517 return 1; 1518 } 1519 if(lz_type == local_zone_redirect || 1520 lz_type == local_zone_inform_redirect) { 1521 /* convert rrset name to query name; like a wildcard */ 1522 struct ub_packed_rrset_key r = *lr->rrset; 1523 r.rk.dname = qinfo->qname; 1524 r.rk.dname_len = qinfo->qname_len; 1525 return local_encode(qinfo, env, edns, repinfo, buf, temp, &r, 1, 1526 LDNS_RCODE_NOERROR); 1527 } 1528 return local_encode(qinfo, env, edns, repinfo, buf, temp, lr->rrset, 1, 1529 LDNS_RCODE_NOERROR); 1530 } 1531 1532 /** 1533 * See if the local zone does not cover the name, eg. the name is not 1534 * in the zone and the zone is transparent */ 1535 static int 1536 local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo, 1537 int labs) 1538 { 1539 struct local_data key; 1540 struct local_data* ld = NULL; 1541 struct local_rrset* lr = NULL; 1542 if(z->type == local_zone_always_transparent) 1543 return 1; 1544 if(z->type != local_zone_transparent 1545 && z->type != local_zone_typetransparent 1546 && z->type != local_zone_inform) 1547 return 0; 1548 key.node.key = &key; 1549 key.name = qinfo->qname; 1550 key.namelen = qinfo->qname_len; 1551 key.namelabs = labs; 1552 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1553 if(z->type == local_zone_transparent || z->type == local_zone_inform) 1554 return (ld == NULL); 1555 if(ld) 1556 lr = local_data_find_type(ld, qinfo->qtype, 1); 1557 /* local_zone_typetransparent */ 1558 return (lr == NULL); 1559 } 1560 1561 int 1562 local_zones_zone_answer(struct local_zone* z, struct module_env* env, 1563 struct query_info* qinfo, struct edns_data* edns, 1564 struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp, 1565 struct local_data* ld, enum localzone_type lz_type) 1566 { 1567 if(lz_type == local_zone_deny || 1568 lz_type == local_zone_always_deny || 1569 lz_type == local_zone_inform_deny) { 1570 /** no reply at all, signal caller by clearing buffer. */ 1571 sldns_buffer_clear(buf); 1572 sldns_buffer_flip(buf); 1573 return 1; 1574 } else if(lz_type == local_zone_refuse 1575 || lz_type == local_zone_always_refuse) { 1576 local_error_encode(qinfo, env, edns, repinfo, buf, temp, 1577 LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA)); 1578 return 1; 1579 } else if(lz_type == local_zone_static || 1580 lz_type == local_zone_redirect || 1581 lz_type == local_zone_inform_redirect || 1582 lz_type == local_zone_always_nxdomain || 1583 lz_type == local_zone_always_nodata) { 1584 /* for static, reply nodata or nxdomain 1585 * for redirect, reply nodata */ 1586 /* no additional section processing, 1587 * cname, dname or wildcard processing, 1588 * or using closest match for NSEC. 1589 * or using closest match for returning delegation downwards 1590 */ 1591 int rcode = (ld || lz_type == local_zone_redirect || 1592 lz_type == local_zone_inform_redirect || 1593 lz_type == local_zone_always_nodata)? 1594 LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN; 1595 if(z->soa && z->soa_negative) 1596 return local_encode(qinfo, env, edns, repinfo, buf, temp, 1597 z->soa_negative, 0, rcode); 1598 local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, 1599 (rcode|BIT_AA)); 1600 return 1; 1601 } else if(lz_type == local_zone_typetransparent 1602 || lz_type == local_zone_always_transparent) { 1603 /* no NODATA or NXDOMAINS for this zone type */ 1604 return 0; 1605 } else if(lz_type == local_zone_always_null) { 1606 /* 0.0.0.0 or ::0 or noerror/nodata for this zone type, 1607 * used for blocklists. */ 1608 if(qinfo->qtype == LDNS_RR_TYPE_A || 1609 qinfo->qtype == LDNS_RR_TYPE_AAAA) { 1610 struct ub_packed_rrset_key lrr; 1611 struct packed_rrset_data d; 1612 time_t rr_ttl = 3600; 1613 size_t rr_len = 0; 1614 uint8_t rr_data[2+16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 1615 uint8_t* rr_datas = rr_data; 1616 memset(&lrr, 0, sizeof(lrr)); 1617 memset(&d, 0, sizeof(d)); 1618 lrr.entry.data = &d; 1619 lrr.rk.dname = qinfo->qname; 1620 lrr.rk.dname_len = qinfo->qname_len; 1621 lrr.rk.type = htons(qinfo->qtype); 1622 lrr.rk.rrset_class = htons(qinfo->qclass); 1623 if(qinfo->qtype == LDNS_RR_TYPE_A) { 1624 rr_len = 4; 1625 sldns_write_uint16(rr_data, rr_len); 1626 rr_len += 2; 1627 } else { 1628 rr_len = 16; 1629 sldns_write_uint16(rr_data, rr_len); 1630 rr_len += 2; 1631 } 1632 d.ttl = rr_ttl; 1633 d.count = 1; 1634 d.rr_len = &rr_len; 1635 d.rr_data = &rr_datas; 1636 d.rr_ttl = &rr_ttl; 1637 return local_encode(qinfo, env, edns, repinfo, buf, temp, 1638 &lrr, 1, LDNS_RCODE_NOERROR); 1639 } else { 1640 local_error_encode(qinfo, env, edns, repinfo, buf, 1641 temp, LDNS_RCODE_NOERROR, 1642 (LDNS_RCODE_NOERROR|BIT_AA)); 1643 } 1644 return 1; 1645 } 1646 /* else lz_type == local_zone_transparent */ 1647 1648 /* if the zone is transparent and the name exists, but the type 1649 * does not, then we should make this noerror/nodata */ 1650 if(ld && ld->rrsets) { 1651 int rcode = LDNS_RCODE_NOERROR; 1652 if(z->soa && z->soa_negative) 1653 return local_encode(qinfo, env, edns, repinfo, buf, temp, 1654 z->soa_negative, 0, rcode); 1655 local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, 1656 (rcode|BIT_AA)); 1657 return 1; 1658 } 1659 1660 /* stop here, and resolve further on */ 1661 return 0; 1662 } 1663 1664 /** print log information for an inform zone query */ 1665 static void 1666 lz_inform_print(struct local_zone* z, struct query_info* qinfo, 1667 struct comm_reply* repinfo) 1668 { 1669 char ip[128], txt[512]; 1670 char zname[LDNS_MAX_DOMAINLEN+1]; 1671 uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); 1672 dname_str(z->name, zname); 1673 addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); 1674 snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip, 1675 (unsigned)port); 1676 log_nametypeclass(NO_VERBOSE, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); 1677 } 1678 1679 static enum localzone_type 1680 lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2, 1681 uint8_t *tagactions, size_t tagactionssize, enum localzone_type lzt, 1682 struct comm_reply* repinfo, struct rbtree_type* override_tree, 1683 int* tag, char** tagname, int num_tags) 1684 { 1685 struct local_zone_override* lzo; 1686 if(repinfo && override_tree) { 1687 lzo = (struct local_zone_override*)addr_tree_lookup( 1688 override_tree, &repinfo->addr, repinfo->addrlen); 1689 if(lzo && lzo->type) { 1690 verbose(VERB_ALGO, "local zone override to type %s", 1691 local_zone_type2str(lzo->type)); 1692 return lzo->type; 1693 } 1694 } 1695 if(!taglist || !taglist2) 1696 return lzt; 1697 return local_data_find_tag_action(taglist, taglen, taglist2, taglen2, 1698 tagactions, tagactionssize, lzt, tag, tagname, num_tags); 1699 } 1700 1701 enum localzone_type 1702 local_data_find_tag_action(const uint8_t* taglist, size_t taglen, 1703 const uint8_t* taglist2, size_t taglen2, const uint8_t* tagactions, 1704 size_t tagactionssize, enum localzone_type lzt, int* tag, 1705 char* const* tagname, int num_tags) 1706 { 1707 size_t i, j; 1708 uint8_t tagmatch; 1709 1710 for(i=0; i<taglen && i<taglen2; i++) { 1711 tagmatch = (taglist[i] & taglist2[i]); 1712 for(j=0; j<8 && tagmatch>0; j++) { 1713 if((tagmatch & 0x1)) { 1714 *tag = (int)(i*8+j); 1715 verbose(VERB_ALGO, "matched tag [%d] %s", 1716 *tag, (*tag<num_tags?tagname[*tag]:"null")); 1717 /* does this tag have a tag action? */ 1718 if(i*8+j < tagactionssize && tagactions 1719 && tagactions[i*8+j] != 0) { 1720 verbose(VERB_ALGO, "tag action [%d] %s to type %s", 1721 *tag, (*tag<num_tags?tagname[*tag]:"null"), 1722 local_zone_type2str( 1723 (enum localzone_type) 1724 tagactions[i*8+j])); 1725 return (enum localzone_type)tagactions[i*8+j]; 1726 } 1727 return lzt; 1728 } 1729 tagmatch >>= 1; 1730 } 1731 } 1732 return lzt; 1733 } 1734 1735 int 1736 local_zones_answer(struct local_zones* zones, struct module_env* env, 1737 struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, 1738 struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, 1739 size_t taglen, uint8_t* tagactions, size_t tagactionssize, 1740 struct config_strlist** tag_datas, size_t tag_datas_size, 1741 char** tagname, int num_tags, struct view* view) 1742 { 1743 /* see if query is covered by a zone, 1744 * if so: - try to match (exact) local data 1745 * - look at zone type for negative response. */ 1746 int labs = dname_count_labels(qinfo->qname); 1747 struct local_data* ld = NULL; 1748 struct local_zone* z = NULL; 1749 enum localzone_type lzt = local_zone_transparent; 1750 int r, tag = -1; 1751 1752 if(view) { 1753 lock_rw_rdlock(&view->lock); 1754 if(view->local_zones && 1755 (z = local_zones_lookup(view->local_zones, 1756 qinfo->qname, qinfo->qname_len, labs, 1757 qinfo->qclass, qinfo->qtype))) { 1758 lock_rw_rdlock(&z->lock); 1759 lzt = z->type; 1760 } 1761 if(lzt == local_zone_noview) { 1762 lock_rw_unlock(&z->lock); 1763 z = NULL; 1764 } 1765 if(z && (lzt == local_zone_transparent || 1766 lzt == local_zone_typetransparent || 1767 lzt == local_zone_inform || 1768 lzt == local_zone_always_transparent) && 1769 local_zone_does_not_cover(z, qinfo, labs)) { 1770 lock_rw_unlock(&z->lock); 1771 z = NULL; 1772 } 1773 if(view->local_zones && !z && !view->isfirst){ 1774 lock_rw_unlock(&view->lock); 1775 return 0; 1776 } 1777 if(z && verbosity >= VERB_ALGO) { 1778 char zname[255+1]; 1779 dname_str(z->name, zname); 1780 verbose(VERB_ALGO, "using localzone %s %s from view %s", 1781 zname, local_zone_type2str(lzt), view->name); 1782 } 1783 lock_rw_unlock(&view->lock); 1784 } 1785 if(!z) { 1786 /* try global local_zones tree */ 1787 lock_rw_rdlock(&zones->lock); 1788 if(!(z = local_zones_tags_lookup(zones, qinfo->qname, 1789 qinfo->qname_len, labs, qinfo->qclass, qinfo->qtype, 1790 taglist, taglen, 0))) { 1791 lock_rw_unlock(&zones->lock); 1792 return 0; 1793 } 1794 lock_rw_rdlock(&z->lock); 1795 lzt = lz_type(taglist, taglen, z->taglist, z->taglen, 1796 tagactions, tagactionssize, z->type, repinfo, 1797 z->override_tree, &tag, tagname, num_tags); 1798 lock_rw_unlock(&zones->lock); 1799 if(z && verbosity >= VERB_ALGO) { 1800 char zname[255+1]; 1801 dname_str(z->name, zname); 1802 verbose(VERB_ALGO, "using localzone %s %s", zname, 1803 local_zone_type2str(lzt)); 1804 } 1805 } 1806 if((env->cfg->log_local_actions || 1807 lzt == local_zone_inform || 1808 lzt == local_zone_inform_deny || 1809 lzt == local_zone_inform_redirect) 1810 && repinfo) 1811 lz_inform_print(z, qinfo, repinfo); 1812 1813 if(lzt != local_zone_always_refuse 1814 && lzt != local_zone_always_transparent 1815 && lzt != local_zone_always_nxdomain 1816 && lzt != local_zone_always_nodata 1817 && lzt != local_zone_always_deny 1818 && local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs, 1819 &ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) { 1820 lock_rw_unlock(&z->lock); 1821 /* We should tell the caller that encode is deferred if we found 1822 * a local alias. */ 1823 return !qinfo->local_alias; 1824 } 1825 r = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt); 1826 lock_rw_unlock(&z->lock); 1827 return r && !qinfo->local_alias; /* see above */ 1828 } 1829 1830 const char* local_zone_type2str(enum localzone_type t) 1831 { 1832 switch(t) { 1833 case local_zone_unset: return "unset"; 1834 case local_zone_deny: return "deny"; 1835 case local_zone_refuse: return "refuse"; 1836 case local_zone_redirect: return "redirect"; 1837 case local_zone_transparent: return "transparent"; 1838 case local_zone_typetransparent: return "typetransparent"; 1839 case local_zone_static: return "static"; 1840 case local_zone_nodefault: return "nodefault"; 1841 case local_zone_inform: return "inform"; 1842 case local_zone_inform_deny: return "inform_deny"; 1843 case local_zone_inform_redirect: return "inform_redirect"; 1844 case local_zone_always_transparent: return "always_transparent"; 1845 case local_zone_always_refuse: return "always_refuse"; 1846 case local_zone_always_nxdomain: return "always_nxdomain"; 1847 case local_zone_always_nodata: return "always_nodata"; 1848 case local_zone_always_deny: return "always_deny"; 1849 case local_zone_always_null: return "always_null"; 1850 case local_zone_noview: return "noview"; 1851 case local_zone_invalid: return "invalid"; 1852 } 1853 return "badtyped"; 1854 } 1855 1856 int local_zone_str2type(const char* type, enum localzone_type* t) 1857 { 1858 if(strcmp(type, "deny") == 0) 1859 *t = local_zone_deny; 1860 else if(strcmp(type, "refuse") == 0) 1861 *t = local_zone_refuse; 1862 else if(strcmp(type, "static") == 0) 1863 *t = local_zone_static; 1864 else if(strcmp(type, "transparent") == 0) 1865 *t = local_zone_transparent; 1866 else if(strcmp(type, "typetransparent") == 0) 1867 *t = local_zone_typetransparent; 1868 else if(strcmp(type, "redirect") == 0) 1869 *t = local_zone_redirect; 1870 else if(strcmp(type, "inform") == 0) 1871 *t = local_zone_inform; 1872 else if(strcmp(type, "inform_deny") == 0) 1873 *t = local_zone_inform_deny; 1874 else if(strcmp(type, "inform_redirect") == 0) 1875 *t = local_zone_inform_redirect; 1876 else if(strcmp(type, "always_transparent") == 0) 1877 *t = local_zone_always_transparent; 1878 else if(strcmp(type, "always_refuse") == 0) 1879 *t = local_zone_always_refuse; 1880 else if(strcmp(type, "always_nxdomain") == 0) 1881 *t = local_zone_always_nxdomain; 1882 else if(strcmp(type, "always_nodata") == 0) 1883 *t = local_zone_always_nodata; 1884 else if(strcmp(type, "always_deny") == 0) 1885 *t = local_zone_always_deny; 1886 else if(strcmp(type, "always_null") == 0) 1887 *t = local_zone_always_null; 1888 else if(strcmp(type, "noview") == 0) 1889 *t = local_zone_noview; 1890 else if(strcmp(type, "nodefault") == 0) 1891 *t = local_zone_nodefault; 1892 else return 0; 1893 return 1; 1894 } 1895 1896 /** iterate over the kiddies of the given name and set their parent ptr */ 1897 static void 1898 set_kiddo_parents(struct local_zone* z, struct local_zone* match, 1899 struct local_zone* newp) 1900 { 1901 /* both zones and z are locked already */ 1902 /* in the sorted rbtree, the kiddies of z are located after z */ 1903 /* z must be present in the tree */ 1904 struct local_zone* p = z; 1905 p = (struct local_zone*)rbtree_next(&p->node); 1906 while(p!=(struct local_zone*)RBTREE_NULL && 1907 p->dclass == z->dclass && dname_strict_subdomain(p->name, 1908 p->namelabs, z->name, z->namelabs)) { 1909 /* update parent ptr */ 1910 /* only when matches with existing parent pointer, so that 1911 * deeper child structures are not touched, i.e. 1912 * update of x, and a.x, b.x, f.b.x, g.b.x, c.x, y 1913 * gets to update a.x, b.x and c.x */ 1914 lock_rw_wrlock(&p->lock); 1915 if(p->parent == match) 1916 p->parent = newp; 1917 lock_rw_unlock(&p->lock); 1918 p = (struct local_zone*)rbtree_next(&p->node); 1919 } 1920 } 1921 1922 struct local_zone* local_zones_add_zone(struct local_zones* zones, 1923 uint8_t* name, size_t len, int labs, uint16_t dclass, 1924 enum localzone_type tp) 1925 { 1926 /* create */ 1927 struct local_zone* z = local_zone_create(name, len, labs, tp, dclass); 1928 if(!z) { 1929 free(name); 1930 return NULL; 1931 } 1932 lock_rw_wrlock(&z->lock); 1933 1934 /* find the closest parent */ 1935 z->parent = local_zones_find(zones, name, len, labs, dclass); 1936 1937 /* insert into the tree */ 1938 if(!rbtree_insert(&zones->ztree, &z->node)) { 1939 /* duplicate entry! */ 1940 lock_rw_unlock(&z->lock); 1941 local_zone_delete(z); 1942 log_err("internal: duplicate entry in local_zones_add_zone"); 1943 return NULL; 1944 } 1945 1946 /* set parent pointers right */ 1947 set_kiddo_parents(z, z->parent, z); 1948 1949 lock_rw_unlock(&z->lock); 1950 return z; 1951 } 1952 1953 void local_zones_del_zone(struct local_zones* zones, struct local_zone* z) 1954 { 1955 /* fix up parents in tree */ 1956 lock_rw_wrlock(&z->lock); 1957 set_kiddo_parents(z, z, z->parent); 1958 1959 /* remove from tree */ 1960 (void)rbtree_delete(&zones->ztree, z); 1961 1962 /* delete the zone */ 1963 lock_rw_unlock(&z->lock); 1964 local_zone_delete(z); 1965 } 1966 1967 int 1968 local_zones_add_RR(struct local_zones* zones, const char* rr) 1969 { 1970 uint8_t* rr_name; 1971 uint16_t rr_class, rr_type; 1972 size_t len; 1973 int labs; 1974 struct local_zone* z; 1975 int r; 1976 if(!get_rr_nameclass(rr, &rr_name, &rr_class, &rr_type)) { 1977 return 0; 1978 } 1979 labs = dname_count_size_labels(rr_name, &len); 1980 /* could first try readlock then get writelock if zone does not exist, 1981 * but we do not add enough RRs (from multiple threads) to optimize */ 1982 lock_rw_wrlock(&zones->lock); 1983 z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type); 1984 if(!z) { 1985 z = local_zones_add_zone(zones, rr_name, len, labs, rr_class, 1986 local_zone_transparent); 1987 if(!z) { 1988 lock_rw_unlock(&zones->lock); 1989 return 0; 1990 } 1991 } else { 1992 free(rr_name); 1993 } 1994 lock_rw_wrlock(&z->lock); 1995 lock_rw_unlock(&zones->lock); 1996 r = lz_enter_rr_into_zone(z, rr); 1997 lock_rw_unlock(&z->lock); 1998 return r; 1999 } 2000 2001 /** returns true if the node is terminal so no deeper domain names exist */ 2002 static int 2003 is_terminal(struct local_data* d) 2004 { 2005 /* for empty nonterminals, the deeper domain names are sorted 2006 * right after them, so simply check the next name in the tree 2007 */ 2008 struct local_data* n = (struct local_data*)rbtree_next(&d->node); 2009 if(n == (struct local_data*)RBTREE_NULL) 2010 return 1; /* last in tree, no deeper node */ 2011 if(dname_strict_subdomain(n->name, n->namelabs, d->name, d->namelabs)) 2012 return 0; /* there is a deeper node */ 2013 return 1; 2014 } 2015 2016 /** delete empty terminals from tree when final data is deleted */ 2017 static void 2018 del_empty_term(struct local_zone* z, struct local_data* d, 2019 uint8_t* name, size_t len, int labs) 2020 { 2021 while(d && d->rrsets == NULL && is_terminal(d)) { 2022 /* is this empty nonterminal? delete */ 2023 /* note, no memory recycling in zone region */ 2024 (void)rbtree_delete(&z->data, d); 2025 2026 /* go up and to the next label */ 2027 if(dname_is_root(name)) 2028 return; 2029 dname_remove_label(&name, &len); 2030 labs--; 2031 d = local_zone_find_data(z, name, len, labs); 2032 } 2033 } 2034 2035 /** find and remove type from list in domain struct */ 2036 static void 2037 del_local_rrset(struct local_data* d, uint16_t dtype) 2038 { 2039 struct local_rrset* prev=NULL, *p=d->rrsets; 2040 while(p && ntohs(p->rrset->rk.type) != dtype) { 2041 prev = p; 2042 p = p->next; 2043 } 2044 if(!p) 2045 return; /* rrset type not found */ 2046 /* unlink it */ 2047 if(prev) prev->next = p->next; 2048 else d->rrsets = p->next; 2049 /* no memory recycling for zone deletions ... */ 2050 } 2051 2052 void local_zones_del_data(struct local_zones* zones, 2053 uint8_t* name, size_t len, int labs, uint16_t dclass) 2054 { 2055 /* find zone */ 2056 struct local_zone* z; 2057 struct local_data* d; 2058 2059 /* remove DS */ 2060 lock_rw_rdlock(&zones->lock); 2061 z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS); 2062 if(z) { 2063 lock_rw_wrlock(&z->lock); 2064 d = local_zone_find_data(z, name, len, labs); 2065 if(d) { 2066 del_local_rrset(d, LDNS_RR_TYPE_DS); 2067 del_empty_term(z, d, name, len, labs); 2068 } 2069 lock_rw_unlock(&z->lock); 2070 } 2071 lock_rw_unlock(&zones->lock); 2072 2073 /* remove other types */ 2074 lock_rw_rdlock(&zones->lock); 2075 z = local_zones_lookup(zones, name, len, labs, dclass, 0); 2076 if(!z) { 2077 /* no such zone, we're done */ 2078 lock_rw_unlock(&zones->lock); 2079 return; 2080 } 2081 lock_rw_wrlock(&z->lock); 2082 lock_rw_unlock(&zones->lock); 2083 2084 /* find the domain */ 2085 d = local_zone_find_data(z, name, len, labs); 2086 if(d) { 2087 /* no memory recycling for zone deletions ... */ 2088 d->rrsets = NULL; 2089 /* did we delete the soa record ? */ 2090 if(query_dname_compare(d->name, z->name) == 0) { 2091 z->soa = NULL; 2092 z->soa_negative = NULL; 2093 } 2094 2095 /* cleanup the empty nonterminals for this name */ 2096 del_empty_term(z, d, name, len, labs); 2097 } 2098 2099 lock_rw_unlock(&z->lock); 2100 } 2101