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 #ifndef THREADS_DISABLED 749 struct local_zone* z; 750 #endif 751 for(p = cfg->local_zones; p; p = p->next) { 752 if(!( 753 #ifndef THREADS_DISABLED 754 z= 755 #endif 756 lz_enter_zone(zones, p->str, p->str2, 757 LDNS_RR_CLASS_IN))) 758 return 0; 759 lock_rw_unlock(&z->lock); 760 } 761 return 1; 762 } 763 764 /** lookup a zone in rbtree; exact match only; SLOW due to parse */ 765 static int 766 lz_exists(struct local_zones* zones, const char* name) 767 { 768 struct local_zone z; 769 z.node.key = &z; 770 z.dclass = LDNS_RR_CLASS_IN; 771 if(!parse_dname(name, &z.name, &z.namelen, &z.namelabs)) { 772 log_err("bad name %s", name); 773 return 0; 774 } 775 lock_rw_rdlock(&zones->lock); 776 if(rbtree_search(&zones->ztree, &z.node)) { 777 lock_rw_unlock(&zones->lock); 778 free(z.name); 779 return 1; 780 } 781 lock_rw_unlock(&zones->lock); 782 free(z.name); 783 return 0; 784 } 785 786 /** lookup a zone in cfg->nodefault list */ 787 static int 788 lz_nodefault(struct config_file* cfg, const char* name) 789 { 790 struct config_strlist* p; 791 size_t len = strlen(name); 792 if(len == 0) return 0; 793 if(name[len-1] == '.') len--; 794 795 for(p = cfg->local_zones_nodefault; p; p = p->next) { 796 /* compare zone name, lowercase, compare without ending . */ 797 if(strncasecmp(p->str, name, len) == 0 && 798 (strlen(p->str) == len || (strlen(p->str)==len+1 && 799 p->str[len] == '.'))) 800 return 1; 801 } 802 return 0; 803 } 804 805 /** enter (AS112) empty default zone */ 806 static int 807 add_empty_default(struct local_zones* zones, struct config_file* cfg, 808 const char* name) 809 { 810 struct local_zone* z; 811 char str[1024]; /* known long enough */ 812 if(lz_exists(zones, name) || lz_nodefault(cfg, name)) 813 return 1; /* do not enter default content */ 814 if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN))) 815 return 0; 816 snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. " 817 "nobody.invalid. 1 3600 1200 604800 10800", name); 818 if(!lz_enter_rr_into_zone(z, str)) { 819 lock_rw_unlock(&z->lock); 820 return 0; 821 } 822 snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name); 823 if(!lz_enter_rr_into_zone(z, str)) { 824 lock_rw_unlock(&z->lock); 825 return 0; 826 } 827 lock_rw_unlock(&z->lock); 828 return 1; 829 } 830 831 /** enter default zones */ 832 int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg) 833 { 834 struct local_zone* z; 835 const char** zstr; 836 837 /* Do not add any default */ 838 if(cfg->local_zones_disable_default) 839 return 1; 840 841 /* this list of zones is from RFC 6303 and RFC 7686 */ 842 843 /* block localhost level zones first, then onion and later the LAN zones */ 844 845 /* localhost. zone */ 846 if(!lz_exists(zones, "localhost.") && 847 !lz_nodefault(cfg, "localhost.")) { 848 if(!(z=lz_enter_zone(zones, "localhost.", "redirect", 849 LDNS_RR_CLASS_IN)) || 850 !lz_enter_rr_into_zone(z, 851 "localhost. 10800 IN NS localhost.") || 852 !lz_enter_rr_into_zone(z, 853 "localhost. 10800 IN SOA localhost. nobody.invalid. " 854 "1 3600 1200 604800 10800") || 855 !lz_enter_rr_into_zone(z, 856 "localhost. 10800 IN A 127.0.0.1") || 857 !lz_enter_rr_into_zone(z, 858 "localhost. 10800 IN AAAA ::1")) { 859 log_err("out of memory adding default zone"); 860 if(z) { lock_rw_unlock(&z->lock); } 861 return 0; 862 } 863 lock_rw_unlock(&z->lock); 864 } 865 /* reverse ip4 zone */ 866 if(!lz_exists(zones, "127.in-addr.arpa.") && 867 !lz_nodefault(cfg, "127.in-addr.arpa.")) { 868 if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static", 869 LDNS_RR_CLASS_IN)) || 870 !lz_enter_rr_into_zone(z, 871 "127.in-addr.arpa. 10800 IN NS localhost.") || 872 !lz_enter_rr_into_zone(z, 873 "127.in-addr.arpa. 10800 IN SOA localhost. " 874 "nobody.invalid. 1 3600 1200 604800 10800") || 875 !lz_enter_rr_into_zone(z, 876 "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) { 877 log_err("out of memory adding default zone"); 878 if(z) { lock_rw_unlock(&z->lock); } 879 return 0; 880 } 881 lock_rw_unlock(&z->lock); 882 } 883 /* reverse ip6 zone */ 884 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.") && 885 !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.")) { 886 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", 887 LDNS_RR_CLASS_IN)) || 888 !lz_enter_rr_into_zone(z, 889 "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.") || 890 !lz_enter_rr_into_zone(z, 891 "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. " 892 "nobody.invalid. 1 3600 1200 604800 10800") || 893 !lz_enter_rr_into_zone(z, 894 "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.")) { 895 log_err("out of memory adding default zone"); 896 if(z) { lock_rw_unlock(&z->lock); } 897 return 0; 898 } 899 lock_rw_unlock(&z->lock); 900 } 901 /* onion. zone (RFC 7686) */ 902 if(!add_empty_default(zones, cfg, "onion.")) { 903 log_err("out of memory adding default zone"); 904 return 0; 905 } 906 /* test. zone (RFC 6761) */ 907 if(!add_empty_default(zones, cfg, "test.")) { 908 log_err("out of memory adding default zone"); 909 return 0; 910 } 911 /* invalid. zone (RFC 6761) */ 912 if(!add_empty_default(zones, cfg, "invalid.")) { 913 log_err("out of memory adding default zone"); 914 return 0; 915 } 916 /* block AS112 zones, unless asked not to */ 917 if(!cfg->unblock_lan_zones) { 918 for(zstr = as112_zones; *zstr; zstr++) { 919 if(!add_empty_default(zones, cfg, *zstr)) { 920 log_err("out of memory adding default zone"); 921 return 0; 922 } 923 } 924 } 925 return 1; 926 } 927 928 /** parse local-zone-override: statements */ 929 static int 930 lz_enter_overrides(struct local_zones* zones, struct config_file* cfg) 931 { 932 struct config_str3list* p; 933 for(p = cfg->local_zone_overrides; p; p = p->next) { 934 if(!lz_enter_override(zones, p->str, p->str2, p->str3, 935 LDNS_RR_CLASS_IN)) 936 return 0; 937 } 938 return 1; 939 } 940 941 /** setup parent pointers, so that a lookup can be done for closest match */ 942 static void 943 init_parents(struct local_zones* zones) 944 { 945 struct local_zone* node, *prev = NULL, *p; 946 int m; 947 lock_rw_wrlock(&zones->lock); 948 RBTREE_FOR(node, struct local_zone*, &zones->ztree) { 949 lock_rw_wrlock(&node->lock); 950 node->parent = NULL; 951 if(!prev || prev->dclass != node->dclass) { 952 prev = node; 953 lock_rw_unlock(&node->lock); 954 continue; 955 } 956 (void)dname_lab_cmp(prev->name, prev->namelabs, node->name, 957 node->namelabs, &m); /* we know prev is smaller */ 958 /* sort order like: . com. bla.com. zwb.com. net. */ 959 /* find the previous, or parent-parent-parent */ 960 for(p = prev; p; p = p->parent) 961 /* looking for name with few labels, a parent */ 962 if(p->namelabs <= m) { 963 /* ==: since prev matched m, this is closest*/ 964 /* <: prev matches more, but is not a parent, 965 * this one is a (grand)parent */ 966 node->parent = p; 967 break; 968 } 969 prev = node; 970 971 if(node->override_tree) 972 addr_tree_init_parents(node->override_tree); 973 lock_rw_unlock(&node->lock); 974 } 975 lock_rw_unlock(&zones->lock); 976 } 977 978 /** enter implicit transparent zone for local-data: without local-zone: */ 979 static int 980 lz_setup_implicit(struct local_zones* zones, struct config_file* cfg) 981 { 982 /* walk over all items that have no parent zone and find 983 * the name that covers them all (could be the root) and 984 * add that as a transparent zone */ 985 struct config_strlist* p; 986 int have_name = 0; 987 int have_other_classes = 0; 988 uint16_t dclass = 0; 989 uint8_t* nm = 0; 990 size_t nmlen = 0; 991 int nmlabs = 0; 992 int match = 0; /* number of labels match count */ 993 994 init_parents(zones); /* to enable local_zones_lookup() */ 995 for(p = cfg->local_data; p; p = p->next) { 996 uint8_t* rr_name; 997 uint16_t rr_class, rr_type; 998 size_t len; 999 int labs; 1000 if(!get_rr_nameclass(p->str, &rr_name, &rr_class, &rr_type)) { 1001 log_err("Bad local-data RR %s", p->str); 1002 return 0; 1003 } 1004 labs = dname_count_size_labels(rr_name, &len); 1005 lock_rw_rdlock(&zones->lock); 1006 if(!local_zones_lookup(zones, rr_name, len, labs, rr_class, 1007 rr_type)) { 1008 if(!have_name) { 1009 dclass = rr_class; 1010 nm = rr_name; 1011 nmlen = len; 1012 nmlabs = labs; 1013 match = labs; 1014 have_name = 1; 1015 } else { 1016 int m; 1017 if(rr_class != dclass) { 1018 /* process other classes later */ 1019 free(rr_name); 1020 have_other_classes = 1; 1021 lock_rw_unlock(&zones->lock); 1022 continue; 1023 } 1024 /* find smallest shared topdomain */ 1025 (void)dname_lab_cmp(nm, nmlabs, 1026 rr_name, labs, &m); 1027 free(rr_name); 1028 if(m < match) 1029 match = m; 1030 } 1031 } else free(rr_name); 1032 lock_rw_unlock(&zones->lock); 1033 } 1034 if(have_name) { 1035 uint8_t* n2; 1036 #ifndef THREADS_DISABLED 1037 struct local_zone* z; 1038 #endif 1039 /* allocate zone of smallest shared topdomain to contain em */ 1040 n2 = nm; 1041 dname_remove_labels(&n2, &nmlen, nmlabs - match); 1042 n2 = memdup(n2, nmlen); 1043 free(nm); 1044 if(!n2) { 1045 log_err("out of memory"); 1046 return 0; 1047 } 1048 log_nametypeclass(VERB_ALGO, "implicit transparent local-zone", 1049 n2, 0, dclass); 1050 if(!( 1051 #ifndef THREADS_DISABLED 1052 z= 1053 #endif 1054 lz_enter_zone_dname(zones, n2, nmlen, match, 1055 local_zone_transparent, dclass))) { 1056 return 0; 1057 } 1058 lock_rw_unlock(&z->lock); 1059 } 1060 if(have_other_classes) { 1061 /* restart to setup other class */ 1062 return lz_setup_implicit(zones, cfg); 1063 } 1064 return 1; 1065 } 1066 1067 /** enter local-zone-tag info */ 1068 static int 1069 lz_enter_zone_tags(struct local_zones* zones, struct config_file* cfg) 1070 { 1071 struct config_strbytelist* p; 1072 int c = 0; 1073 for(p = cfg->local_zone_tags; p; p = p->next) { 1074 if(!lz_enter_zone_tag(zones, p->str, p->str2, p->str2len, 1075 LDNS_RR_CLASS_IN)) 1076 return 0; 1077 c++; 1078 } 1079 if(c) verbose(VERB_ALGO, "applied tags to %d local zones", c); 1080 return 1; 1081 } 1082 1083 /** enter auth data */ 1084 static int 1085 lz_enter_data(struct local_zones* zones, struct config_file* cfg) 1086 { 1087 struct config_strlist* p; 1088 for(p = cfg->local_data; p; p = p->next) { 1089 if(!lz_enter_rr_str(zones, p->str)) 1090 return 0; 1091 } 1092 return 1; 1093 } 1094 1095 /** free memory from config */ 1096 static void 1097 lz_freeup_cfg(struct config_file* cfg) 1098 { 1099 config_deldblstrlist(cfg->local_zones); 1100 cfg->local_zones = NULL; 1101 config_delstrlist(cfg->local_zones_nodefault); 1102 cfg->local_zones_nodefault = NULL; 1103 config_delstrlist(cfg->local_data); 1104 cfg->local_data = NULL; 1105 } 1106 1107 int 1108 local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg) 1109 { 1110 /* create zones from zone statements. */ 1111 if(!lz_enter_zones(zones, cfg)) { 1112 return 0; 1113 } 1114 /* apply default zones+content (unless disabled, or overridden) */ 1115 if(!local_zone_enter_defaults(zones, cfg)) { 1116 return 0; 1117 } 1118 /* enter local zone overrides */ 1119 if(!lz_enter_overrides(zones, cfg)) { 1120 return 0; 1121 } 1122 /* create implicit transparent zone from data. */ 1123 if(!lz_setup_implicit(zones, cfg)) { 1124 return 0; 1125 } 1126 1127 /* setup parent ptrs for lookup during data entry */ 1128 init_parents(zones); 1129 /* insert local zone tags */ 1130 if(!lz_enter_zone_tags(zones, cfg)) { 1131 return 0; 1132 } 1133 /* insert local data */ 1134 if(!lz_enter_data(zones, cfg)) { 1135 return 0; 1136 } 1137 /* freeup memory from cfg struct. */ 1138 lz_freeup_cfg(cfg); 1139 return 1; 1140 } 1141 1142 struct local_zone* 1143 local_zones_lookup(struct local_zones* zones, 1144 uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype) 1145 { 1146 return local_zones_tags_lookup(zones, name, len, labs, 1147 dclass, dtype, NULL, 0, 1); 1148 } 1149 1150 struct local_zone* 1151 local_zones_tags_lookup(struct local_zones* zones, 1152 uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype, 1153 uint8_t* taglist, size_t taglen, int ignoretags) 1154 { 1155 rbnode_type* res = NULL; 1156 struct local_zone *result; 1157 struct local_zone key; 1158 int m; 1159 /* for type DS use a zone higher when on a zonecut */ 1160 if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) { 1161 dname_remove_label(&name, &len); 1162 labs--; 1163 } 1164 key.node.key = &key; 1165 key.dclass = dclass; 1166 key.name = name; 1167 key.namelen = len; 1168 key.namelabs = labs; 1169 rbtree_find_less_equal(&zones->ztree, &key, &res); 1170 result = (struct local_zone*)res; 1171 /* exact or smaller element (or no element) */ 1172 if(!result || result->dclass != dclass) 1173 return NULL; 1174 /* count number of labels matched */ 1175 (void)dname_lab_cmp(result->name, result->namelabs, key.name, 1176 key.namelabs, &m); 1177 while(result) { /* go up until qname is zone or subdomain of zone */ 1178 if(result->namelabs <= m) 1179 if(ignoretags || !result->taglist || 1180 taglist_intersect(result->taglist, 1181 result->taglen, taglist, taglen)) 1182 break; 1183 result = result->parent; 1184 } 1185 return result; 1186 } 1187 1188 struct local_zone* 1189 local_zones_find(struct local_zones* zones, 1190 uint8_t* name, size_t len, int labs, uint16_t dclass) 1191 { 1192 struct local_zone key; 1193 key.node.key = &key; 1194 key.dclass = dclass; 1195 key.name = name; 1196 key.namelen = len; 1197 key.namelabs = labs; 1198 /* exact */ 1199 return (struct local_zone*)rbtree_search(&zones->ztree, &key); 1200 } 1201 1202 struct local_zone* 1203 local_zones_find_le(struct local_zones* zones, 1204 uint8_t* name, size_t len, int labs, uint16_t dclass, 1205 int* exact) 1206 { 1207 struct local_zone key; 1208 rbnode_type *node; 1209 key.node.key = &key; 1210 key.dclass = dclass; 1211 key.name = name; 1212 key.namelen = len; 1213 key.namelabs = labs; 1214 *exact = rbtree_find_less_equal(&zones->ztree, &key, &node); 1215 return (struct local_zone*)node; 1216 } 1217 1218 /** print all RRsets in local zone */ 1219 static void 1220 local_zone_out(struct local_zone* z) 1221 { 1222 struct local_data* d; 1223 struct local_rrset* p; 1224 RBTREE_FOR(d, struct local_data*, &z->data) { 1225 for(p = d->rrsets; p; p = p->next) { 1226 log_nametypeclass(NO_VERBOSE, "rrset", d->name, 1227 ntohs(p->rrset->rk.type), 1228 ntohs(p->rrset->rk.rrset_class)); 1229 } 1230 } 1231 } 1232 1233 void local_zones_print(struct local_zones* zones) 1234 { 1235 struct local_zone* z; 1236 lock_rw_rdlock(&zones->lock); 1237 log_info("number of auth zones %u", (unsigned)zones->ztree.count); 1238 RBTREE_FOR(z, struct local_zone*, &zones->ztree) { 1239 char buf[64]; 1240 lock_rw_rdlock(&z->lock); 1241 snprintf(buf, sizeof(buf), "%s zone", 1242 local_zone_type2str(z->type)); 1243 log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass); 1244 local_zone_out(z); 1245 lock_rw_unlock(&z->lock); 1246 } 1247 lock_rw_unlock(&zones->lock); 1248 } 1249 1250 /** encode answer consisting of 1 rrset */ 1251 static int 1252 local_encode(struct query_info* qinfo, struct module_env* env, 1253 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1254 struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, 1255 int rcode) 1256 { 1257 struct reply_info rep; 1258 uint16_t udpsize; 1259 /* make answer with time=0 for fixed TTL values */ 1260 memset(&rep, 0, sizeof(rep)); 1261 rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode); 1262 rep.qdcount = 1; 1263 if(ansec) 1264 rep.an_numrrsets = 1; 1265 else rep.ns_numrrsets = 1; 1266 rep.rrset_count = 1; 1267 rep.rrsets = &rrset; 1268 udpsize = edns->udp_size; 1269 edns->edns_version = EDNS_ADVERTISED_VERSION; 1270 edns->udp_size = EDNS_ADVERTISED_SIZE; 1271 edns->ext_rcode = 0; 1272 edns->bits &= EDNS_DO; 1273 if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, 1274 repinfo, temp, env->now_tv) || !reply_info_answer_encode(qinfo, &rep, 1275 *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), 1276 buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) { 1277 error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, 1278 *(uint16_t*)sldns_buffer_begin(buf), 1279 sldns_buffer_read_u16_at(buf, 2), edns); 1280 } 1281 return 1; 1282 } 1283 1284 /** encode local error answer */ 1285 static void 1286 local_error_encode(struct query_info* qinfo, struct module_env* env, 1287 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1288 struct regional* temp, int rcode, int r) 1289 { 1290 edns->edns_version = EDNS_ADVERTISED_VERSION; 1291 edns->udp_size = EDNS_ADVERTISED_SIZE; 1292 edns->ext_rcode = 0; 1293 edns->bits &= EDNS_DO; 1294 1295 if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL, 1296 rcode, edns, repinfo, temp, env->now_tv)) 1297 edns->opt_list = NULL; 1298 error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf), 1299 sldns_buffer_read_u16_at(buf, 2), edns); 1300 } 1301 1302 /** find local data tag string match for the given type in the list */ 1303 int 1304 local_data_find_tag_datas(const struct query_info* qinfo, 1305 struct config_strlist* list, struct ub_packed_rrset_key* r, 1306 struct regional* temp) 1307 { 1308 struct config_strlist* p; 1309 char buf[65536]; 1310 uint8_t rr[LDNS_RR_BUF_SIZE]; 1311 size_t len; 1312 int res; 1313 struct packed_rrset_data* d; 1314 for(p=list; p; p=p->next) { 1315 uint16_t rdr_type; 1316 1317 len = sizeof(rr); 1318 /* does this element match the type? */ 1319 snprintf(buf, sizeof(buf), ". %s", p->str); 1320 res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, 1321 NULL, 0, NULL, 0); 1322 if(res != 0) 1323 /* parse errors are already checked before, in 1324 * acllist check_data, skip this for robustness */ 1325 continue; 1326 if(len < 1 /* . */ + 8 /* typeclassttl*/ + 2 /*rdatalen*/) 1327 continue; 1328 rdr_type = sldns_wirerr_get_type(rr, len, 1); 1329 if(rdr_type != qinfo->qtype && rdr_type != LDNS_RR_TYPE_CNAME) 1330 continue; 1331 1332 /* do we have entries already? if not setup key */ 1333 if(r->rk.dname == NULL) { 1334 r->entry.key = r; 1335 r->rk.dname = qinfo->qname; 1336 r->rk.dname_len = qinfo->qname_len; 1337 r->rk.type = htons(rdr_type); 1338 r->rk.rrset_class = htons(qinfo->qclass); 1339 r->rk.flags = 0; 1340 d = (struct packed_rrset_data*)regional_alloc_zero( 1341 temp, sizeof(struct packed_rrset_data) 1342 + sizeof(size_t) + sizeof(uint8_t*) + 1343 sizeof(time_t)); 1344 if(!d) return 0; /* out of memory */ 1345 r->entry.data = d; 1346 d->ttl = sldns_wirerr_get_ttl(rr, len, 1); 1347 d->rr_len = (size_t*)((uint8_t*)d + 1348 sizeof(struct packed_rrset_data)); 1349 d->rr_data = (uint8_t**)&(d->rr_len[1]); 1350 d->rr_ttl = (time_t*)&(d->rr_data[1]); 1351 } 1352 d = (struct packed_rrset_data*)r->entry.data; 1353 /* add entry to the data */ 1354 if(d->count != 0) { 1355 size_t* oldlen = d->rr_len; 1356 uint8_t** olddata = d->rr_data; 1357 time_t* oldttl = d->rr_ttl; 1358 /* increase arrays for lookup */ 1359 /* this is of course slow for very many records, 1360 * but most redirects are expected with few records */ 1361 d->rr_len = (size_t*)regional_alloc_zero(temp, 1362 (d->count+1)*sizeof(size_t)); 1363 d->rr_data = (uint8_t**)regional_alloc_zero(temp, 1364 (d->count+1)*sizeof(uint8_t*)); 1365 d->rr_ttl = (time_t*)regional_alloc_zero(temp, 1366 (d->count+1)*sizeof(time_t)); 1367 if(!d->rr_len || !d->rr_data || !d->rr_ttl) 1368 return 0; /* out of memory */ 1369 /* first one was allocated after struct d, but new 1370 * ones get their own array increment alloc, so 1371 * copy old content */ 1372 memmove(d->rr_len, oldlen, d->count*sizeof(size_t)); 1373 memmove(d->rr_data, olddata, d->count*sizeof(uint8_t*)); 1374 memmove(d->rr_ttl, oldttl, d->count*sizeof(time_t)); 1375 } 1376 1377 d->rr_len[d->count] = sldns_wirerr_get_rdatalen(rr, len, 1)+2; 1378 d->rr_ttl[d->count] = sldns_wirerr_get_ttl(rr, len, 1); 1379 d->rr_data[d->count] = regional_alloc_init(temp, 1380 sldns_wirerr_get_rdatawl(rr, len, 1), 1381 d->rr_len[d->count]); 1382 if(!d->rr_data[d->count]) 1383 return 0; /* out of memory */ 1384 d->count++; 1385 } 1386 if(r->rk.dname) 1387 return 1; 1388 return 0; 1389 } 1390 1391 static int 1392 find_tag_datas(struct query_info* qinfo, struct config_strlist* list, 1393 struct ub_packed_rrset_key* r, struct regional* temp) 1394 { 1395 int result = local_data_find_tag_datas(qinfo, list, r, temp); 1396 1397 /* If we've found a non-exact alias type of local data, make a shallow 1398 * copy of the RRset and remember it in qinfo to complete the alias 1399 * chain later. */ 1400 if(result && qinfo->qtype != LDNS_RR_TYPE_CNAME && 1401 r->rk.type == htons(LDNS_RR_TYPE_CNAME)) { 1402 qinfo->local_alias = 1403 regional_alloc_zero(temp, sizeof(struct local_rrset)); 1404 if(!qinfo->local_alias) 1405 return 0; /* out of memory */ 1406 qinfo->local_alias->rrset = 1407 regional_alloc_init(temp, r, sizeof(*r)); 1408 if(!qinfo->local_alias->rrset) 1409 return 0; /* out of memory */ 1410 } 1411 return result; 1412 } 1413 1414 int 1415 local_data_answer(struct local_zone* z, struct module_env* env, 1416 struct query_info* qinfo, struct edns_data* edns, 1417 struct comm_reply* repinfo, sldns_buffer* buf, 1418 struct regional* temp, int labs, struct local_data** ldp, 1419 enum localzone_type lz_type, int tag, struct config_strlist** tag_datas, 1420 size_t tag_datas_size, char** tagname, int num_tags) 1421 { 1422 struct local_data key; 1423 struct local_data* ld; 1424 struct local_rrset* lr; 1425 key.node.key = &key; 1426 key.name = qinfo->qname; 1427 key.namelen = qinfo->qname_len; 1428 key.namelabs = labs; 1429 if(lz_type == local_zone_redirect || 1430 lz_type == local_zone_inform_redirect) { 1431 key.name = z->name; 1432 key.namelen = z->namelen; 1433 key.namelabs = z->namelabs; 1434 if(tag != -1 && (size_t)tag<tag_datas_size && tag_datas[tag]) { 1435 struct ub_packed_rrset_key r; 1436 memset(&r, 0, sizeof(r)); 1437 if(find_tag_datas(qinfo, tag_datas[tag], &r, temp)) { 1438 verbose(VERB_ALGO, "redirect with tag data [%d] %s", 1439 tag, (tag<num_tags?tagname[tag]:"null")); 1440 1441 /* If we found a matching alias, we should 1442 * use it as part of the answer, but we can't 1443 * encode it until we complete the alias 1444 * chain. */ 1445 if(qinfo->local_alias) 1446 return 1; 1447 return local_encode(qinfo, env, edns, repinfo, buf, temp, 1448 &r, 1, LDNS_RCODE_NOERROR); 1449 } 1450 } 1451 } 1452 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1453 *ldp = ld; 1454 if(!ld) { 1455 return 0; 1456 } 1457 lr = local_data_find_type(ld, qinfo->qtype, 1); 1458 if(!lr) 1459 return 0; 1460 1461 /* Special case for alias matching. See local_data_answer(). */ 1462 if((lz_type == local_zone_redirect || 1463 lz_type == local_zone_inform_redirect) && 1464 qinfo->qtype != LDNS_RR_TYPE_CNAME && 1465 lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) { 1466 uint8_t* ctarget; 1467 size_t ctargetlen = 0; 1468 1469 qinfo->local_alias = 1470 regional_alloc_zero(temp, sizeof(struct local_rrset)); 1471 if(!qinfo->local_alias) 1472 return 0; /* out of memory */ 1473 qinfo->local_alias->rrset = regional_alloc_init( 1474 temp, lr->rrset, sizeof(*lr->rrset)); 1475 if(!qinfo->local_alias->rrset) 1476 return 0; /* out of memory */ 1477 qinfo->local_alias->rrset->rk.dname = qinfo->qname; 1478 qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; 1479 get_cname_target(lr->rrset, &ctarget, &ctargetlen); 1480 if(!ctargetlen) 1481 return 0; /* invalid cname */ 1482 if(dname_is_wild(ctarget)) { 1483 /* synthesize cname target */ 1484 struct packed_rrset_data* d; 1485 /* -3 for wildcard label and root label from qname */ 1486 size_t newtargetlen = qinfo->qname_len + ctargetlen - 3; 1487 1488 log_assert(ctargetlen >= 3); 1489 log_assert(qinfo->qname_len >= 1); 1490 1491 if(newtargetlen > LDNS_MAX_DOMAINLEN) { 1492 qinfo->local_alias = NULL; 1493 local_error_encode(qinfo, env, edns, repinfo, 1494 buf, temp, LDNS_RCODE_YXDOMAIN, 1495 (LDNS_RCODE_YXDOMAIN|BIT_AA)); 1496 return 1; 1497 } 1498 memset(&qinfo->local_alias->rrset->entry, 0, 1499 sizeof(qinfo->local_alias->rrset->entry)); 1500 qinfo->local_alias->rrset->entry.key = 1501 qinfo->local_alias->rrset; 1502 qinfo->local_alias->rrset->entry.hash = 1503 rrset_key_hash(&qinfo->local_alias->rrset->rk); 1504 d = (struct packed_rrset_data*)regional_alloc_zero(temp, 1505 sizeof(struct packed_rrset_data) + sizeof(size_t) + 1506 sizeof(uint8_t*) + sizeof(time_t) + sizeof(uint16_t) 1507 + newtargetlen); 1508 if(!d) 1509 return 0; /* out of memory */ 1510 qinfo->local_alias->rrset->entry.data = d; 1511 d->ttl = 0; /* 0 for synthesized CNAME TTL */ 1512 d->count = 1; 1513 d->rrsig_count = 0; 1514 d->trust = rrset_trust_ans_noAA; 1515 d->rr_len = (size_t*)((uint8_t*)d + 1516 sizeof(struct packed_rrset_data)); 1517 d->rr_len[0] = newtargetlen + sizeof(uint16_t); 1518 packed_rrset_ptr_fixup(d); 1519 d->rr_ttl[0] = d->ttl; 1520 sldns_write_uint16(d->rr_data[0], newtargetlen); 1521 /* write qname */ 1522 memmove(d->rr_data[0] + sizeof(uint16_t), qinfo->qname, 1523 qinfo->qname_len - 1); 1524 /* write cname target wilcard wildcard label */ 1525 memmove(d->rr_data[0] + sizeof(uint16_t) + 1526 qinfo->qname_len - 1, ctarget + 2, 1527 ctargetlen - 2); 1528 } 1529 return 1; 1530 } 1531 if(lz_type == local_zone_redirect || 1532 lz_type == local_zone_inform_redirect) { 1533 /* convert rrset name to query name; like a wildcard */ 1534 struct ub_packed_rrset_key r = *lr->rrset; 1535 r.rk.dname = qinfo->qname; 1536 r.rk.dname_len = qinfo->qname_len; 1537 return local_encode(qinfo, env, edns, repinfo, buf, temp, &r, 1, 1538 LDNS_RCODE_NOERROR); 1539 } 1540 return local_encode(qinfo, env, edns, repinfo, buf, temp, lr->rrset, 1, 1541 LDNS_RCODE_NOERROR); 1542 } 1543 1544 /** 1545 * See if the local zone does not cover the name, eg. the name is not 1546 * in the zone and the zone is transparent */ 1547 static int 1548 local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo, 1549 int labs) 1550 { 1551 struct local_data key; 1552 struct local_data* ld = NULL; 1553 struct local_rrset* lr = NULL; 1554 if(z->type == local_zone_always_transparent) 1555 return 1; 1556 if(z->type != local_zone_transparent 1557 && z->type != local_zone_typetransparent 1558 && z->type != local_zone_inform) 1559 return 0; 1560 key.node.key = &key; 1561 key.name = qinfo->qname; 1562 key.namelen = qinfo->qname_len; 1563 key.namelabs = labs; 1564 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1565 if(z->type == local_zone_transparent || z->type == local_zone_inform) 1566 return (ld == NULL); 1567 if(ld) 1568 lr = local_data_find_type(ld, qinfo->qtype, 1); 1569 /* local_zone_typetransparent */ 1570 return (lr == NULL); 1571 } 1572 1573 int 1574 local_zones_zone_answer(struct local_zone* z, struct module_env* env, 1575 struct query_info* qinfo, struct edns_data* edns, 1576 struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp, 1577 struct local_data* ld, enum localzone_type lz_type) 1578 { 1579 if(lz_type == local_zone_deny || 1580 lz_type == local_zone_always_deny || 1581 lz_type == local_zone_inform_deny) { 1582 /** no reply at all, signal caller by clearing buffer. */ 1583 sldns_buffer_clear(buf); 1584 sldns_buffer_flip(buf); 1585 return 1; 1586 } else if(lz_type == local_zone_refuse 1587 || lz_type == local_zone_always_refuse) { 1588 local_error_encode(qinfo, env, edns, repinfo, buf, temp, 1589 LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA)); 1590 return 1; 1591 } else if(lz_type == local_zone_static || 1592 lz_type == local_zone_redirect || 1593 lz_type == local_zone_inform_redirect || 1594 lz_type == local_zone_always_nxdomain || 1595 lz_type == local_zone_always_nodata) { 1596 /* for static, reply nodata or nxdomain 1597 * for redirect, reply nodata */ 1598 /* no additional section processing, 1599 * cname, dname or wildcard processing, 1600 * or using closest match for NSEC. 1601 * or using closest match for returning delegation downwards 1602 */ 1603 int rcode = (ld || lz_type == local_zone_redirect || 1604 lz_type == local_zone_inform_redirect || 1605 lz_type == local_zone_always_nodata)? 1606 LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN; 1607 if(z->soa && z->soa_negative) 1608 return local_encode(qinfo, env, edns, repinfo, buf, temp, 1609 z->soa_negative, 0, rcode); 1610 local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, 1611 (rcode|BIT_AA)); 1612 return 1; 1613 } else if(lz_type == local_zone_typetransparent 1614 || lz_type == local_zone_always_transparent) { 1615 /* no NODATA or NXDOMAINS for this zone type */ 1616 return 0; 1617 } else if(lz_type == local_zone_always_null) { 1618 /* 0.0.0.0 or ::0 or noerror/nodata for this zone type, 1619 * used for blocklists. */ 1620 if(qinfo->qtype == LDNS_RR_TYPE_A || 1621 qinfo->qtype == LDNS_RR_TYPE_AAAA) { 1622 struct ub_packed_rrset_key lrr; 1623 struct packed_rrset_data d; 1624 time_t rr_ttl = 3600; 1625 size_t rr_len = 0; 1626 uint8_t rr_data[2+16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 1627 uint8_t* rr_datas = rr_data; 1628 memset(&lrr, 0, sizeof(lrr)); 1629 memset(&d, 0, sizeof(d)); 1630 lrr.entry.data = &d; 1631 lrr.rk.dname = qinfo->qname; 1632 lrr.rk.dname_len = qinfo->qname_len; 1633 lrr.rk.type = htons(qinfo->qtype); 1634 lrr.rk.rrset_class = htons(qinfo->qclass); 1635 if(qinfo->qtype == LDNS_RR_TYPE_A) { 1636 rr_len = 4; 1637 sldns_write_uint16(rr_data, rr_len); 1638 rr_len += 2; 1639 } else { 1640 rr_len = 16; 1641 sldns_write_uint16(rr_data, rr_len); 1642 rr_len += 2; 1643 } 1644 d.ttl = rr_ttl; 1645 d.count = 1; 1646 d.rr_len = &rr_len; 1647 d.rr_data = &rr_datas; 1648 d.rr_ttl = &rr_ttl; 1649 return local_encode(qinfo, env, edns, repinfo, buf, temp, 1650 &lrr, 1, LDNS_RCODE_NOERROR); 1651 } else { 1652 local_error_encode(qinfo, env, edns, repinfo, buf, 1653 temp, LDNS_RCODE_NOERROR, 1654 (LDNS_RCODE_NOERROR|BIT_AA)); 1655 } 1656 return 1; 1657 } 1658 /* else lz_type == local_zone_transparent */ 1659 1660 /* if the zone is transparent and the name exists, but the type 1661 * does not, then we should make this noerror/nodata */ 1662 if(ld && ld->rrsets) { 1663 int rcode = LDNS_RCODE_NOERROR; 1664 if(z->soa && z->soa_negative) 1665 return local_encode(qinfo, env, edns, repinfo, buf, temp, 1666 z->soa_negative, 0, rcode); 1667 local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, 1668 (rcode|BIT_AA)); 1669 return 1; 1670 } 1671 1672 /* stop here, and resolve further on */ 1673 return 0; 1674 } 1675 1676 /** print log information for an inform zone query */ 1677 static void 1678 lz_inform_print(struct local_zone* z, struct query_info* qinfo, 1679 struct comm_reply* repinfo) 1680 { 1681 char ip[128], txt[512]; 1682 char zname[LDNS_MAX_DOMAINLEN+1]; 1683 uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); 1684 dname_str(z->name, zname); 1685 addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); 1686 snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip, 1687 (unsigned)port); 1688 log_nametypeclass(NO_VERBOSE, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); 1689 } 1690 1691 static enum localzone_type 1692 lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2, 1693 uint8_t *tagactions, size_t tagactionssize, enum localzone_type lzt, 1694 struct comm_reply* repinfo, struct rbtree_type* override_tree, 1695 int* tag, char** tagname, int num_tags) 1696 { 1697 struct local_zone_override* lzo; 1698 if(repinfo && override_tree) { 1699 lzo = (struct local_zone_override*)addr_tree_lookup( 1700 override_tree, &repinfo->addr, repinfo->addrlen); 1701 if(lzo && lzo->type) { 1702 verbose(VERB_ALGO, "local zone override to type %s", 1703 local_zone_type2str(lzo->type)); 1704 return lzo->type; 1705 } 1706 } 1707 if(!taglist || !taglist2) 1708 return lzt; 1709 return local_data_find_tag_action(taglist, taglen, taglist2, taglen2, 1710 tagactions, tagactionssize, lzt, tag, tagname, num_tags); 1711 } 1712 1713 enum localzone_type 1714 local_data_find_tag_action(const uint8_t* taglist, size_t taglen, 1715 const uint8_t* taglist2, size_t taglen2, const uint8_t* tagactions, 1716 size_t tagactionssize, enum localzone_type lzt, int* tag, 1717 char* const* tagname, int num_tags) 1718 { 1719 size_t i, j; 1720 uint8_t tagmatch; 1721 1722 for(i=0; i<taglen && i<taglen2; i++) { 1723 tagmatch = (taglist[i] & taglist2[i]); 1724 for(j=0; j<8 && tagmatch>0; j++) { 1725 if((tagmatch & 0x1)) { 1726 *tag = (int)(i*8+j); 1727 verbose(VERB_ALGO, "matched tag [%d] %s", 1728 *tag, (*tag<num_tags?tagname[*tag]:"null")); 1729 /* does this tag have a tag action? */ 1730 if(i*8+j < tagactionssize && tagactions 1731 && tagactions[i*8+j] != 0) { 1732 verbose(VERB_ALGO, "tag action [%d] %s to type %s", 1733 *tag, (*tag<num_tags?tagname[*tag]:"null"), 1734 local_zone_type2str( 1735 (enum localzone_type) 1736 tagactions[i*8+j])); 1737 return (enum localzone_type)tagactions[i*8+j]; 1738 } 1739 return lzt; 1740 } 1741 tagmatch >>= 1; 1742 } 1743 } 1744 return lzt; 1745 } 1746 1747 int 1748 local_zones_answer(struct local_zones* zones, struct module_env* env, 1749 struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, 1750 struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, 1751 size_t taglen, uint8_t* tagactions, size_t tagactionssize, 1752 struct config_strlist** tag_datas, size_t tag_datas_size, 1753 char** tagname, int num_tags, struct view* view) 1754 { 1755 /* see if query is covered by a zone, 1756 * if so: - try to match (exact) local data 1757 * - look at zone type for negative response. */ 1758 int labs = dname_count_labels(qinfo->qname); 1759 struct local_data* ld = NULL; 1760 struct local_zone* z = NULL; 1761 enum localzone_type lzt = local_zone_transparent; 1762 int r, tag = -1; 1763 1764 if(view) { 1765 lock_rw_rdlock(&view->lock); 1766 if(view->local_zones && 1767 (z = local_zones_lookup(view->local_zones, 1768 qinfo->qname, qinfo->qname_len, labs, 1769 qinfo->qclass, qinfo->qtype))) { 1770 lock_rw_rdlock(&z->lock); 1771 lzt = z->type; 1772 } 1773 if(lzt == local_zone_noview) { 1774 lock_rw_unlock(&z->lock); 1775 z = NULL; 1776 } 1777 if(z && (lzt == local_zone_transparent || 1778 lzt == local_zone_typetransparent || 1779 lzt == local_zone_inform || 1780 lzt == local_zone_always_transparent) && 1781 local_zone_does_not_cover(z, qinfo, labs)) { 1782 lock_rw_unlock(&z->lock); 1783 z = NULL; 1784 } 1785 if(view->local_zones && !z && !view->isfirst){ 1786 lock_rw_unlock(&view->lock); 1787 return 0; 1788 } 1789 if(z && verbosity >= VERB_ALGO) { 1790 char zname[255+1]; 1791 dname_str(z->name, zname); 1792 verbose(VERB_ALGO, "using localzone %s %s from view %s", 1793 zname, local_zone_type2str(lzt), view->name); 1794 } 1795 lock_rw_unlock(&view->lock); 1796 } 1797 if(!z) { 1798 /* try global local_zones tree */ 1799 lock_rw_rdlock(&zones->lock); 1800 if(!(z = local_zones_tags_lookup(zones, qinfo->qname, 1801 qinfo->qname_len, labs, qinfo->qclass, qinfo->qtype, 1802 taglist, taglen, 0))) { 1803 lock_rw_unlock(&zones->lock); 1804 return 0; 1805 } 1806 lock_rw_rdlock(&z->lock); 1807 lzt = lz_type(taglist, taglen, z->taglist, z->taglen, 1808 tagactions, tagactionssize, z->type, repinfo, 1809 z->override_tree, &tag, tagname, num_tags); 1810 lock_rw_unlock(&zones->lock); 1811 if(z && verbosity >= VERB_ALGO) { 1812 char zname[255+1]; 1813 dname_str(z->name, zname); 1814 verbose(VERB_ALGO, "using localzone %s %s", zname, 1815 local_zone_type2str(lzt)); 1816 } 1817 } 1818 if((env->cfg->log_local_actions || 1819 lzt == local_zone_inform || 1820 lzt == local_zone_inform_deny || 1821 lzt == local_zone_inform_redirect) 1822 && repinfo) 1823 lz_inform_print(z, qinfo, repinfo); 1824 1825 if(lzt != local_zone_always_refuse 1826 && lzt != local_zone_always_transparent 1827 && lzt != local_zone_always_nxdomain 1828 && lzt != local_zone_always_nodata 1829 && lzt != local_zone_always_deny 1830 && local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs, 1831 &ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) { 1832 lock_rw_unlock(&z->lock); 1833 /* We should tell the caller that encode is deferred if we found 1834 * a local alias. */ 1835 return !qinfo->local_alias; 1836 } 1837 r = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt); 1838 lock_rw_unlock(&z->lock); 1839 return r && !qinfo->local_alias; /* see above */ 1840 } 1841 1842 const char* local_zone_type2str(enum localzone_type t) 1843 { 1844 switch(t) { 1845 case local_zone_unset: return "unset"; 1846 case local_zone_deny: return "deny"; 1847 case local_zone_refuse: return "refuse"; 1848 case local_zone_redirect: return "redirect"; 1849 case local_zone_transparent: return "transparent"; 1850 case local_zone_typetransparent: return "typetransparent"; 1851 case local_zone_static: return "static"; 1852 case local_zone_nodefault: return "nodefault"; 1853 case local_zone_inform: return "inform"; 1854 case local_zone_inform_deny: return "inform_deny"; 1855 case local_zone_inform_redirect: return "inform_redirect"; 1856 case local_zone_always_transparent: return "always_transparent"; 1857 case local_zone_always_refuse: return "always_refuse"; 1858 case local_zone_always_nxdomain: return "always_nxdomain"; 1859 case local_zone_always_nodata: return "always_nodata"; 1860 case local_zone_always_deny: return "always_deny"; 1861 case local_zone_always_null: return "always_null"; 1862 case local_zone_noview: return "noview"; 1863 case local_zone_invalid: return "invalid"; 1864 } 1865 return "badtyped"; 1866 } 1867 1868 int local_zone_str2type(const char* type, enum localzone_type* t) 1869 { 1870 if(strcmp(type, "deny") == 0) 1871 *t = local_zone_deny; 1872 else if(strcmp(type, "refuse") == 0) 1873 *t = local_zone_refuse; 1874 else if(strcmp(type, "static") == 0) 1875 *t = local_zone_static; 1876 else if(strcmp(type, "transparent") == 0) 1877 *t = local_zone_transparent; 1878 else if(strcmp(type, "typetransparent") == 0) 1879 *t = local_zone_typetransparent; 1880 else if(strcmp(type, "redirect") == 0) 1881 *t = local_zone_redirect; 1882 else if(strcmp(type, "inform") == 0) 1883 *t = local_zone_inform; 1884 else if(strcmp(type, "inform_deny") == 0) 1885 *t = local_zone_inform_deny; 1886 else if(strcmp(type, "inform_redirect") == 0) 1887 *t = local_zone_inform_redirect; 1888 else if(strcmp(type, "always_transparent") == 0) 1889 *t = local_zone_always_transparent; 1890 else if(strcmp(type, "always_refuse") == 0) 1891 *t = local_zone_always_refuse; 1892 else if(strcmp(type, "always_nxdomain") == 0) 1893 *t = local_zone_always_nxdomain; 1894 else if(strcmp(type, "always_nodata") == 0) 1895 *t = local_zone_always_nodata; 1896 else if(strcmp(type, "always_deny") == 0) 1897 *t = local_zone_always_deny; 1898 else if(strcmp(type, "always_null") == 0) 1899 *t = local_zone_always_null; 1900 else if(strcmp(type, "noview") == 0) 1901 *t = local_zone_noview; 1902 else if(strcmp(type, "nodefault") == 0) 1903 *t = local_zone_nodefault; 1904 else return 0; 1905 return 1; 1906 } 1907 1908 /** iterate over the kiddies of the given name and set their parent ptr */ 1909 static void 1910 set_kiddo_parents(struct local_zone* z, struct local_zone* match, 1911 struct local_zone* newp) 1912 { 1913 /* both zones and z are locked already */ 1914 /* in the sorted rbtree, the kiddies of z are located after z */ 1915 /* z must be present in the tree */ 1916 struct local_zone* p = z; 1917 p = (struct local_zone*)rbtree_next(&p->node); 1918 while(p!=(struct local_zone*)RBTREE_NULL && 1919 p->dclass == z->dclass && dname_strict_subdomain(p->name, 1920 p->namelabs, z->name, z->namelabs)) { 1921 /* update parent ptr */ 1922 /* only when matches with existing parent pointer, so that 1923 * deeper child structures are not touched, i.e. 1924 * update of x, and a.x, b.x, f.b.x, g.b.x, c.x, y 1925 * gets to update a.x, b.x and c.x */ 1926 lock_rw_wrlock(&p->lock); 1927 if(p->parent == match) 1928 p->parent = newp; 1929 lock_rw_unlock(&p->lock); 1930 p = (struct local_zone*)rbtree_next(&p->node); 1931 } 1932 } 1933 1934 struct local_zone* local_zones_add_zone(struct local_zones* zones, 1935 uint8_t* name, size_t len, int labs, uint16_t dclass, 1936 enum localzone_type tp) 1937 { 1938 /* create */ 1939 struct local_zone* z = local_zone_create(name, len, labs, tp, dclass); 1940 if(!z) { 1941 free(name); 1942 return NULL; 1943 } 1944 lock_rw_wrlock(&z->lock); 1945 1946 /* find the closest parent */ 1947 z->parent = local_zones_find(zones, name, len, labs, dclass); 1948 1949 /* insert into the tree */ 1950 if(!rbtree_insert(&zones->ztree, &z->node)) { 1951 /* duplicate entry! */ 1952 lock_rw_unlock(&z->lock); 1953 local_zone_delete(z); 1954 log_err("internal: duplicate entry in local_zones_add_zone"); 1955 return NULL; 1956 } 1957 1958 /* set parent pointers right */ 1959 set_kiddo_parents(z, z->parent, z); 1960 1961 lock_rw_unlock(&z->lock); 1962 return z; 1963 } 1964 1965 void local_zones_del_zone(struct local_zones* zones, struct local_zone* z) 1966 { 1967 /* fix up parents in tree */ 1968 lock_rw_wrlock(&z->lock); 1969 set_kiddo_parents(z, z, z->parent); 1970 1971 /* remove from tree */ 1972 (void)rbtree_delete(&zones->ztree, z); 1973 1974 /* delete the zone */ 1975 lock_rw_unlock(&z->lock); 1976 local_zone_delete(z); 1977 } 1978 1979 int 1980 local_zones_add_RR(struct local_zones* zones, const char* rr) 1981 { 1982 uint8_t* rr_name; 1983 uint16_t rr_class, rr_type; 1984 size_t len; 1985 int labs; 1986 struct local_zone* z; 1987 int r; 1988 if(!get_rr_nameclass(rr, &rr_name, &rr_class, &rr_type)) { 1989 return 0; 1990 } 1991 labs = dname_count_size_labels(rr_name, &len); 1992 /* could first try readlock then get writelock if zone does not exist, 1993 * but we do not add enough RRs (from multiple threads) to optimize */ 1994 lock_rw_wrlock(&zones->lock); 1995 z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type); 1996 if(!z) { 1997 z = local_zones_add_zone(zones, rr_name, len, labs, rr_class, 1998 local_zone_transparent); 1999 if(!z) { 2000 lock_rw_unlock(&zones->lock); 2001 return 0; 2002 } 2003 } else { 2004 free(rr_name); 2005 } 2006 lock_rw_wrlock(&z->lock); 2007 lock_rw_unlock(&zones->lock); 2008 r = lz_enter_rr_into_zone(z, rr); 2009 lock_rw_unlock(&z->lock); 2010 return r; 2011 } 2012 2013 /** returns true if the node is terminal so no deeper domain names exist */ 2014 static int 2015 is_terminal(struct local_data* d) 2016 { 2017 /* for empty nonterminals, the deeper domain names are sorted 2018 * right after them, so simply check the next name in the tree 2019 */ 2020 struct local_data* n = (struct local_data*)rbtree_next(&d->node); 2021 if(n == (struct local_data*)RBTREE_NULL) 2022 return 1; /* last in tree, no deeper node */ 2023 if(dname_strict_subdomain(n->name, n->namelabs, d->name, d->namelabs)) 2024 return 0; /* there is a deeper node */ 2025 return 1; 2026 } 2027 2028 /** delete empty terminals from tree when final data is deleted */ 2029 static void 2030 del_empty_term(struct local_zone* z, struct local_data* d, 2031 uint8_t* name, size_t len, int labs) 2032 { 2033 while(d && d->rrsets == NULL && is_terminal(d)) { 2034 /* is this empty nonterminal? delete */ 2035 /* note, no memory recycling in zone region */ 2036 (void)rbtree_delete(&z->data, d); 2037 2038 /* go up and to the next label */ 2039 if(dname_is_root(name)) 2040 return; 2041 dname_remove_label(&name, &len); 2042 labs--; 2043 d = local_zone_find_data(z, name, len, labs); 2044 } 2045 } 2046 2047 /** find and remove type from list in domain struct */ 2048 static void 2049 del_local_rrset(struct local_data* d, uint16_t dtype) 2050 { 2051 struct local_rrset* prev=NULL, *p=d->rrsets; 2052 while(p && ntohs(p->rrset->rk.type) != dtype) { 2053 prev = p; 2054 p = p->next; 2055 } 2056 if(!p) 2057 return; /* rrset type not found */ 2058 /* unlink it */ 2059 if(prev) prev->next = p->next; 2060 else d->rrsets = p->next; 2061 /* no memory recycling for zone deletions ... */ 2062 } 2063 2064 void local_zones_del_data(struct local_zones* zones, 2065 uint8_t* name, size_t len, int labs, uint16_t dclass) 2066 { 2067 /* find zone */ 2068 struct local_zone* z; 2069 struct local_data* d; 2070 2071 /* remove DS */ 2072 lock_rw_rdlock(&zones->lock); 2073 z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS); 2074 if(z) { 2075 lock_rw_wrlock(&z->lock); 2076 d = local_zone_find_data(z, name, len, labs); 2077 if(d) { 2078 del_local_rrset(d, LDNS_RR_TYPE_DS); 2079 del_empty_term(z, d, name, len, labs); 2080 } 2081 lock_rw_unlock(&z->lock); 2082 } 2083 lock_rw_unlock(&zones->lock); 2084 2085 /* remove other types */ 2086 lock_rw_rdlock(&zones->lock); 2087 z = local_zones_lookup(zones, name, len, labs, dclass, 0); 2088 if(!z) { 2089 /* no such zone, we're done */ 2090 lock_rw_unlock(&zones->lock); 2091 return; 2092 } 2093 lock_rw_wrlock(&z->lock); 2094 lock_rw_unlock(&zones->lock); 2095 2096 /* find the domain */ 2097 d = local_zone_find_data(z, name, len, labs); 2098 if(d) { 2099 /* no memory recycling for zone deletions ... */ 2100 d->rrsets = NULL; 2101 /* did we delete the soa record ? */ 2102 if(query_dname_compare(d->name, z->name) == 0) { 2103 z->soa = NULL; 2104 z->soa_negative = NULL; 2105 } 2106 2107 /* cleanup the empty nonterminals for this name */ 2108 del_empty_term(z, d, name, len, labs); 2109 } 2110 2111 lock_rw_unlock(&z->lock); 2112 } 2113