1 /* $NetBSD: rpz.c,v 1.13 2023/06/26 22:03:00 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <inttypes.h> 19 #include <stdbool.h> 20 #include <stdlib.h> 21 22 #include <isc/buffer.h> 23 #include <isc/mem.h> 24 #include <isc/net.h> 25 #include <isc/netaddr.h> 26 #include <isc/print.h> 27 #include <isc/rwlock.h> 28 #include <isc/string.h> 29 #include <isc/task.h> 30 #include <isc/util.h> 31 32 #include <dns/db.h> 33 #include <dns/dbiterator.h> 34 #include <dns/dnsrps.h> 35 #include <dns/events.h> 36 #include <dns/fixedname.h> 37 #include <dns/log.h> 38 #include <dns/rbt.h> 39 #include <dns/rdata.h> 40 #include <dns/rdataset.h> 41 #include <dns/rdatasetiter.h> 42 #include <dns/rdatastruct.h> 43 #include <dns/result.h> 44 #include <dns/rpz.h> 45 #include <dns/view.h> 46 47 /* 48 * Parallel radix trees for databases of response policy IP addresses 49 * 50 * The radix or patricia trees are somewhat specialized to handle response 51 * policy addresses by representing the two sets of IP addresses and name 52 * server IP addresses in a single tree. One set of IP addresses is 53 * for rpz-ip policies or policies triggered by addresses in A or 54 * AAAA records in responses. 55 * The second set is for rpz-nsip policies or policies triggered by addresses 56 * in A or AAAA records for NS records that are authorities for responses. 57 * 58 * Each leaf indicates that an IP address is listed in the IP address or the 59 * name server IP address policy sub-zone (or both) of the corresponding 60 * response policy zone. The policy data such as a CNAME or an A record 61 * is kept in the policy zone. After an IP address has been found in a radix 62 * tree, the node in the policy zone's database is found by converting 63 * the IP address to a domain name in a canonical form. 64 * 65 * 66 * The response policy zone canonical form of an IPv6 address is one of: 67 * prefix.W.W.W.W.W.W.W.W 68 * prefix.WORDS.zz 69 * prefix.WORDS.zz.WORDS 70 * prefix.zz.WORDS 71 * where 72 * prefix is the prefix length of the IPv6 address between 1 and 128 73 * W is a number between 0 and 65535 74 * WORDS is one or more numbers W separated with "." 75 * zz corresponds to :: in the standard IPv6 text representation 76 * 77 * The canonical form of IPv4 addresses is: 78 * prefix.B.B.B.B 79 * where 80 * prefix is the prefix length of the address between 1 and 32 81 * B is a number between 0 and 255 82 * 83 * Names for IPv4 addresses are distinguished from IPv6 addresses by having 84 * 5 labels all of which are numbers, and a prefix between 1 and 32. 85 */ 86 87 /* 88 * Nodes hashtable calculation parameters 89 */ 90 #define DNS_RPZ_HTSIZE_MAX 24 91 #define DNS_RPZ_HTSIZE_DIV 3 92 93 /* 94 * Maximum number of nodes to process per quantum 95 */ 96 #define DNS_RPZ_QUANTUM 1024 97 98 static void 99 dns_rpz_update_from_db(dns_rpz_zone_t *rpz); 100 101 static void 102 dns_rpz_update_taskaction(isc_task_t *task, isc_event_t *event); 103 104 /* 105 * Use a private definition of IPv6 addresses because s6_addr32 is not 106 * always defined and our IPv6 addresses are in non-standard byte order 107 */ 108 typedef uint32_t dns_rpz_cidr_word_t; 109 #define DNS_RPZ_CIDR_WORD_BITS ((int)sizeof(dns_rpz_cidr_word_t) * 8) 110 #define DNS_RPZ_CIDR_KEY_BITS ((int)sizeof(dns_rpz_cidr_key_t) * 8) 111 #define DNS_RPZ_CIDR_WORDS (128 / DNS_RPZ_CIDR_WORD_BITS) 112 typedef struct { 113 dns_rpz_cidr_word_t w[DNS_RPZ_CIDR_WORDS]; 114 } dns_rpz_cidr_key_t; 115 116 #define ADDR_V4MAPPED 0xffff 117 #define KEY_IS_IPV4(prefix, ip) \ 118 ((prefix) >= 96 && (ip)->w[0] == 0 && (ip)->w[1] == 0 && \ 119 (ip)->w[2] == ADDR_V4MAPPED) 120 121 #define DNS_RPZ_WORD_MASK(b) \ 122 ((b) == 0 ? (dns_rpz_cidr_word_t)(-1) \ 123 : ((dns_rpz_cidr_word_t)(-1) \ 124 << (DNS_RPZ_CIDR_WORD_BITS - (b)))) 125 126 /* 127 * Get bit #n from the array of words of an IP address. 128 */ 129 #define DNS_RPZ_IP_BIT(ip, n) \ 130 (1 & ((ip)->w[(n) / DNS_RPZ_CIDR_WORD_BITS] >> \ 131 (DNS_RPZ_CIDR_WORD_BITS - 1 - ((n) % DNS_RPZ_CIDR_WORD_BITS)))) 132 133 /* 134 * A triplet of arrays of bits flagging the existence of 135 * client-IP, IP, and NSIP policy triggers. 136 */ 137 typedef struct dns_rpz_addr_zbits dns_rpz_addr_zbits_t; 138 struct dns_rpz_addr_zbits { 139 dns_rpz_zbits_t client_ip; 140 dns_rpz_zbits_t ip; 141 dns_rpz_zbits_t nsip; 142 }; 143 144 /* 145 * A CIDR or radix tree node. 146 */ 147 struct dns_rpz_cidr_node { 148 dns_rpz_cidr_node_t *parent; 149 dns_rpz_cidr_node_t *child[2]; 150 dns_rpz_cidr_key_t ip; 151 dns_rpz_prefix_t prefix; 152 dns_rpz_addr_zbits_t set; 153 dns_rpz_addr_zbits_t sum; 154 }; 155 156 /* 157 * A pair of arrays of bits flagging the existence of 158 * QNAME and NSDNAME policy triggers. 159 */ 160 typedef struct dns_rpz_nm_zbits dns_rpz_nm_zbits_t; 161 struct dns_rpz_nm_zbits { 162 dns_rpz_zbits_t qname; 163 dns_rpz_zbits_t ns; 164 }; 165 166 /* 167 * The data in a RBT node has two pairs of bits for policy zones. 168 * One pair is for the corresponding name of the node such as example.com 169 * and the other pair is for a wildcard child such as *.example.com. 170 */ 171 typedef struct dns_rpz_nm_data dns_rpz_nm_data_t; 172 struct dns_rpz_nm_data { 173 dns_rpz_nm_zbits_t set; 174 dns_rpz_nm_zbits_t wild; 175 }; 176 177 static void 178 rpz_detach(dns_rpz_zone_t **rpzp); 179 180 static void 181 rpz_detach_rpzs(dns_rpz_zones_t **rpzsp); 182 183 #if 0 184 /* 185 * Catch a name while debugging. 186 */ 187 static void 188 catch_name(const dns_name_t *src_name, const char *tgt, const char *str) { 189 dns_fixedname_t tgt_namef; 190 dns_name_t *tgt_name; 191 192 tgt_name = dns_fixedname_initname(&tgt_namef); 193 dns_name_fromstring(tgt_name, tgt, DNS_NAME_DOWNCASE, NULL); 194 if (dns_name_equal(src_name, tgt_name)) { 195 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 196 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 197 "rpz hit failed: %s %s", str, tgt); 198 } 199 } 200 #endif /* if 0 */ 201 202 const char * 203 dns_rpz_type2str(dns_rpz_type_t type) { 204 switch (type) { 205 case DNS_RPZ_TYPE_CLIENT_IP: 206 return ("CLIENT-IP"); 207 case DNS_RPZ_TYPE_QNAME: 208 return ("QNAME"); 209 case DNS_RPZ_TYPE_IP: 210 return ("IP"); 211 case DNS_RPZ_TYPE_NSIP: 212 return ("NSIP"); 213 case DNS_RPZ_TYPE_NSDNAME: 214 return ("NSDNAME"); 215 case DNS_RPZ_TYPE_BAD: 216 break; 217 } 218 FATAL_ERROR(__FILE__, __LINE__, "impossible rpz type %d", type); 219 return ("impossible"); 220 } 221 222 dns_rpz_policy_t 223 dns_rpz_str2policy(const char *str) { 224 static struct { 225 const char *str; 226 dns_rpz_policy_t policy; 227 } tbl[] = { 228 { "given", DNS_RPZ_POLICY_GIVEN }, 229 { "disabled", DNS_RPZ_POLICY_DISABLED }, 230 { "passthru", DNS_RPZ_POLICY_PASSTHRU }, 231 { "drop", DNS_RPZ_POLICY_DROP }, 232 { "tcp-only", DNS_RPZ_POLICY_TCP_ONLY }, 233 { "nxdomain", DNS_RPZ_POLICY_NXDOMAIN }, 234 { "nodata", DNS_RPZ_POLICY_NODATA }, 235 { "cname", DNS_RPZ_POLICY_CNAME }, 236 { "no-op", DNS_RPZ_POLICY_PASSTHRU }, /* old passthru */ 237 }; 238 unsigned int n; 239 240 if (str == NULL) { 241 return (DNS_RPZ_POLICY_ERROR); 242 } 243 for (n = 0; n < sizeof(tbl) / sizeof(tbl[0]); ++n) { 244 if (!strcasecmp(tbl[n].str, str)) { 245 return (tbl[n].policy); 246 } 247 } 248 return (DNS_RPZ_POLICY_ERROR); 249 } 250 251 const char * 252 dns_rpz_policy2str(dns_rpz_policy_t policy) { 253 const char *str; 254 255 switch (policy) { 256 case DNS_RPZ_POLICY_PASSTHRU: 257 str = "PASSTHRU"; 258 break; 259 case DNS_RPZ_POLICY_DROP: 260 str = "DROP"; 261 break; 262 case DNS_RPZ_POLICY_TCP_ONLY: 263 str = "TCP-ONLY"; 264 break; 265 case DNS_RPZ_POLICY_NXDOMAIN: 266 str = "NXDOMAIN"; 267 break; 268 case DNS_RPZ_POLICY_NODATA: 269 str = "NODATA"; 270 break; 271 case DNS_RPZ_POLICY_RECORD: 272 str = "Local-Data"; 273 break; 274 case DNS_RPZ_POLICY_CNAME: 275 case DNS_RPZ_POLICY_WILDCNAME: 276 str = "CNAME"; 277 break; 278 case DNS_RPZ_POLICY_MISS: 279 str = "MISS"; 280 break; 281 case DNS_RPZ_POLICY_DNS64: 282 str = "DNS64"; 283 break; 284 case DNS_RPZ_POLICY_ERROR: 285 str = "ERROR"; 286 break; 287 default: 288 UNREACHABLE(); 289 } 290 return (str); 291 } 292 293 /* 294 * Return the bit number of the highest set bit in 'zbit'. 295 * (for example, 0x01 returns 0, 0xFF returns 7, etc.) 296 */ 297 static int 298 zbit_to_num(dns_rpz_zbits_t zbit) { 299 dns_rpz_num_t rpz_num; 300 301 REQUIRE(zbit != 0); 302 rpz_num = 0; 303 if ((zbit & 0xffffffff00000000ULL) != 0) { 304 zbit >>= 32; 305 rpz_num += 32; 306 } 307 if ((zbit & 0xffff0000) != 0) { 308 zbit >>= 16; 309 rpz_num += 16; 310 } 311 if ((zbit & 0xff00) != 0) { 312 zbit >>= 8; 313 rpz_num += 8; 314 } 315 if ((zbit & 0xf0) != 0) { 316 zbit >>= 4; 317 rpz_num += 4; 318 } 319 if ((zbit & 0xc) != 0) { 320 zbit >>= 2; 321 rpz_num += 2; 322 } 323 if ((zbit & 2) != 0) { 324 ++rpz_num; 325 } 326 return (rpz_num); 327 } 328 329 /* 330 * Make a set of bit masks given one or more bits and their type. 331 */ 332 static void 333 make_addr_set(dns_rpz_addr_zbits_t *tgt_set, dns_rpz_zbits_t zbits, 334 dns_rpz_type_t type) { 335 switch (type) { 336 case DNS_RPZ_TYPE_CLIENT_IP: 337 tgt_set->client_ip = zbits; 338 tgt_set->ip = 0; 339 tgt_set->nsip = 0; 340 break; 341 case DNS_RPZ_TYPE_IP: 342 tgt_set->client_ip = 0; 343 tgt_set->ip = zbits; 344 tgt_set->nsip = 0; 345 break; 346 case DNS_RPZ_TYPE_NSIP: 347 tgt_set->client_ip = 0; 348 tgt_set->ip = 0; 349 tgt_set->nsip = zbits; 350 break; 351 default: 352 UNREACHABLE(); 353 } 354 } 355 356 static void 357 make_nm_set(dns_rpz_nm_zbits_t *tgt_set, dns_rpz_num_t rpz_num, 358 dns_rpz_type_t type) { 359 switch (type) { 360 case DNS_RPZ_TYPE_QNAME: 361 tgt_set->qname = DNS_RPZ_ZBIT(rpz_num); 362 tgt_set->ns = 0; 363 break; 364 case DNS_RPZ_TYPE_NSDNAME: 365 tgt_set->qname = 0; 366 tgt_set->ns = DNS_RPZ_ZBIT(rpz_num); 367 break; 368 default: 369 UNREACHABLE(); 370 } 371 } 372 373 /* 374 * Mark a node and all of its parents as having client-IP, IP, or NSIP data 375 */ 376 static void 377 set_sum_pair(dns_rpz_cidr_node_t *cnode) { 378 dns_rpz_cidr_node_t *child; 379 dns_rpz_addr_zbits_t sum; 380 381 do { 382 sum = cnode->set; 383 384 child = cnode->child[0]; 385 if (child != NULL) { 386 sum.client_ip |= child->sum.client_ip; 387 sum.ip |= child->sum.ip; 388 sum.nsip |= child->sum.nsip; 389 } 390 391 child = cnode->child[1]; 392 if (child != NULL) { 393 sum.client_ip |= child->sum.client_ip; 394 sum.ip |= child->sum.ip; 395 sum.nsip |= child->sum.nsip; 396 } 397 398 if (cnode->sum.client_ip == sum.client_ip && 399 cnode->sum.ip == sum.ip && cnode->sum.nsip == sum.nsip) 400 { 401 break; 402 } 403 cnode->sum = sum; 404 cnode = cnode->parent; 405 } while (cnode != NULL); 406 } 407 408 /* Caller must hold rpzs->maint_lock */ 409 static void 410 fix_qname_skip_recurse(dns_rpz_zones_t *rpzs) { 411 dns_rpz_zbits_t mask; 412 413 /* 414 * qname_wait_recurse and qname_skip_recurse are used to 415 * implement the "qname-wait-recurse" config option. 416 * 417 * When "qname-wait-recurse" is yes, no processing happens without 418 * recursion. In this case, qname_wait_recurse is true, and 419 * qname_skip_recurse (a bit field indicating which policy zones 420 * can be processed without recursion) is set to all 0's by 421 * fix_qname_skip_recurse(). 422 * 423 * When "qname-wait-recurse" is no, qname_skip_recurse may be 424 * set to a non-zero value by fix_qname_skip_recurse(). The mask 425 * has to have bits set for the policy zones for which 426 * processing may continue without recursion, and bits cleared 427 * for the rest. 428 * 429 * (1) The ARM says: 430 * 431 * The "qname-wait-recurse no" option overrides that default 432 * behavior when recursion cannot change a non-error 433 * response. The option does not affect QNAME or client-IP 434 * triggers in policy zones listed after other zones 435 * containing IP, NSIP and NSDNAME triggers, because those may 436 * depend on the A, AAAA, and NS records that would be found 437 * during recursive resolution. 438 * 439 * Let's consider the following: 440 * 441 * zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 | 442 * rpzs->have.nsdname | 443 * rpzs->have.nsipv4 | rpzs->have.nsipv6); 444 * 445 * zbits_req now contains bits set for zones which require 446 * recursion. 447 * 448 * But going by the description in the ARM, if the first policy 449 * zone requires recursion, then all zones after that (higher 450 * order bits) have to wait as well. If the Nth zone requires 451 * recursion, then (N+1)th zone onwards all need to wait. 452 * 453 * So mapping this, examples: 454 * 455 * zbits_req = 0b000 mask = 0xffffffff (no zones have to wait for 456 * recursion) 457 * zbits_req = 0b001 mask = 0x00000000 (all zones have to wait) 458 * zbits_req = 0b010 mask = 0x00000001 (the first zone doesn't have to 459 * wait, second zone onwards need 460 * to wait) 461 * zbits_req = 0b011 mask = 0x00000000 (all zones have to wait) 462 * zbits_req = 0b100 mask = 0x00000011 (the 1st and 2nd zones don't 463 * have to wait, third zone 464 * onwards need to wait) 465 * 466 * More generally, we have to count the number of trailing 0 467 * bits in zbits_req and only these can be processed without 468 * recursion. All the rest need to wait. 469 * 470 * (2) The ARM says that "qname-wait-recurse no" option 471 * overrides the default behavior when recursion cannot change a 472 * non-error response. So, in the order of listing of policy 473 * zones, within the first policy zone where recursion may be 474 * required, we should first allow CLIENT-IP and QNAME policy 475 * records to be attempted without recursion. 476 */ 477 478 /* 479 * Get a mask covering all policy zones that are not subordinate to 480 * other policy zones containing triggers that require that the 481 * qname be resolved before they can be checked. 482 */ 483 rpzs->have.client_ip = rpzs->have.client_ipv4 | rpzs->have.client_ipv6; 484 rpzs->have.ip = rpzs->have.ipv4 | rpzs->have.ipv6; 485 rpzs->have.nsip = rpzs->have.nsipv4 | rpzs->have.nsipv6; 486 487 if (rpzs->p.qname_wait_recurse) { 488 mask = 0; 489 } else { 490 dns_rpz_zbits_t zbits_req; 491 dns_rpz_zbits_t zbits_notreq; 492 dns_rpz_zbits_t mask2; 493 dns_rpz_zbits_t req_mask; 494 495 /* 496 * Get the masks of zones with policies that 497 * do/don't require recursion 498 */ 499 500 zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 | 501 rpzs->have.nsdname | rpzs->have.nsipv4 | 502 rpzs->have.nsipv6); 503 zbits_notreq = (rpzs->have.client_ip | rpzs->have.qname); 504 505 if (zbits_req == 0) { 506 mask = DNS_RPZ_ALL_ZBITS; 507 goto set; 508 } 509 510 /* 511 * req_mask is a mask covering used bits in 512 * zbits_req. (For instance, 0b1 => 0b1, 0b101 => 0b111, 513 * 0b11010101 => 0b11111111). 514 */ 515 req_mask = zbits_req; 516 req_mask |= req_mask >> 1; 517 req_mask |= req_mask >> 2; 518 req_mask |= req_mask >> 4; 519 req_mask |= req_mask >> 8; 520 req_mask |= req_mask >> 16; 521 req_mask |= req_mask >> 32; 522 523 /* 524 * There's no point in skipping recursion for a later 525 * zone if it is required in a previous zone. 526 */ 527 if ((zbits_notreq & req_mask) == 0) { 528 mask = 0; 529 goto set; 530 } 531 532 /* 533 * This bit arithmetic creates a mask of zones in which 534 * it is okay to skip recursion. After the first zone 535 * that has to wait for recursion, all the others have 536 * to wait as well, so we want to create a mask in which 537 * all the trailing zeroes in zbits_req are are 1, and 538 * more significant bits are 0. (For instance, 539 * 0x0700 => 0x00ff, 0x0007 => 0x0000) 540 */ 541 mask = ~(zbits_req | ((~zbits_req) + 1)); 542 543 /* 544 * As mentioned in (2) above, the zone corresponding to 545 * the least significant zero could have its CLIENT-IP 546 * and QNAME policies checked before recursion, if it 547 * has any of those policies. So if it does, we 548 * can set its 0 to 1. 549 * 550 * Locate the least significant 0 bit in the mask (for 551 * instance, 0xff => 0x100)... 552 */ 553 mask2 = (mask << 1) & ~mask; 554 555 /* 556 * Also set the bit for zone 0, because if it's in 557 * zbits_notreq then it's definitely okay to attempt to 558 * skip recursion for zone 0... 559 */ 560 mask2 |= 1; 561 562 /* Clear any bits *not* in zbits_notreq... */ 563 mask2 &= zbits_notreq; 564 565 /* And merge the result into the skip-recursion mask */ 566 mask |= mask2; 567 } 568 569 set: 570 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, 571 DNS_RPZ_DEBUG_QUIET, 572 "computed RPZ qname_skip_recurse mask=0x%" PRIx64, 573 (uint64_t)mask); 574 rpzs->have.qname_skip_recurse = mask; 575 } 576 577 static void 578 adj_trigger_cnt(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, 579 dns_rpz_type_t rpz_type, const dns_rpz_cidr_key_t *tgt_ip, 580 dns_rpz_prefix_t tgt_prefix, bool inc) { 581 dns_rpz_trigger_counter_t *cnt = NULL; 582 dns_rpz_zbits_t *have = NULL; 583 584 switch (rpz_type) { 585 case DNS_RPZ_TYPE_CLIENT_IP: 586 REQUIRE(tgt_ip != NULL); 587 if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { 588 cnt = &rpzs->triggers[rpz_num].client_ipv4; 589 have = &rpzs->have.client_ipv4; 590 } else { 591 cnt = &rpzs->triggers[rpz_num].client_ipv6; 592 have = &rpzs->have.client_ipv6; 593 } 594 break; 595 case DNS_RPZ_TYPE_QNAME: 596 cnt = &rpzs->triggers[rpz_num].qname; 597 have = &rpzs->have.qname; 598 break; 599 case DNS_RPZ_TYPE_IP: 600 REQUIRE(tgt_ip != NULL); 601 if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { 602 cnt = &rpzs->triggers[rpz_num].ipv4; 603 have = &rpzs->have.ipv4; 604 } else { 605 cnt = &rpzs->triggers[rpz_num].ipv6; 606 have = &rpzs->have.ipv6; 607 } 608 break; 609 case DNS_RPZ_TYPE_NSDNAME: 610 cnt = &rpzs->triggers[rpz_num].nsdname; 611 have = &rpzs->have.nsdname; 612 break; 613 case DNS_RPZ_TYPE_NSIP: 614 REQUIRE(tgt_ip != NULL); 615 if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { 616 cnt = &rpzs->triggers[rpz_num].nsipv4; 617 have = &rpzs->have.nsipv4; 618 } else { 619 cnt = &rpzs->triggers[rpz_num].nsipv6; 620 have = &rpzs->have.nsipv6; 621 } 622 break; 623 default: 624 UNREACHABLE(); 625 } 626 627 if (inc) { 628 if (++*cnt == 1U) { 629 *have |= DNS_RPZ_ZBIT(rpz_num); 630 fix_qname_skip_recurse(rpzs); 631 } 632 } else { 633 REQUIRE(*cnt != 0U); 634 if (--*cnt == 0U) { 635 *have &= ~DNS_RPZ_ZBIT(rpz_num); 636 fix_qname_skip_recurse(rpzs); 637 } 638 } 639 } 640 641 static dns_rpz_cidr_node_t * 642 new_node(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *ip, 643 dns_rpz_prefix_t prefix, const dns_rpz_cidr_node_t *child) { 644 dns_rpz_cidr_node_t *node; 645 int i, words, wlen; 646 647 node = isc_mem_get(rpzs->mctx, sizeof(*node)); 648 memset(node, 0, sizeof(*node)); 649 650 if (child != NULL) { 651 node->sum = child->sum; 652 } 653 654 node->prefix = prefix; 655 words = prefix / DNS_RPZ_CIDR_WORD_BITS; 656 wlen = prefix % DNS_RPZ_CIDR_WORD_BITS; 657 i = 0; 658 while (i < words) { 659 node->ip.w[i] = ip->w[i]; 660 ++i; 661 } 662 if (wlen != 0) { 663 node->ip.w[i] = ip->w[i] & DNS_RPZ_WORD_MASK(wlen); 664 ++i; 665 } 666 while (i < DNS_RPZ_CIDR_WORDS) { 667 node->ip.w[i++] = 0; 668 } 669 670 return (node); 671 } 672 673 static void 674 badname(int level, const dns_name_t *name, const char *str1, const char *str2) { 675 char namebuf[DNS_NAME_FORMATSIZE]; 676 677 /* 678 * bin/tests/system/rpz/tests.sh looks for "invalid rpz". 679 */ 680 if (level < DNS_RPZ_DEBUG_QUIET && isc_log_wouldlog(dns_lctx, level)) { 681 dns_name_format(name, namebuf, sizeof(namebuf)); 682 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 683 DNS_LOGMODULE_RBTDB, level, 684 "invalid rpz IP address \"%s\"%s%s", namebuf, 685 str1, str2); 686 } 687 } 688 689 /* 690 * Convert an IP address from radix tree binary (host byte order) to 691 * to its canonical response policy domain name without the origin of the 692 * policy zone. 693 * 694 * Generate a name for an IPv6 address that fits RFC 5952, except that our 695 * reversed format requires that when the length of the consecutive 16-bit 696 * 0 fields are equal (e.g., 1.0.0.1.0.0.db8.2001 corresponding to 697 * 2001:db8:0:0:1:0:0:1), we shorted the last instead of the first 698 * (e.g., 1.0.0.1.zz.db8.2001 corresponding to 2001:db8::1:0:0:1). 699 */ 700 static isc_result_t 701 ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, 702 const dns_name_t *base_name, dns_name_t *ip_name) { 703 #ifndef INET6_ADDRSTRLEN 704 #define INET6_ADDRSTRLEN 46 705 #endif /* ifndef INET6_ADDRSTRLEN */ 706 int w[DNS_RPZ_CIDR_WORDS * 2]; 707 char str[1 + 8 + 1 + INET6_ADDRSTRLEN + 1]; 708 isc_buffer_t buffer; 709 isc_result_t result; 710 int best_first, best_len, cur_first, cur_len; 711 int i, n, len; 712 713 if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { 714 len = snprintf(str, sizeof(str), "%u.%u.%u.%u.%u", 715 tgt_prefix - 96U, tgt_ip->w[3] & 0xffU, 716 (tgt_ip->w[3] >> 8) & 0xffU, 717 (tgt_ip->w[3] >> 16) & 0xffU, 718 (tgt_ip->w[3] >> 24) & 0xffU); 719 if (len < 0 || (size_t)len >= sizeof(str)) { 720 return (ISC_R_FAILURE); 721 } 722 } else { 723 len = snprintf(str, sizeof(str), "%d", tgt_prefix); 724 if (len < 0 || (size_t)len >= sizeof(str)) { 725 return (ISC_R_FAILURE); 726 } 727 728 for (i = 0; i < DNS_RPZ_CIDR_WORDS; i++) { 729 w[i * 2 + 1] = 730 ((tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - i] >> 16) & 731 0xffff); 732 w[i * 2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - i] & 733 0xffff; 734 } 735 /* 736 * Find the start and length of the first longest sequence 737 * of zeros in the address. 738 */ 739 best_first = -1; 740 best_len = 0; 741 cur_first = -1; 742 cur_len = 0; 743 for (n = 0; n <= 7; ++n) { 744 if (w[n] != 0) { 745 cur_len = 0; 746 cur_first = -1; 747 } else { 748 ++cur_len; 749 if (cur_first < 0) { 750 cur_first = n; 751 } else if (cur_len >= best_len) { 752 best_first = cur_first; 753 best_len = cur_len; 754 } 755 } 756 } 757 758 for (n = 0; n <= 7; ++n) { 759 INSIST(len > 0 && (size_t)len < sizeof(str)); 760 if (n == best_first) { 761 i = snprintf(str + len, sizeof(str) - len, 762 ".zz"); 763 n += best_len - 1; 764 } else { 765 i = snprintf(str + len, sizeof(str) - len, 766 ".%x", w[n]); 767 } 768 if (i < 0 || (size_t)i >= (size_t)(sizeof(str) - len)) { 769 return (ISC_R_FAILURE); 770 } 771 len += i; 772 } 773 } 774 775 isc_buffer_init(&buffer, str, sizeof(str)); 776 isc_buffer_add(&buffer, len); 777 result = dns_name_fromtext(ip_name, &buffer, base_name, 0, NULL); 778 return (result); 779 } 780 781 /* 782 * Determine the type of a name in a response policy zone. 783 */ 784 static dns_rpz_type_t 785 type_from_name(const dns_rpz_zones_t *rpzs, dns_rpz_zone_t *rpz, 786 const dns_name_t *name) { 787 if (dns_name_issubdomain(name, &rpz->ip)) { 788 return (DNS_RPZ_TYPE_IP); 789 } 790 791 if (dns_name_issubdomain(name, &rpz->client_ip)) { 792 return (DNS_RPZ_TYPE_CLIENT_IP); 793 } 794 795 if ((rpzs->p.nsip_on & DNS_RPZ_ZBIT(rpz->num)) != 0 && 796 dns_name_issubdomain(name, &rpz->nsip)) 797 { 798 return (DNS_RPZ_TYPE_NSIP); 799 } 800 801 if ((rpzs->p.nsdname_on & DNS_RPZ_ZBIT(rpz->num)) != 0 && 802 dns_name_issubdomain(name, &rpz->nsdname)) 803 { 804 return (DNS_RPZ_TYPE_NSDNAME); 805 } 806 807 return (DNS_RPZ_TYPE_QNAME); 808 } 809 810 /* 811 * Convert an IP address from canonical response policy domain name form 812 * to radix tree binary (host byte order) for adding or deleting IP or NSIP 813 * data. 814 */ 815 static isc_result_t 816 name2ipkey(int log_level, const dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, 817 dns_rpz_type_t rpz_type, const dns_name_t *src_name, 818 dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t *tgt_prefix, 819 dns_rpz_addr_zbits_t *new_set) { 820 dns_rpz_zone_t *rpz; 821 char ip_str[DNS_NAME_FORMATSIZE], ip2_str[DNS_NAME_FORMATSIZE]; 822 dns_offsets_t ip_name_offsets; 823 dns_fixedname_t ip_name2f; 824 dns_name_t ip_name, *ip_name2; 825 const char *prefix_str, *cp, *end; 826 char *cp2; 827 int ip_labels; 828 dns_rpz_prefix_t prefix; 829 unsigned long prefix_num, l; 830 isc_result_t result; 831 int i; 832 833 REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); 834 rpz = rpzs->zones[rpz_num]; 835 REQUIRE(rpz != NULL); 836 837 make_addr_set(new_set, DNS_RPZ_ZBIT(rpz_num), rpz_type); 838 839 ip_labels = dns_name_countlabels(src_name); 840 if (rpz_type == DNS_RPZ_TYPE_QNAME) { 841 ip_labels -= dns_name_countlabels(&rpz->origin); 842 } else { 843 ip_labels -= dns_name_countlabels(&rpz->nsdname); 844 } 845 if (ip_labels < 2) { 846 badname(log_level, src_name, "; too short", ""); 847 return (ISC_R_FAILURE); 848 } 849 dns_name_init(&ip_name, ip_name_offsets); 850 dns_name_getlabelsequence(src_name, 0, ip_labels, &ip_name); 851 852 /* 853 * Get text for the IP address 854 */ 855 dns_name_format(&ip_name, ip_str, sizeof(ip_str)); 856 end = &ip_str[strlen(ip_str) + 1]; 857 prefix_str = ip_str; 858 859 prefix_num = strtoul(prefix_str, &cp2, 10); 860 if (*cp2 != '.') { 861 badname(log_level, src_name, "; invalid leading prefix length", 862 ""); 863 return (ISC_R_FAILURE); 864 } 865 /* 866 * Patch in trailing nul character to print just the length 867 * label (for various cases below). 868 */ 869 *cp2 = '\0'; 870 if (prefix_num < 1U || prefix_num > 128U) { 871 badname(log_level, src_name, "; invalid prefix length of ", 872 prefix_str); 873 return (ISC_R_FAILURE); 874 } 875 cp = cp2 + 1; 876 877 if (--ip_labels == 4 && !strchr(cp, 'z')) { 878 /* 879 * Convert an IPv4 address 880 * from the form "prefix.z.y.x.w" 881 */ 882 if (prefix_num > 32U) { 883 badname(log_level, src_name, 884 "; invalid IPv4 prefix length of ", prefix_str); 885 return (ISC_R_FAILURE); 886 } 887 prefix_num += 96; 888 *tgt_prefix = (dns_rpz_prefix_t)prefix_num; 889 tgt_ip->w[0] = 0; 890 tgt_ip->w[1] = 0; 891 tgt_ip->w[2] = ADDR_V4MAPPED; 892 tgt_ip->w[3] = 0; 893 for (i = 0; i < 32; i += 8) { 894 l = strtoul(cp, &cp2, 10); 895 if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) { 896 if (*cp2 == '.') { 897 *cp2 = '\0'; 898 } 899 badname(log_level, src_name, 900 "; invalid IPv4 octet ", cp); 901 return (ISC_R_FAILURE); 902 } 903 tgt_ip->w[3] |= l << i; 904 cp = cp2 + 1; 905 } 906 } else { 907 /* 908 * Convert a text IPv6 address. 909 */ 910 *tgt_prefix = (dns_rpz_prefix_t)prefix_num; 911 for (i = 0; ip_labels > 0 && i < DNS_RPZ_CIDR_WORDS * 2; 912 ip_labels--) 913 { 914 if (cp[0] == 'z' && cp[1] == 'z' && 915 (cp[2] == '.' || cp[2] == '\0') && i <= 6) 916 { 917 do { 918 if ((i & 1) == 0) { 919 tgt_ip->w[3 - i / 2] = 0; 920 } 921 ++i; 922 } while (ip_labels + i <= 8); 923 cp += 3; 924 } else { 925 l = strtoul(cp, &cp2, 16); 926 if (l > 0xffffu || 927 (*cp2 != '.' && *cp2 != '\0')) 928 { 929 if (*cp2 == '.') { 930 *cp2 = '\0'; 931 } 932 badname(log_level, src_name, 933 "; invalid IPv6 word ", cp); 934 return (ISC_R_FAILURE); 935 } 936 if ((i & 1) == 0) { 937 tgt_ip->w[3 - i / 2] = l; 938 } else { 939 tgt_ip->w[3 - i / 2] |= l << 16; 940 } 941 i++; 942 cp = cp2 + 1; 943 } 944 } 945 } 946 if (cp != end) { 947 badname(log_level, src_name, "", ""); 948 return (ISC_R_FAILURE); 949 } 950 951 /* 952 * Check for 1s after the prefix length. 953 */ 954 prefix = (dns_rpz_prefix_t)prefix_num; 955 while (prefix < DNS_RPZ_CIDR_KEY_BITS) { 956 dns_rpz_cidr_word_t aword; 957 958 i = prefix % DNS_RPZ_CIDR_WORD_BITS; 959 aword = tgt_ip->w[prefix / DNS_RPZ_CIDR_WORD_BITS]; 960 if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) { 961 badname(log_level, src_name, 962 "; too small prefix length of ", prefix_str); 963 return (ISC_R_FAILURE); 964 } 965 prefix -= i; 966 prefix += DNS_RPZ_CIDR_WORD_BITS; 967 } 968 969 /* 970 * Complain about bad names but be generous and accept them. 971 */ 972 if (log_level < DNS_RPZ_DEBUG_QUIET && 973 isc_log_wouldlog(dns_lctx, log_level)) 974 { 975 /* 976 * Convert the address back to a canonical domain name 977 * to ensure that the original name is in canonical form. 978 */ 979 ip_name2 = dns_fixedname_initname(&ip_name2f); 980 result = ip2name(tgt_ip, (dns_rpz_prefix_t)prefix_num, NULL, 981 ip_name2); 982 if (result != ISC_R_SUCCESS || 983 !dns_name_equal(&ip_name, ip_name2)) 984 { 985 dns_name_format(ip_name2, ip2_str, sizeof(ip2_str)); 986 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 987 DNS_LOGMODULE_RBTDB, log_level, 988 "rpz IP address \"%s\"" 989 " is not the canonical \"%s\"", 990 ip_str, ip2_str); 991 } 992 } 993 994 return (ISC_R_SUCCESS); 995 } 996 997 /* 998 * Get trigger name and data bits for adding or deleting summary NSDNAME 999 * or QNAME data. 1000 */ 1001 static void 1002 name2data(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, 1003 const dns_name_t *src_name, dns_name_t *trig_name, 1004 dns_rpz_nm_data_t *new_data) { 1005 dns_rpz_zone_t *rpz; 1006 dns_offsets_t tmp_name_offsets; 1007 dns_name_t tmp_name; 1008 unsigned int prefix_len, n; 1009 1010 REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); 1011 rpz = rpzs->zones[rpz_num]; 1012 REQUIRE(rpz != NULL); 1013 1014 /* 1015 * Handle wildcards by putting only the parent into the 1016 * summary RBT. The summary database only causes a check of the 1017 * real policy zone where wildcards will be handled. 1018 */ 1019 if (dns_name_iswildcard(src_name)) { 1020 prefix_len = 1; 1021 memset(&new_data->set, 0, sizeof(new_data->set)); 1022 make_nm_set(&new_data->wild, rpz_num, rpz_type); 1023 } else { 1024 prefix_len = 0; 1025 make_nm_set(&new_data->set, rpz_num, rpz_type); 1026 memset(&new_data->wild, 0, sizeof(new_data->wild)); 1027 } 1028 1029 dns_name_init(&tmp_name, tmp_name_offsets); 1030 n = dns_name_countlabels(src_name); 1031 n -= prefix_len; 1032 if (rpz_type == DNS_RPZ_TYPE_QNAME) { 1033 n -= dns_name_countlabels(&rpz->origin); 1034 } else { 1035 n -= dns_name_countlabels(&rpz->nsdname); 1036 } 1037 dns_name_getlabelsequence(src_name, prefix_len, n, &tmp_name); 1038 (void)dns_name_concatenate(&tmp_name, dns_rootname, trig_name, NULL); 1039 } 1040 1041 #ifndef HAVE_BUILTIN_CLZ 1042 /** 1043 * \brief Count Leading Zeros: Find the location of the left-most set 1044 * bit. 1045 */ 1046 static unsigned int 1047 clz(dns_rpz_cidr_word_t w) { 1048 unsigned int bit; 1049 1050 bit = DNS_RPZ_CIDR_WORD_BITS - 1; 1051 1052 if ((w & 0xffff0000) != 0) { 1053 w >>= 16; 1054 bit -= 16; 1055 } 1056 1057 if ((w & 0xff00) != 0) { 1058 w >>= 8; 1059 bit -= 8; 1060 } 1061 1062 if ((w & 0xf0) != 0) { 1063 w >>= 4; 1064 bit -= 4; 1065 } 1066 1067 if ((w & 0xc) != 0) { 1068 w >>= 2; 1069 bit -= 2; 1070 } 1071 1072 if ((w & 2) != 0) { 1073 --bit; 1074 } 1075 1076 return (bit); 1077 } 1078 #endif /* ifndef HAVE_BUILTIN_CLZ */ 1079 1080 /* 1081 * Find the first differing bit in two keys (IP addresses). 1082 */ 1083 static int 1084 diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_prefix_t prefix1, 1085 const dns_rpz_cidr_key_t *key2, dns_rpz_prefix_t prefix2) { 1086 dns_rpz_cidr_word_t delta; 1087 dns_rpz_prefix_t maxbit, bit; 1088 int i; 1089 1090 bit = 0; 1091 maxbit = ISC_MIN(prefix1, prefix2); 1092 1093 /* 1094 * find the first differing words 1095 */ 1096 for (i = 0; bit < maxbit; i++, bit += DNS_RPZ_CIDR_WORD_BITS) { 1097 delta = key1->w[i] ^ key2->w[i]; 1098 if (ISC_UNLIKELY(delta != 0)) { 1099 #ifdef HAVE_BUILTIN_CLZ 1100 bit += __builtin_clz(delta); 1101 #else /* ifdef HAVE_BUILTIN_CLZ */ 1102 bit += clz(delta); 1103 #endif /* ifdef HAVE_BUILTIN_CLZ */ 1104 break; 1105 } 1106 } 1107 return (ISC_MIN(bit, maxbit)); 1108 } 1109 1110 /* 1111 * Given a hit while searching the radix trees, 1112 * clear all bits for higher numbered zones. 1113 */ 1114 static dns_rpz_zbits_t 1115 trim_zbits(dns_rpz_zbits_t zbits, dns_rpz_zbits_t found) { 1116 dns_rpz_zbits_t x; 1117 1118 /* 1119 * Isolate the first or smallest numbered hit bit. 1120 * Make a mask of that bit and all smaller numbered bits. 1121 */ 1122 x = zbits & found; 1123 x &= (~x + 1); 1124 x = (x << 1) - 1; 1125 zbits &= x; 1126 return (zbits); 1127 } 1128 1129 /* 1130 * Search a radix tree for an IP address for ordinary lookup 1131 * or for a CIDR block adding or deleting an entry 1132 * 1133 * Return ISC_R_SUCCESS, DNS_R_PARTIALMATCH, ISC_R_NOTFOUND, 1134 * and *found=longest match node 1135 * or with create==true, ISC_R_EXISTS or ISC_R_NOMEMORY 1136 */ 1137 static isc_result_t 1138 search(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *tgt_ip, 1139 dns_rpz_prefix_t tgt_prefix, const dns_rpz_addr_zbits_t *tgt_set, 1140 bool create, dns_rpz_cidr_node_t **found) { 1141 dns_rpz_cidr_node_t *cur, *parent, *child, *new_parent, *sibling; 1142 dns_rpz_addr_zbits_t set; 1143 int cur_num, child_num; 1144 dns_rpz_prefix_t dbit; 1145 isc_result_t find_result; 1146 1147 set = *tgt_set; 1148 find_result = ISC_R_NOTFOUND; 1149 *found = NULL; 1150 cur = rpzs->cidr; 1151 parent = NULL; 1152 cur_num = 0; 1153 for (;;) { 1154 if (cur == NULL) { 1155 /* 1156 * No child so we cannot go down. 1157 * Quit with whatever we already found 1158 * or add the target as a child of the current parent. 1159 */ 1160 if (!create) { 1161 return (find_result); 1162 } 1163 child = new_node(rpzs, tgt_ip, tgt_prefix, NULL); 1164 if (child == NULL) { 1165 return (ISC_R_NOMEMORY); 1166 } 1167 if (parent == NULL) { 1168 rpzs->cidr = child; 1169 } else { 1170 parent->child[cur_num] = child; 1171 } 1172 child->parent = parent; 1173 child->set.client_ip |= tgt_set->client_ip; 1174 child->set.ip |= tgt_set->ip; 1175 child->set.nsip |= tgt_set->nsip; 1176 set_sum_pair(child); 1177 *found = child; 1178 return (ISC_R_SUCCESS); 1179 } 1180 1181 if ((cur->sum.client_ip & set.client_ip) == 0 && 1182 (cur->sum.ip & set.ip) == 0 && 1183 (cur->sum.nsip & set.nsip) == 0) 1184 { 1185 /* 1186 * This node has no relevant data 1187 * and is in none of the target trees. 1188 * Pretend it does not exist if we are not adding. 1189 * 1190 * If we are adding, continue down to eventually add 1191 * a node and mark/put this node in the correct tree. 1192 */ 1193 if (!create) { 1194 return (find_result); 1195 } 1196 } 1197 1198 dbit = diff_keys(tgt_ip, tgt_prefix, &cur->ip, cur->prefix); 1199 /* 1200 * dbit <= tgt_prefix and dbit <= cur->prefix always. 1201 * We are finished searching if we matched all of the target. 1202 */ 1203 if (dbit == tgt_prefix) { 1204 if (tgt_prefix == cur->prefix) { 1205 /* 1206 * The node's key matches the target exactly. 1207 */ 1208 if ((cur->set.client_ip & set.client_ip) != 0 || 1209 (cur->set.ip & set.ip) != 0 || 1210 (cur->set.nsip & set.nsip) != 0) 1211 { 1212 /* 1213 * It is the answer if it has data. 1214 */ 1215 *found = cur; 1216 if (create) { 1217 find_result = ISC_R_EXISTS; 1218 } else { 1219 find_result = ISC_R_SUCCESS; 1220 } 1221 } else if (create) { 1222 /* 1223 * The node lacked relevant data, 1224 * but will have it now. 1225 */ 1226 cur->set.client_ip |= 1227 tgt_set->client_ip; 1228 cur->set.ip |= tgt_set->ip; 1229 cur->set.nsip |= tgt_set->nsip; 1230 set_sum_pair(cur); 1231 *found = cur; 1232 find_result = ISC_R_SUCCESS; 1233 } 1234 return (find_result); 1235 } 1236 1237 /* 1238 * We know tgt_prefix < cur->prefix which means that 1239 * the target is shorter than the current node. 1240 * Add the target as the current node's parent. 1241 */ 1242 if (!create) { 1243 return (find_result); 1244 } 1245 1246 new_parent = new_node(rpzs, tgt_ip, tgt_prefix, cur); 1247 if (new_parent == NULL) { 1248 return (ISC_R_NOMEMORY); 1249 } 1250 new_parent->parent = parent; 1251 if (parent == NULL) { 1252 rpzs->cidr = new_parent; 1253 } else { 1254 parent->child[cur_num] = new_parent; 1255 } 1256 child_num = DNS_RPZ_IP_BIT(&cur->ip, tgt_prefix); 1257 new_parent->child[child_num] = cur; 1258 cur->parent = new_parent; 1259 new_parent->set = *tgt_set; 1260 set_sum_pair(new_parent); 1261 *found = new_parent; 1262 return (ISC_R_SUCCESS); 1263 } 1264 1265 if (dbit == cur->prefix) { 1266 if ((cur->set.client_ip & set.client_ip) != 0 || 1267 (cur->set.ip & set.ip) != 0 || 1268 (cur->set.nsip & set.nsip) != 0) 1269 { 1270 /* 1271 * We have a partial match between of all of the 1272 * current node but only part of the target. 1273 * Continue searching for other hits in the 1274 * same or lower numbered trees. 1275 */ 1276 find_result = DNS_R_PARTIALMATCH; 1277 *found = cur; 1278 set.client_ip = trim_zbits(set.client_ip, 1279 cur->set.client_ip); 1280 set.ip = trim_zbits(set.ip, cur->set.ip); 1281 set.nsip = trim_zbits(set.nsip, cur->set.nsip); 1282 } 1283 parent = cur; 1284 cur_num = DNS_RPZ_IP_BIT(tgt_ip, dbit); 1285 cur = cur->child[cur_num]; 1286 continue; 1287 } 1288 1289 /* 1290 * dbit < tgt_prefix and dbit < cur->prefix, 1291 * so we failed to match both the target and the current node. 1292 * Insert a fork of a parent above the current node and 1293 * add the target as a sibling of the current node 1294 */ 1295 if (!create) { 1296 return (find_result); 1297 } 1298 1299 sibling = new_node(rpzs, tgt_ip, tgt_prefix, NULL); 1300 if (sibling == NULL) { 1301 return (ISC_R_NOMEMORY); 1302 } 1303 new_parent = new_node(rpzs, tgt_ip, dbit, cur); 1304 if (new_parent == NULL) { 1305 isc_mem_put(rpzs->mctx, sibling, sizeof(*sibling)); 1306 return (ISC_R_NOMEMORY); 1307 } 1308 new_parent->parent = parent; 1309 if (parent == NULL) { 1310 rpzs->cidr = new_parent; 1311 } else { 1312 parent->child[cur_num] = new_parent; 1313 } 1314 child_num = DNS_RPZ_IP_BIT(tgt_ip, dbit); 1315 new_parent->child[child_num] = sibling; 1316 new_parent->child[1 - child_num] = cur; 1317 cur->parent = new_parent; 1318 sibling->parent = new_parent; 1319 sibling->set = *tgt_set; 1320 set_sum_pair(sibling); 1321 *found = sibling; 1322 return (ISC_R_SUCCESS); 1323 } 1324 } 1325 1326 /* 1327 * Add an IP address to the radix tree. 1328 */ 1329 static isc_result_t 1330 add_cidr(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, 1331 const dns_name_t *src_name) { 1332 dns_rpz_cidr_key_t tgt_ip; 1333 dns_rpz_prefix_t tgt_prefix; 1334 dns_rpz_addr_zbits_t set; 1335 dns_rpz_cidr_node_t *found; 1336 isc_result_t result; 1337 1338 result = name2ipkey(DNS_RPZ_ERROR_LEVEL, rpzs, rpz_num, rpz_type, 1339 src_name, &tgt_ip, &tgt_prefix, &set); 1340 /* 1341 * Log complaints about bad owner names but let the zone load. 1342 */ 1343 if (result != ISC_R_SUCCESS) { 1344 return (ISC_R_SUCCESS); 1345 } 1346 1347 result = search(rpzs, &tgt_ip, tgt_prefix, &set, true, &found); 1348 if (result != ISC_R_SUCCESS) { 1349 char namebuf[DNS_NAME_FORMATSIZE]; 1350 1351 /* 1352 * Do not worry if the radix tree already exists, 1353 * because diff_apply() likes to add nodes before deleting. 1354 */ 1355 if (result == ISC_R_EXISTS) { 1356 return (ISC_R_SUCCESS); 1357 } 1358 1359 /* 1360 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". 1361 */ 1362 dns_name_format(src_name, namebuf, sizeof(namebuf)); 1363 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 1364 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 1365 "rpz add_cidr(%s) failed: %s", namebuf, 1366 isc_result_totext(result)); 1367 return (result); 1368 } 1369 1370 adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix, true); 1371 return (result); 1372 } 1373 1374 static isc_result_t 1375 add_nm(dns_rpz_zones_t *rpzs, dns_name_t *trig_name, 1376 const dns_rpz_nm_data_t *new_data) { 1377 dns_rbtnode_t *nmnode; 1378 dns_rpz_nm_data_t *nm_data; 1379 isc_result_t result; 1380 1381 nmnode = NULL; 1382 result = dns_rbt_addnode(rpzs->rbt, trig_name, &nmnode); 1383 switch (result) { 1384 case ISC_R_SUCCESS: 1385 case ISC_R_EXISTS: 1386 nm_data = nmnode->data; 1387 if (nm_data == NULL) { 1388 nm_data = isc_mem_get(rpzs->mctx, sizeof(*nm_data)); 1389 *nm_data = *new_data; 1390 nmnode->data = nm_data; 1391 return (ISC_R_SUCCESS); 1392 } 1393 break; 1394 default: 1395 return (result); 1396 } 1397 1398 /* 1399 * Do not count bits that are already present 1400 */ 1401 if ((nm_data->set.qname & new_data->set.qname) != 0 || 1402 (nm_data->set.ns & new_data->set.ns) != 0 || 1403 (nm_data->wild.qname & new_data->wild.qname) != 0 || 1404 (nm_data->wild.ns & new_data->wild.ns) != 0) 1405 { 1406 return (ISC_R_EXISTS); 1407 } 1408 1409 nm_data->set.qname |= new_data->set.qname; 1410 nm_data->set.ns |= new_data->set.ns; 1411 nm_data->wild.qname |= new_data->wild.qname; 1412 nm_data->wild.ns |= new_data->wild.ns; 1413 return (ISC_R_SUCCESS); 1414 } 1415 1416 static isc_result_t 1417 add_name(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, 1418 const dns_name_t *src_name) { 1419 dns_rpz_nm_data_t new_data; 1420 dns_fixedname_t trig_namef; 1421 dns_name_t *trig_name; 1422 isc_result_t result; 1423 1424 /* 1425 * We need a summary database of names even with 1 policy zone, 1426 * because wildcard triggers are handled differently. 1427 */ 1428 1429 trig_name = dns_fixedname_initname(&trig_namef); 1430 name2data(rpzs, rpz_num, rpz_type, src_name, trig_name, &new_data); 1431 1432 result = add_nm(rpzs, trig_name, &new_data); 1433 1434 /* 1435 * Do not worry if the node already exists, 1436 * because diff_apply() likes to add nodes before deleting. 1437 */ 1438 if (result == ISC_R_EXISTS) { 1439 return (ISC_R_SUCCESS); 1440 } 1441 if (result == ISC_R_SUCCESS) { 1442 adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, true); 1443 } 1444 return (result); 1445 } 1446 1447 /* 1448 * Callback to free the data for a node in the summary RBT database. 1449 */ 1450 static void 1451 rpz_node_deleter(void *nm_data, void *mctx) { 1452 isc_mem_put(mctx, nm_data, sizeof(dns_rpz_nm_data_t)); 1453 } 1454 1455 /* 1456 * Get ready for a new set of policy zones for a view. 1457 */ 1458 isc_result_t 1459 dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, char *rps_cstr, size_t rps_cstr_size, 1460 isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 1461 isc_timermgr_t *timermgr) { 1462 dns_rpz_zones_t *zones; 1463 isc_result_t result = ISC_R_SUCCESS; 1464 1465 REQUIRE(rpzsp != NULL && *rpzsp == NULL); 1466 1467 zones = isc_mem_get(mctx, sizeof(*zones)); 1468 memset(zones, 0, sizeof(*zones)); 1469 1470 isc_rwlock_init(&zones->search_lock, 0, 0); 1471 isc_mutex_init(&zones->maint_lock); 1472 isc_refcount_init(&zones->refs, 1); 1473 isc_refcount_init(&zones->irefs, 1); 1474 1475 zones->rps_cstr = rps_cstr; 1476 zones->rps_cstr_size = rps_cstr_size; 1477 #ifdef USE_DNSRPS 1478 if (rps_cstr != NULL) { 1479 result = dns_dnsrps_view_init(zones, rps_cstr); 1480 } 1481 #else /* ifdef USE_DNSRPS */ 1482 INSIST(!zones->p.dnsrps_enabled); 1483 #endif /* ifdef USE_DNSRPS */ 1484 if (result == ISC_R_SUCCESS && !zones->p.dnsrps_enabled) { 1485 result = dns_rbt_create(mctx, rpz_node_deleter, mctx, 1486 &zones->rbt); 1487 } 1488 1489 if (result != ISC_R_SUCCESS) { 1490 goto cleanup_rbt; 1491 } 1492 1493 result = isc_task_create(taskmgr, 0, &zones->updater); 1494 if (result != ISC_R_SUCCESS) { 1495 goto cleanup_task; 1496 } 1497 1498 isc_mem_attach(mctx, &zones->mctx); 1499 zones->timermgr = timermgr; 1500 zones->taskmgr = taskmgr; 1501 1502 *rpzsp = zones; 1503 return (ISC_R_SUCCESS); 1504 1505 cleanup_task: 1506 dns_rbt_destroy(&zones->rbt); 1507 1508 cleanup_rbt: 1509 isc_refcount_decrementz(&zones->irefs); 1510 isc_refcount_destroy(&zones->irefs); 1511 isc_refcount_decrementz(&zones->refs); 1512 isc_refcount_destroy(&zones->refs); 1513 isc_mutex_destroy(&zones->maint_lock); 1514 isc_rwlock_destroy(&zones->search_lock); 1515 isc_mem_put(mctx, zones, sizeof(*zones)); 1516 1517 return (result); 1518 } 1519 1520 isc_result_t 1521 dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) { 1522 dns_rpz_zone_t *zone; 1523 isc_result_t result; 1524 1525 REQUIRE(rpzp != NULL && *rpzp == NULL); 1526 REQUIRE(rpzs != NULL); 1527 if (rpzs->p.num_zones >= DNS_RPZ_MAX_ZONES) { 1528 return (ISC_R_NOSPACE); 1529 } 1530 1531 zone = isc_mem_get(rpzs->mctx, sizeof(*zone)); 1532 1533 memset(zone, 0, sizeof(*zone)); 1534 isc_refcount_init(&zone->refs, 1); 1535 1536 result = isc_timer_create(rpzs->timermgr, isc_timertype_inactive, NULL, 1537 NULL, rpzs->updater, 1538 dns_rpz_update_taskaction, zone, 1539 &zone->updatetimer); 1540 if (result != ISC_R_SUCCESS) { 1541 goto cleanup_timer; 1542 } 1543 1544 /* 1545 * This will never be used, but costs us nothing and 1546 * simplifies update_from_db 1547 */ 1548 1549 isc_ht_init(&zone->nodes, rpzs->mctx, 1); 1550 1551 dns_name_init(&zone->origin, NULL); 1552 dns_name_init(&zone->client_ip, NULL); 1553 dns_name_init(&zone->ip, NULL); 1554 dns_name_init(&zone->nsdname, NULL); 1555 dns_name_init(&zone->nsip, NULL); 1556 dns_name_init(&zone->passthru, NULL); 1557 dns_name_init(&zone->drop, NULL); 1558 dns_name_init(&zone->tcp_only, NULL); 1559 dns_name_init(&zone->cname, NULL); 1560 1561 isc_time_settoepoch(&zone->lastupdated); 1562 zone->updatepending = false; 1563 zone->updaterunning = false; 1564 zone->db = NULL; 1565 zone->dbversion = NULL; 1566 zone->updb = NULL; 1567 zone->updbversion = NULL; 1568 zone->updbit = NULL; 1569 isc_refcount_increment(&rpzs->irefs); 1570 zone->rpzs = rpzs; 1571 zone->db_registered = false; 1572 zone->addsoa = true; 1573 ISC_EVENT_INIT(&zone->updateevent, sizeof(zone->updateevent), 0, NULL, 1574 0, NULL, NULL, NULL, NULL, NULL); 1575 1576 zone->num = rpzs->p.num_zones++; 1577 rpzs->zones[zone->num] = zone; 1578 1579 *rpzp = zone; 1580 1581 return (ISC_R_SUCCESS); 1582 1583 cleanup_timer: 1584 isc_refcount_decrementz(&zone->refs); 1585 isc_refcount_destroy(&zone->refs); 1586 1587 isc_mem_put(rpzs->mctx, zone, sizeof(*zone)); 1588 1589 return (result); 1590 } 1591 1592 isc_result_t 1593 dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) { 1594 dns_rpz_zone_t *zone = (dns_rpz_zone_t *)fn_arg; 1595 isc_time_t now; 1596 uint64_t tdiff; 1597 isc_result_t result = ISC_R_SUCCESS; 1598 char dname[DNS_NAME_FORMATSIZE]; 1599 1600 REQUIRE(DNS_DB_VALID(db)); 1601 REQUIRE(zone != NULL); 1602 1603 LOCK(&zone->rpzs->maint_lock); 1604 1605 /* New zone came as AXFR */ 1606 if (zone->db != NULL && zone->db != db) { 1607 /* We need to clean up the old DB */ 1608 if (zone->dbversion != NULL) { 1609 dns_db_closeversion(zone->db, &zone->dbversion, false); 1610 } 1611 dns_db_updatenotify_unregister(zone->db, 1612 dns_rpz_dbupdate_callback, zone); 1613 dns_db_detach(&zone->db); 1614 } 1615 1616 if (zone->db == NULL) { 1617 RUNTIME_CHECK(zone->dbversion == NULL); 1618 dns_db_attach(db, &zone->db); 1619 } 1620 1621 if (!zone->updatepending && !zone->updaterunning) { 1622 zone->updatepending = true; 1623 isc_time_now(&now); 1624 tdiff = isc_time_microdiff(&now, &zone->lastupdated) / 1000000; 1625 if (tdiff < zone->min_update_interval) { 1626 uint64_t defer = zone->min_update_interval - tdiff; 1627 isc_interval_t interval; 1628 dns_name_format(&zone->origin, dname, 1629 DNS_NAME_FORMATSIZE); 1630 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1631 DNS_LOGMODULE_MASTER, ISC_LOG_INFO, 1632 "rpz: %s: new zone version came " 1633 "too soon, deferring update for " 1634 "%" PRIu64 " seconds", 1635 dname, defer); 1636 isc_interval_set(&interval, (unsigned int)defer, 0); 1637 dns_db_currentversion(zone->db, &zone->dbversion); 1638 result = isc_timer_reset(zone->updatetimer, 1639 isc_timertype_once, NULL, 1640 &interval, true); 1641 if (result != ISC_R_SUCCESS) { 1642 goto cleanup; 1643 } 1644 } else { 1645 isc_event_t *event; 1646 1647 dns_db_currentversion(zone->db, &zone->dbversion); 1648 INSIST(!ISC_LINK_LINKED(&zone->updateevent, ev_link)); 1649 ISC_EVENT_INIT(&zone->updateevent, 1650 sizeof(zone->updateevent), 0, NULL, 1651 DNS_EVENT_RPZUPDATED, 1652 dns_rpz_update_taskaction, zone, zone, 1653 NULL, NULL); 1654 event = &zone->updateevent; 1655 isc_task_send(zone->rpzs->updater, &event); 1656 } 1657 } else { 1658 zone->updatepending = true; 1659 dns_name_format(&zone->origin, dname, DNS_NAME_FORMATSIZE); 1660 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1661 DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), 1662 "rpz: %s: update already queued or running", 1663 dname); 1664 if (zone->dbversion != NULL) { 1665 dns_db_closeversion(zone->db, &zone->dbversion, false); 1666 } 1667 dns_db_currentversion(zone->db, &zone->dbversion); 1668 } 1669 1670 cleanup: 1671 UNLOCK(&zone->rpzs->maint_lock); 1672 1673 return (result); 1674 } 1675 1676 static void 1677 dns_rpz_update_taskaction(isc_task_t *task, isc_event_t *event) { 1678 isc_result_t result; 1679 dns_rpz_zone_t *zone; 1680 1681 REQUIRE(event != NULL); 1682 REQUIRE(event->ev_arg != NULL); 1683 1684 UNUSED(task); 1685 zone = (dns_rpz_zone_t *)event->ev_arg; 1686 isc_event_free(&event); 1687 LOCK(&zone->rpzs->maint_lock); 1688 zone->updatepending = false; 1689 zone->updaterunning = true; 1690 dns_rpz_update_from_db(zone); 1691 result = isc_timer_reset(zone->updatetimer, isc_timertype_inactive, 1692 NULL, NULL, true); 1693 RUNTIME_CHECK(result == ISC_R_SUCCESS); 1694 result = isc_time_now(&zone->lastupdated); 1695 RUNTIME_CHECK(result == ISC_R_SUCCESS); 1696 UNLOCK(&zone->rpzs->maint_lock); 1697 } 1698 1699 static isc_result_t 1700 setup_update(dns_rpz_zone_t *rpz) { 1701 isc_result_t result; 1702 char domain[DNS_NAME_FORMATSIZE]; 1703 unsigned int nodecount; 1704 uint32_t hashsize; 1705 1706 dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE); 1707 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, 1708 ISC_LOG_INFO, "rpz: %s: reload start", domain); 1709 1710 nodecount = dns_db_nodecount(rpz->updb); 1711 hashsize = 1; 1712 while (nodecount != 0 && 1713 hashsize <= (DNS_RPZ_HTSIZE_MAX + DNS_RPZ_HTSIZE_DIV)) 1714 { 1715 hashsize++; 1716 nodecount >>= 1; 1717 } 1718 1719 if (hashsize > DNS_RPZ_HTSIZE_DIV) { 1720 hashsize -= DNS_RPZ_HTSIZE_DIV; 1721 } 1722 1723 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, 1724 ISC_LOG_DEBUG(1), "rpz: %s: using hashtable size %d", 1725 domain, hashsize); 1726 1727 isc_ht_init(&rpz->newnodes, rpz->rpzs->mctx, hashsize); 1728 1729 result = dns_db_createiterator(rpz->updb, DNS_DB_NONSEC3, &rpz->updbit); 1730 if (result != ISC_R_SUCCESS) { 1731 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1732 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1733 "rpz: %s: failed to create DB iterator - %s", 1734 domain, isc_result_totext(result)); 1735 goto cleanup; 1736 } 1737 1738 result = dns_dbiterator_first(rpz->updbit); 1739 if (result != ISC_R_SUCCESS) { 1740 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1741 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1742 "rpz: %s: failed to get db iterator - %s", domain, 1743 isc_result_totext(result)); 1744 goto cleanup; 1745 } 1746 1747 result = dns_dbiterator_pause(rpz->updbit); 1748 if (result != ISC_R_SUCCESS) { 1749 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1750 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1751 "rpz: %s: failed to pause db iterator - %s", 1752 domain, isc_result_totext(result)); 1753 goto cleanup; 1754 } 1755 1756 cleanup: 1757 if (result != ISC_R_SUCCESS) { 1758 if (rpz->updbit != NULL) { 1759 dns_dbiterator_destroy(&rpz->updbit); 1760 } 1761 if (rpz->newnodes != NULL) { 1762 isc_ht_destroy(&rpz->newnodes); 1763 } 1764 dns_db_closeversion(rpz->updb, &rpz->updbversion, false); 1765 } 1766 1767 return (result); 1768 } 1769 1770 static void 1771 finish_update(dns_rpz_zone_t *rpz) { 1772 LOCK(&rpz->rpzs->maint_lock); 1773 rpz->updaterunning = false; 1774 1775 /* 1776 * If there's an update pending, schedule it. 1777 */ 1778 if (rpz->updatepending) { 1779 if (rpz->min_update_interval > 0) { 1780 uint64_t defer = rpz->min_update_interval; 1781 char dname[DNS_NAME_FORMATSIZE]; 1782 isc_interval_t interval; 1783 1784 dns_name_format(&rpz->origin, dname, 1785 DNS_NAME_FORMATSIZE); 1786 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1787 DNS_LOGMODULE_MASTER, ISC_LOG_INFO, 1788 "rpz: %s: new zone version came " 1789 "too soon, deferring update for " 1790 "%" PRIu64 " seconds", 1791 dname, defer); 1792 isc_interval_set(&interval, (unsigned int)defer, 0); 1793 isc_timer_reset(rpz->updatetimer, isc_timertype_once, 1794 NULL, &interval, true); 1795 } else { 1796 isc_event_t *event = NULL; 1797 INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link)); 1798 ISC_EVENT_INIT(&rpz->updateevent, 1799 sizeof(rpz->updateevent), 0, NULL, 1800 DNS_EVENT_RPZUPDATED, 1801 dns_rpz_update_taskaction, rpz, rpz, 1802 NULL, NULL); 1803 event = &rpz->updateevent; 1804 isc_task_send(rpz->rpzs->updater, &event); 1805 } 1806 } 1807 UNLOCK(&rpz->rpzs->maint_lock); 1808 } 1809 1810 static void 1811 cleanup_quantum(isc_task_t *task, isc_event_t *event) { 1812 isc_result_t result = ISC_R_SUCCESS; 1813 char domain[DNS_NAME_FORMATSIZE]; 1814 dns_rpz_zone_t *rpz = NULL; 1815 isc_ht_iter_t *iter = NULL; 1816 dns_fixedname_t fname; 1817 dns_name_t *name = NULL; 1818 int count = 0; 1819 1820 UNUSED(task); 1821 1822 REQUIRE(event != NULL); 1823 REQUIRE(event->ev_sender != NULL); 1824 1825 rpz = (dns_rpz_zone_t *)event->ev_sender; 1826 iter = (isc_ht_iter_t *)event->ev_arg; 1827 isc_event_free(&event); 1828 1829 if (iter == NULL) { 1830 /* 1831 * Iterate over old ht with existing nodes deleted to 1832 * delete deleted nodes from RPZ 1833 */ 1834 isc_ht_iter_create(rpz->nodes, &iter); 1835 } 1836 1837 name = dns_fixedname_initname(&fname); 1838 1839 LOCK(&rpz->rpzs->maint_lock); 1840 1841 /* Check that we aren't shutting down. */ 1842 if (rpz->rpzs->zones[rpz->num] == NULL) { 1843 UNLOCK(&rpz->rpzs->maint_lock); 1844 goto cleanup; 1845 } 1846 1847 for (result = isc_ht_iter_first(iter); 1848 result == ISC_R_SUCCESS && count++ < DNS_RPZ_QUANTUM; 1849 result = isc_ht_iter_delcurrent_next(iter)) 1850 { 1851 isc_region_t region; 1852 unsigned char *key = NULL; 1853 size_t keysize; 1854 1855 isc_ht_iter_currentkey(iter, &key, &keysize); 1856 region.base = key; 1857 region.length = (unsigned int)keysize; 1858 dns_name_fromregion(name, ®ion); 1859 dns_rpz_delete(rpz->rpzs, rpz->num, name); 1860 } 1861 1862 if (result == ISC_R_SUCCESS) { 1863 isc_event_t *nevent = NULL; 1864 1865 /* 1866 * We finished a quantum; trigger the next one and return. 1867 */ 1868 1869 INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link)); 1870 ISC_EVENT_INIT(&rpz->updateevent, sizeof(rpz->updateevent), 0, 1871 NULL, DNS_EVENT_RPZUPDATED, cleanup_quantum, 1872 iter, rpz, NULL, NULL); 1873 nevent = &rpz->updateevent; 1874 isc_task_send(rpz->rpzs->updater, &nevent); 1875 UNLOCK(&rpz->rpzs->maint_lock); 1876 return; 1877 } else if (result == ISC_R_NOMORE) { 1878 isc_ht_t *tmpht = NULL; 1879 1880 /* 1881 * Done with cleanup of deleted nodes; finalize 1882 * the update. 1883 */ 1884 tmpht = rpz->nodes; 1885 rpz->nodes = rpz->newnodes; 1886 rpz->newnodes = tmpht; 1887 1888 UNLOCK(&rpz->rpzs->maint_lock); 1889 finish_update(rpz); 1890 dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE); 1891 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1892 DNS_LOGMODULE_MASTER, ISC_LOG_INFO, 1893 "rpz: %s: reload done", domain); 1894 } else { 1895 UNLOCK(&rpz->rpzs->maint_lock); 1896 } 1897 1898 /* 1899 * If we're here, we're finished or something went wrong. 1900 */ 1901 cleanup: 1902 if (iter != NULL) { 1903 isc_ht_iter_destroy(&iter); 1904 } 1905 if (rpz->newnodes != NULL) { 1906 isc_ht_destroy(&rpz->newnodes); 1907 } 1908 dns_db_closeversion(rpz->updb, &rpz->updbversion, false); 1909 dns_db_detach(&rpz->updb); 1910 rpz_detach(&rpz); 1911 } 1912 1913 static void 1914 update_quantum(isc_task_t *task, isc_event_t *event) { 1915 isc_result_t result = ISC_R_SUCCESS; 1916 dns_dbnode_t *node = NULL; 1917 dns_rpz_zone_t *rpz = NULL; 1918 char domain[DNS_NAME_FORMATSIZE]; 1919 dns_fixedname_t fixname; 1920 dns_name_t *name = NULL; 1921 isc_event_t *nevent = NULL; 1922 int count = 0; 1923 1924 UNUSED(task); 1925 1926 REQUIRE(event != NULL); 1927 REQUIRE(event->ev_arg != NULL); 1928 1929 rpz = (dns_rpz_zone_t *)event->ev_arg; 1930 isc_event_free(&event); 1931 1932 REQUIRE(rpz->updbit != NULL); 1933 REQUIRE(rpz->newnodes != NULL); 1934 1935 name = dns_fixedname_initname(&fixname); 1936 1937 dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE); 1938 1939 LOCK(&rpz->rpzs->maint_lock); 1940 1941 /* Check that we aren't shutting down. */ 1942 if (rpz->rpzs->zones[rpz->num] == NULL) { 1943 UNLOCK(&rpz->rpzs->maint_lock); 1944 goto cleanup; 1945 } 1946 1947 while (result == ISC_R_SUCCESS && count++ < DNS_RPZ_QUANTUM) { 1948 char namebuf[DNS_NAME_FORMATSIZE]; 1949 dns_rdatasetiter_t *rdsiter = NULL; 1950 1951 result = dns_dbiterator_current(rpz->updbit, &node, name); 1952 if (result != ISC_R_SUCCESS) { 1953 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1954 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1955 "rpz: %s: failed to get dbiterator - %s", 1956 domain, isc_result_totext(result)); 1957 dns_db_detachnode(rpz->updb, &node); 1958 break; 1959 } 1960 1961 result = dns_db_allrdatasets(rpz->updb, node, rpz->updbversion, 1962 0, 0, &rdsiter); 1963 if (result != ISC_R_SUCCESS) { 1964 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1965 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1966 "rpz: %s: failed to fetch " 1967 "rrdatasets - %s", 1968 domain, isc_result_totext(result)); 1969 dns_db_detachnode(rpz->updb, &node); 1970 break; 1971 } 1972 1973 result = dns_rdatasetiter_first(rdsiter); 1974 dns_rdatasetiter_destroy(&rdsiter); 1975 if (result != ISC_R_SUCCESS) { /* empty non-terminal */ 1976 if (result != ISC_R_NOMORE) { 1977 isc_log_write( 1978 dns_lctx, DNS_LOGCATEGORY_GENERAL, 1979 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1980 "rpz: %s: error %s while creating " 1981 "rdatasetiter", 1982 domain, isc_result_totext(result)); 1983 } 1984 dns_db_detachnode(rpz->updb, &node); 1985 result = dns_dbiterator_next(rpz->updbit); 1986 continue; 1987 } 1988 1989 dns_name_downcase(name, name, NULL); 1990 result = isc_ht_add(rpz->newnodes, name->ndata, name->length, 1991 rpz); 1992 if (result != ISC_R_SUCCESS) { 1993 dns_name_format(name, namebuf, sizeof(namebuf)); 1994 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 1995 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, 1996 "rpz: %s, adding node %s to HT error %s", 1997 domain, namebuf, 1998 isc_result_totext(result)); 1999 dns_db_detachnode(rpz->updb, &node); 2000 result = dns_dbiterator_next(rpz->updbit); 2001 continue; 2002 } 2003 2004 result = isc_ht_find(rpz->nodes, name->ndata, name->length, 2005 NULL); 2006 if (result == ISC_R_SUCCESS) { 2007 isc_ht_delete(rpz->nodes, name->ndata, name->length); 2008 } else { /* not found */ 2009 result = dns_rpz_add(rpz->rpzs, rpz->num, name); 2010 if (result != ISC_R_SUCCESS) { 2011 dns_name_format(name, namebuf, sizeof(namebuf)); 2012 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 2013 DNS_LOGMODULE_MASTER, 2014 ISC_LOG_ERROR, 2015 "rpz: %s: adding node %s " 2016 "to RPZ error %s", 2017 domain, namebuf, 2018 isc_result_totext(result)); 2019 } else { 2020 dns_name_format(name, namebuf, sizeof(namebuf)); 2021 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 2022 DNS_LOGMODULE_MASTER, 2023 ISC_LOG_DEBUG(3), 2024 "rpz: %s: adding node %s", domain, 2025 namebuf); 2026 } 2027 } 2028 2029 dns_db_detachnode(rpz->updb, &node); 2030 result = dns_dbiterator_next(rpz->updbit); 2031 } 2032 2033 if (result == ISC_R_SUCCESS) { 2034 /* 2035 * Pause the iterator so that the DB is not locked. 2036 */ 2037 dns_dbiterator_pause(rpz->updbit); 2038 2039 /* 2040 * We finished a quantum; trigger the next one and return. 2041 */ 2042 INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link)); 2043 ISC_EVENT_INIT(&rpz->updateevent, sizeof(rpz->updateevent), 0, 2044 NULL, DNS_EVENT_RPZUPDATED, update_quantum, rpz, 2045 rpz, NULL, NULL); 2046 nevent = &rpz->updateevent; 2047 isc_task_send(rpz->rpzs->updater, &nevent); 2048 UNLOCK(&rpz->rpzs->maint_lock); 2049 return; 2050 } else if (result == ISC_R_NOMORE) { 2051 /* 2052 * Done with the new database; now we just need to 2053 * clean up the old. 2054 */ 2055 dns_dbiterator_destroy(&rpz->updbit); 2056 2057 INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link)); 2058 ISC_EVENT_INIT(&rpz->updateevent, sizeof(rpz->updateevent), 0, 2059 NULL, DNS_EVENT_RPZUPDATED, cleanup_quantum, 2060 NULL, rpz, NULL, NULL); 2061 nevent = &rpz->updateevent; 2062 isc_task_send(rpz->rpzs->updater, &nevent); 2063 UNLOCK(&rpz->rpzs->maint_lock); 2064 return; 2065 } 2066 2067 /* 2068 * If we're here, something went wrong, so clean up. 2069 */ 2070 UNLOCK(&rpz->rpzs->maint_lock); 2071 2072 cleanup: 2073 if (rpz->updbit != NULL) { 2074 dns_dbiterator_destroy(&rpz->updbit); 2075 } 2076 if (rpz->newnodes != NULL) { 2077 isc_ht_destroy(&rpz->newnodes); 2078 } 2079 dns_db_closeversion(rpz->updb, &rpz->updbversion, false); 2080 dns_db_detach(&rpz->updb); 2081 rpz_detach(&rpz); 2082 } 2083 2084 static void 2085 dns_rpz_update_from_db(dns_rpz_zone_t *rpz) { 2086 isc_result_t result; 2087 isc_event_t *event; 2088 2089 REQUIRE(rpz != NULL); 2090 REQUIRE(DNS_DB_VALID(rpz->db)); 2091 REQUIRE(rpz->updb == NULL); 2092 REQUIRE(rpz->updbversion == NULL); 2093 REQUIRE(rpz->updbit == NULL); 2094 REQUIRE(rpz->newnodes == NULL); 2095 2096 isc_refcount_increment(&rpz->refs); 2097 dns_db_attach(rpz->db, &rpz->updb); 2098 rpz->updbversion = rpz->dbversion; 2099 rpz->dbversion = NULL; 2100 2101 result = setup_update(rpz); 2102 if (result != ISC_R_SUCCESS) { 2103 goto cleanup; 2104 } 2105 2106 event = &rpz->updateevent; 2107 INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link)); 2108 ISC_EVENT_INIT(&rpz->updateevent, sizeof(rpz->updateevent), 0, NULL, 2109 DNS_EVENT_RPZUPDATED, update_quantum, rpz, rpz, NULL, 2110 NULL); 2111 isc_task_send(rpz->rpzs->updater, &event); 2112 return; 2113 2114 cleanup: 2115 if (rpz->updbit != NULL) { 2116 dns_dbiterator_destroy(&rpz->updbit); 2117 } 2118 if (rpz->newnodes != NULL) { 2119 isc_ht_destroy(&rpz->newnodes); 2120 } 2121 dns_db_closeversion(rpz->updb, &rpz->updbversion, false); 2122 dns_db_detach(&rpz->updb); 2123 rpz_detach(&rpz); 2124 } 2125 2126 /* 2127 * Free the radix tree of a response policy database. 2128 */ 2129 static void 2130 cidr_free(dns_rpz_zones_t *rpzs) { 2131 dns_rpz_cidr_node_t *cur, *child, *parent; 2132 2133 cur = rpzs->cidr; 2134 while (cur != NULL) { 2135 /* Depth first. */ 2136 child = cur->child[0]; 2137 if (child != NULL) { 2138 cur = child; 2139 continue; 2140 } 2141 child = cur->child[1]; 2142 if (child != NULL) { 2143 cur = child; 2144 continue; 2145 } 2146 2147 /* Delete this leaf and go up. */ 2148 parent = cur->parent; 2149 if (parent == NULL) { 2150 rpzs->cidr = NULL; 2151 } else { 2152 parent->child[parent->child[1] == cur] = NULL; 2153 } 2154 isc_mem_put(rpzs->mctx, cur, sizeof(*cur)); 2155 cur = parent; 2156 } 2157 } 2158 2159 /* 2160 * Discard a response policy zone blob 2161 * before discarding the overall rpz structure. 2162 */ 2163 static void 2164 rpz_detach(dns_rpz_zone_t **rpzp) { 2165 dns_rpz_zone_t *rpz; 2166 dns_rpz_zones_t *rpzs; 2167 2168 REQUIRE(rpzp != NULL && *rpzp != NULL); 2169 2170 rpz = *rpzp; 2171 *rpzp = NULL; 2172 2173 if (isc_refcount_decrement(&rpz->refs) == 1) { 2174 isc_refcount_destroy(&rpz->refs); 2175 2176 rpzs = rpz->rpzs; 2177 rpz->rpzs = NULL; 2178 2179 if (dns_name_dynamic(&rpz->origin)) { 2180 dns_name_free(&rpz->origin, rpzs->mctx); 2181 } 2182 if (dns_name_dynamic(&rpz->client_ip)) { 2183 dns_name_free(&rpz->client_ip, rpzs->mctx); 2184 } 2185 if (dns_name_dynamic(&rpz->ip)) { 2186 dns_name_free(&rpz->ip, rpzs->mctx); 2187 } 2188 if (dns_name_dynamic(&rpz->nsdname)) { 2189 dns_name_free(&rpz->nsdname, rpzs->mctx); 2190 } 2191 if (dns_name_dynamic(&rpz->nsip)) { 2192 dns_name_free(&rpz->nsip, rpzs->mctx); 2193 } 2194 if (dns_name_dynamic(&rpz->passthru)) { 2195 dns_name_free(&rpz->passthru, rpzs->mctx); 2196 } 2197 if (dns_name_dynamic(&rpz->drop)) { 2198 dns_name_free(&rpz->drop, rpzs->mctx); 2199 } 2200 if (dns_name_dynamic(&rpz->tcp_only)) { 2201 dns_name_free(&rpz->tcp_only, rpzs->mctx); 2202 } 2203 if (dns_name_dynamic(&rpz->cname)) { 2204 dns_name_free(&rpz->cname, rpzs->mctx); 2205 } 2206 if (rpz->db != NULL) { 2207 if (rpz->dbversion != NULL) { 2208 dns_db_closeversion(rpz->db, &rpz->dbversion, 2209 false); 2210 } 2211 dns_db_updatenotify_unregister( 2212 rpz->db, dns_rpz_dbupdate_callback, rpz); 2213 dns_db_detach(&rpz->db); 2214 } 2215 if (rpz->updaterunning) { 2216 isc_task_purgeevent(rpzs->updater, &rpz->updateevent); 2217 if (rpz->updbit != NULL) { 2218 dns_dbiterator_destroy(&rpz->updbit); 2219 } 2220 if (rpz->newnodes != NULL) { 2221 isc_ht_destroy(&rpz->newnodes); 2222 } 2223 if (rpz->updb != NULL) { 2224 if (rpz->updbversion != NULL) { 2225 dns_db_closeversion(rpz->updb, 2226 &rpz->updbversion, 2227 false); 2228 } 2229 dns_db_detach(&rpz->updb); 2230 } 2231 } 2232 2233 isc_timer_reset(rpz->updatetimer, isc_timertype_inactive, NULL, 2234 NULL, true); 2235 isc_timer_destroy(&rpz->updatetimer); 2236 2237 isc_ht_destroy(&rpz->nodes); 2238 2239 isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz)); 2240 rpz_detach_rpzs(&rpzs); 2241 } 2242 } 2243 2244 void 2245 dns_rpz_attach_rpzs(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **rpzsp) { 2246 REQUIRE(rpzsp != NULL && *rpzsp == NULL); 2247 isc_refcount_increment(&rpzs->refs); 2248 *rpzsp = rpzs; 2249 } 2250 2251 /* 2252 * Forget a view's policy zones. 2253 */ 2254 void 2255 dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) { 2256 REQUIRE(rpzsp != NULL && *rpzsp != NULL); 2257 dns_rpz_zones_t *rpzs = *rpzsp; 2258 *rpzsp = NULL; 2259 2260 if (isc_refcount_decrement(&rpzs->refs) == 1) { 2261 LOCK(&rpzs->maint_lock); 2262 /* 2263 * Forget the last of view's rpz machinery after 2264 * the last reference. 2265 */ 2266 for (dns_rpz_num_t rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; 2267 ++rpz_num) 2268 { 2269 dns_rpz_zone_t *rpz = rpzs->zones[rpz_num]; 2270 rpzs->zones[rpz_num] = NULL; 2271 if (rpz != NULL) { 2272 rpz_detach(&rpz); 2273 } 2274 } 2275 UNLOCK(&rpzs->maint_lock); 2276 rpz_detach_rpzs(&rpzs); 2277 } 2278 } 2279 2280 static void 2281 rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) { 2282 REQUIRE(rpzsp != NULL && *rpzsp != NULL); 2283 dns_rpz_zones_t *rpzs = *rpzsp; 2284 *rpzsp = NULL; 2285 2286 if (isc_refcount_decrement(&rpzs->irefs) == 1) { 2287 if (rpzs->rps_cstr_size != 0) { 2288 #ifdef USE_DNSRPS 2289 librpz->client_detach(&rpzs->rps_client); 2290 #endif /* ifdef USE_DNSRPS */ 2291 isc_mem_put(rpzs->mctx, rpzs->rps_cstr, 2292 rpzs->rps_cstr_size); 2293 } 2294 2295 cidr_free(rpzs); 2296 if (rpzs->rbt != NULL) { 2297 dns_rbt_destroy(&rpzs->rbt); 2298 } 2299 isc_task_destroy(&rpzs->updater); 2300 isc_mutex_destroy(&rpzs->maint_lock); 2301 isc_rwlock_destroy(&rpzs->search_lock); 2302 isc_refcount_destroy(&rpzs->refs); 2303 isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs)); 2304 } 2305 } 2306 2307 /* 2308 * Deprecated and removed. 2309 */ 2310 isc_result_t 2311 dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp, dns_rpz_zones_t *rpzs, 2312 dns_rpz_num_t rpz_num) { 2313 UNUSED(load_rpzsp); 2314 UNUSED(rpzs); 2315 UNUSED(rpz_num); 2316 2317 return (ISC_R_NOTIMPLEMENTED); 2318 } 2319 2320 /* 2321 * Deprecated and removed. 2322 */ 2323 isc_result_t 2324 dns_rpz_ready(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **load_rpzsp, 2325 dns_rpz_num_t rpz_num) { 2326 UNUSED(rpzs); 2327 UNUSED(load_rpzsp); 2328 UNUSED(rpz_num); 2329 2330 return (ISC_R_NOTIMPLEMENTED); 2331 } 2332 2333 /* 2334 * Add an IP address to the radix tree or a name to the summary database. 2335 */ 2336 isc_result_t 2337 dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, 2338 const dns_name_t *src_name) { 2339 dns_rpz_zone_t *rpz; 2340 dns_rpz_type_t rpz_type; 2341 isc_result_t result = ISC_R_FAILURE; 2342 2343 REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); 2344 rpz = rpzs->zones[rpz_num]; 2345 REQUIRE(rpz != NULL); 2346 RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); 2347 2348 rpz_type = type_from_name(rpzs, rpz, src_name); 2349 2350 switch (rpz_type) { 2351 case DNS_RPZ_TYPE_QNAME: 2352 case DNS_RPZ_TYPE_NSDNAME: 2353 result = add_name(rpzs, rpz_num, rpz_type, src_name); 2354 break; 2355 case DNS_RPZ_TYPE_CLIENT_IP: 2356 case DNS_RPZ_TYPE_IP: 2357 case DNS_RPZ_TYPE_NSIP: 2358 result = add_cidr(rpzs, rpz_num, rpz_type, src_name); 2359 break; 2360 case DNS_RPZ_TYPE_BAD: 2361 break; 2362 } 2363 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); 2364 2365 return (result); 2366 } 2367 2368 /* 2369 * Remove an IP address from the radix tree. 2370 */ 2371 static void 2372 del_cidr(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, 2373 const dns_name_t *src_name) { 2374 isc_result_t result; 2375 dns_rpz_cidr_key_t tgt_ip; 2376 dns_rpz_prefix_t tgt_prefix; 2377 dns_rpz_addr_zbits_t tgt_set; 2378 dns_rpz_cidr_node_t *tgt, *parent, *child; 2379 2380 /* 2381 * Do not worry about invalid rpz IP address names. If we 2382 * are here, then something relevant was added and so was 2383 * valid. Invalid names here are usually internal RBTDB nodes. 2384 */ 2385 result = name2ipkey(DNS_RPZ_DEBUG_QUIET, rpzs, rpz_num, rpz_type, 2386 src_name, &tgt_ip, &tgt_prefix, &tgt_set); 2387 if (result != ISC_R_SUCCESS) { 2388 return; 2389 } 2390 2391 result = search(rpzs, &tgt_ip, tgt_prefix, &tgt_set, false, &tgt); 2392 if (result != ISC_R_SUCCESS) { 2393 INSIST(result == ISC_R_NOTFOUND || 2394 result == DNS_R_PARTIALMATCH); 2395 /* 2396 * Do not worry about missing summary RBT nodes that probably 2397 * correspond to RBTDB nodes that were implicit RBT nodes 2398 * that were later added for (often empty) wildcards 2399 * and then to the RBTDB deferred cleanup list. 2400 */ 2401 return; 2402 } 2403 2404 /* 2405 * Mark the node and its parents to reflect the deleted IP address. 2406 * Do not count bits that are already clear for internal RBTDB nodes. 2407 */ 2408 tgt_set.client_ip &= tgt->set.client_ip; 2409 tgt_set.ip &= tgt->set.ip; 2410 tgt_set.nsip &= tgt->set.nsip; 2411 tgt->set.client_ip &= ~tgt_set.client_ip; 2412 tgt->set.ip &= ~tgt_set.ip; 2413 tgt->set.nsip &= ~tgt_set.nsip; 2414 set_sum_pair(tgt); 2415 2416 adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix, false); 2417 2418 /* 2419 * We might need to delete 2 nodes. 2420 */ 2421 do { 2422 /* 2423 * The node is now useless if it has no data of its own 2424 * and 0 or 1 children. We are finished if it is not useless. 2425 */ 2426 if ((child = tgt->child[0]) != NULL) { 2427 if (tgt->child[1] != NULL) { 2428 break; 2429 } 2430 } else { 2431 child = tgt->child[1]; 2432 } 2433 if (tgt->set.client_ip != 0 || tgt->set.ip != 0 || 2434 tgt->set.nsip != 0) 2435 { 2436 break; 2437 } 2438 2439 /* 2440 * Replace the pointer to this node in the parent with 2441 * the remaining child or NULL. 2442 */ 2443 parent = tgt->parent; 2444 if (parent == NULL) { 2445 rpzs->cidr = child; 2446 } else { 2447 parent->child[parent->child[1] == tgt] = child; 2448 } 2449 /* 2450 * If the child exists fix up its parent pointer. 2451 */ 2452 if (child != NULL) { 2453 child->parent = parent; 2454 } 2455 isc_mem_put(rpzs->mctx, tgt, sizeof(*tgt)); 2456 2457 tgt = parent; 2458 } while (tgt != NULL); 2459 } 2460 2461 static void 2462 del_name(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, 2463 const dns_name_t *src_name) { 2464 char namebuf[DNS_NAME_FORMATSIZE]; 2465 dns_fixedname_t trig_namef; 2466 dns_name_t *trig_name; 2467 dns_rbtnode_t *nmnode; 2468 dns_rpz_nm_data_t *nm_data, del_data; 2469 isc_result_t result; 2470 bool exists; 2471 2472 /* 2473 * We need a summary database of names even with 1 policy zone, 2474 * because wildcard triggers are handled differently. 2475 */ 2476 2477 trig_name = dns_fixedname_initname(&trig_namef); 2478 name2data(rpzs, rpz_num, rpz_type, src_name, trig_name, &del_data); 2479 2480 nmnode = NULL; 2481 result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, NULL, 0, 2482 NULL, NULL); 2483 if (result != ISC_R_SUCCESS) { 2484 /* 2485 * Do not worry about missing summary RBT nodes that probably 2486 * correspond to RBTDB nodes that were implicit RBT nodes 2487 * that were later added for (often empty) wildcards 2488 * and then to the RBTDB deferred cleanup list. 2489 */ 2490 if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) { 2491 return; 2492 } 2493 dns_name_format(src_name, namebuf, sizeof(namebuf)); 2494 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 2495 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 2496 "rpz del_name(%s) node search failed: %s", 2497 namebuf, isc_result_totext(result)); 2498 return; 2499 } 2500 2501 nm_data = nmnode->data; 2502 INSIST(nm_data != NULL); 2503 2504 /* 2505 * Do not count bits that next existed for RBT nodes that would we 2506 * would not have found in a summary for a single RBTDB tree. 2507 */ 2508 del_data.set.qname &= nm_data->set.qname; 2509 del_data.set.ns &= nm_data->set.ns; 2510 del_data.wild.qname &= nm_data->wild.qname; 2511 del_data.wild.ns &= nm_data->wild.ns; 2512 2513 exists = (del_data.set.qname != 0 || del_data.set.ns != 0 || 2514 del_data.wild.qname != 0 || del_data.wild.ns != 0); 2515 2516 nm_data->set.qname &= ~del_data.set.qname; 2517 nm_data->set.ns &= ~del_data.set.ns; 2518 nm_data->wild.qname &= ~del_data.wild.qname; 2519 nm_data->wild.ns &= ~del_data.wild.ns; 2520 2521 if (nm_data->set.qname == 0 && nm_data->set.ns == 0 && 2522 nm_data->wild.qname == 0 && nm_data->wild.ns == 0) 2523 { 2524 result = dns_rbt_deletenode(rpzs->rbt, nmnode, false); 2525 if (result != ISC_R_SUCCESS) { 2526 /* 2527 * bin/tests/system/rpz/tests.sh looks for 2528 * "rpz.*failed". 2529 */ 2530 dns_name_format(src_name, namebuf, sizeof(namebuf)); 2531 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 2532 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 2533 "rpz del_name(%s) node delete failed: %s", 2534 namebuf, isc_result_totext(result)); 2535 } 2536 } 2537 2538 if (exists) { 2539 adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, false); 2540 } 2541 } 2542 2543 /* 2544 * Remove an IP address from the radix tree or a name from the summary database. 2545 */ 2546 void 2547 dns_rpz_delete(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, 2548 const dns_name_t *src_name) { 2549 dns_rpz_zone_t *rpz; 2550 dns_rpz_type_t rpz_type; 2551 2552 REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); 2553 rpz = rpzs->zones[rpz_num]; 2554 REQUIRE(rpz != NULL); 2555 2556 RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); 2557 2558 rpz_type = type_from_name(rpzs, rpz, src_name); 2559 2560 switch (rpz_type) { 2561 case DNS_RPZ_TYPE_QNAME: 2562 case DNS_RPZ_TYPE_NSDNAME: 2563 del_name(rpzs, rpz_num, rpz_type, src_name); 2564 break; 2565 case DNS_RPZ_TYPE_CLIENT_IP: 2566 case DNS_RPZ_TYPE_IP: 2567 case DNS_RPZ_TYPE_NSIP: 2568 del_cidr(rpzs, rpz_num, rpz_type, src_name); 2569 break; 2570 case DNS_RPZ_TYPE_BAD: 2571 break; 2572 } 2573 2574 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); 2575 } 2576 2577 /* 2578 * Search the summary radix tree to get a relative owner name in a 2579 * policy zone relevant to a triggering IP address. 2580 * rpz_type and zbits limit the search for IP address netaddr 2581 * return the policy zone's number or DNS_RPZ_INVALID_NUM 2582 * ip_name is the relative owner name found and 2583 * *prefixp is its prefix length. 2584 */ 2585 dns_rpz_num_t 2586 dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, 2587 dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr, 2588 dns_name_t *ip_name, dns_rpz_prefix_t *prefixp) { 2589 dns_rpz_cidr_key_t tgt_ip; 2590 dns_rpz_addr_zbits_t tgt_set; 2591 dns_rpz_cidr_node_t *found; 2592 isc_result_t result; 2593 dns_rpz_num_t rpz_num = 0; 2594 dns_rpz_have_t have; 2595 int i; 2596 2597 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2598 have = rpzs->have; 2599 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2600 2601 /* 2602 * Convert IP address to CIDR tree key. 2603 */ 2604 if (netaddr->family == AF_INET) { 2605 tgt_ip.w[0] = 0; 2606 tgt_ip.w[1] = 0; 2607 tgt_ip.w[2] = ADDR_V4MAPPED; 2608 tgt_ip.w[3] = ntohl(netaddr->type.in.s_addr); 2609 switch (rpz_type) { 2610 case DNS_RPZ_TYPE_CLIENT_IP: 2611 zbits &= have.client_ipv4; 2612 break; 2613 case DNS_RPZ_TYPE_IP: 2614 zbits &= have.ipv4; 2615 break; 2616 case DNS_RPZ_TYPE_NSIP: 2617 zbits &= have.nsipv4; 2618 break; 2619 default: 2620 UNREACHABLE(); 2621 } 2622 } else if (netaddr->family == AF_INET6) { 2623 dns_rpz_cidr_key_t src_ip6; 2624 2625 /* 2626 * Given the int aligned struct in_addr member of netaddr->type 2627 * one could cast netaddr->type.in6 to dns_rpz_cidr_key_t *, 2628 * but some people object. 2629 */ 2630 memmove(src_ip6.w, &netaddr->type.in6, sizeof(src_ip6.w)); 2631 for (i = 0; i < 4; i++) { 2632 tgt_ip.w[i] = ntohl(src_ip6.w[i]); 2633 } 2634 switch (rpz_type) { 2635 case DNS_RPZ_TYPE_CLIENT_IP: 2636 zbits &= have.client_ipv6; 2637 break; 2638 case DNS_RPZ_TYPE_IP: 2639 zbits &= have.ipv6; 2640 break; 2641 case DNS_RPZ_TYPE_NSIP: 2642 zbits &= have.nsipv6; 2643 break; 2644 default: 2645 UNREACHABLE(); 2646 } 2647 } else { 2648 return (DNS_RPZ_INVALID_NUM); 2649 } 2650 2651 if (zbits == 0) { 2652 return (DNS_RPZ_INVALID_NUM); 2653 } 2654 make_addr_set(&tgt_set, zbits, rpz_type); 2655 2656 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2657 result = search(rpzs, &tgt_ip, 128, &tgt_set, false, &found); 2658 if (result == ISC_R_NOTFOUND) { 2659 /* 2660 * There are no eligible zones for this IP address. 2661 */ 2662 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2663 return (DNS_RPZ_INVALID_NUM); 2664 } 2665 2666 /* 2667 * Construct the trigger name for the longest matching trigger 2668 * in the first eligible zone with a match. 2669 */ 2670 *prefixp = found->prefix; 2671 switch (rpz_type) { 2672 case DNS_RPZ_TYPE_CLIENT_IP: 2673 rpz_num = zbit_to_num(found->set.client_ip & tgt_set.client_ip); 2674 break; 2675 case DNS_RPZ_TYPE_IP: 2676 rpz_num = zbit_to_num(found->set.ip & tgt_set.ip); 2677 break; 2678 case DNS_RPZ_TYPE_NSIP: 2679 rpz_num = zbit_to_num(found->set.nsip & tgt_set.nsip); 2680 break; 2681 default: 2682 UNREACHABLE(); 2683 } 2684 result = ip2name(&found->ip, found->prefix, dns_rootname, ip_name); 2685 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2686 if (result != ISC_R_SUCCESS) { 2687 /* 2688 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". 2689 */ 2690 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 2691 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 2692 "rpz ip2name() failed: %s", 2693 isc_result_totext(result)); 2694 return (DNS_RPZ_INVALID_NUM); 2695 } 2696 return (rpz_num); 2697 } 2698 2699 /* 2700 * Search the summary radix tree for policy zones with triggers matching 2701 * a name. 2702 */ 2703 dns_rpz_zbits_t 2704 dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, 2705 dns_rpz_zbits_t zbits, dns_name_t *trig_name) { 2706 char namebuf[DNS_NAME_FORMATSIZE]; 2707 dns_rbtnode_t *nmnode; 2708 const dns_rpz_nm_data_t *nm_data; 2709 dns_rpz_zbits_t found_zbits; 2710 dns_rbtnodechain_t chain; 2711 isc_result_t result; 2712 int i; 2713 2714 if (zbits == 0) { 2715 return (0); 2716 } 2717 2718 found_zbits = 0; 2719 2720 dns_rbtnodechain_init(&chain); 2721 2722 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2723 2724 nmnode = NULL; 2725 result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, &chain, 2726 DNS_RBTFIND_EMPTYDATA, NULL, NULL); 2727 2728 switch (result) { 2729 case ISC_R_SUCCESS: 2730 nm_data = nmnode->data; 2731 if (nm_data != NULL) { 2732 if (rpz_type == DNS_RPZ_TYPE_QNAME) { 2733 found_zbits = nm_data->set.qname; 2734 } else { 2735 found_zbits = nm_data->set.ns; 2736 } 2737 } 2738 FALLTHROUGH; 2739 2740 case DNS_R_PARTIALMATCH: 2741 i = chain.level_matches; 2742 nmnode = chain.levels[chain.level_matches]; 2743 2744 /* 2745 * Whenever an exact match is found by dns_rbt_findnode(), 2746 * the highest level node in the chain will not be put into 2747 * chain->levels[] array, but instead the chain->end 2748 * pointer will be adjusted to point to that node. 2749 * 2750 * Suppose we have the following entries in a rpz zone: 2751 * example.com CNAME rpz-passthru. 2752 * *.example.com CNAME rpz-passthru. 2753 * 2754 * A query for www.example.com would result in the 2755 * following chain object returned by dns_rbt_findnode(): 2756 * chain->level_count = 2 2757 * chain->level_matches = 2 2758 * chain->levels[0] = . 2759 * chain->levels[1] = example.com 2760 * chain->levels[2] = NULL 2761 * chain->end = www 2762 * 2763 * Since exact matches only care for testing rpz set bits, 2764 * we need to test for rpz wild bits through iterating the 2765 * nodechain, and that includes testing the rpz wild bits 2766 * in the highest level node found. In the case of an exact 2767 * match, chain->levels[chain->level_matches] will be NULL, 2768 * to address that we must use chain->end as the start 2769 * point, then iterate over the remaining levels in the 2770 * chain. 2771 */ 2772 if (nmnode == NULL) { 2773 --i; 2774 nmnode = chain.end; 2775 } 2776 2777 while (nmnode != NULL) { 2778 nm_data = nmnode->data; 2779 if (nm_data != NULL) { 2780 if (rpz_type == DNS_RPZ_TYPE_QNAME) { 2781 found_zbits |= nm_data->wild.qname; 2782 } else { 2783 found_zbits |= nm_data->wild.ns; 2784 } 2785 } 2786 2787 if (i >= 0) { 2788 nmnode = chain.levels[i]; 2789 --i; 2790 } else { 2791 break; 2792 } 2793 } 2794 break; 2795 2796 case ISC_R_NOTFOUND: 2797 break; 2798 2799 default: 2800 /* 2801 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". 2802 */ 2803 dns_name_format(trig_name, namebuf, sizeof(namebuf)); 2804 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, 2805 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, 2806 "dns_rpz_find_name(%s) failed: %s", namebuf, 2807 isc_result_totext(result)); 2808 break; 2809 } 2810 2811 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 2812 2813 dns_rbtnodechain_invalidate(&chain); 2814 2815 return (zbits & found_zbits); 2816 } 2817 2818 /* 2819 * Translate CNAME rdata to a QNAME response policy action. 2820 */ 2821 dns_rpz_policy_t 2822 dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, 2823 dns_name_t *selfname) { 2824 dns_rdata_t rdata = DNS_RDATA_INIT; 2825 dns_rdata_cname_t cname; 2826 isc_result_t result; 2827 2828 result = dns_rdataset_first(rdataset); 2829 INSIST(result == ISC_R_SUCCESS); 2830 dns_rdataset_current(rdataset, &rdata); 2831 result = dns_rdata_tostruct(&rdata, &cname, NULL); 2832 INSIST(result == ISC_R_SUCCESS); 2833 dns_rdata_reset(&rdata); 2834 2835 /* 2836 * CNAME . means NXDOMAIN 2837 */ 2838 if (dns_name_equal(&cname.cname, dns_rootname)) { 2839 return (DNS_RPZ_POLICY_NXDOMAIN); 2840 } 2841 2842 if (dns_name_iswildcard(&cname.cname)) { 2843 /* 2844 * CNAME *. means NODATA 2845 */ 2846 if (dns_name_countlabels(&cname.cname) == 2) { 2847 return (DNS_RPZ_POLICY_NODATA); 2848 } 2849 2850 /* 2851 * A qname of www.evil.com and a policy of 2852 * *.evil.com CNAME *.garden.net 2853 * gives a result of 2854 * evil.com CNAME evil.com.garden.net 2855 */ 2856 if (dns_name_countlabels(&cname.cname) > 2) { 2857 return (DNS_RPZ_POLICY_WILDCNAME); 2858 } 2859 } 2860 2861 /* 2862 * CNAME rpz-tcp-only. means "send truncated UDP responses." 2863 */ 2864 if (dns_name_equal(&cname.cname, &rpz->tcp_only)) { 2865 return (DNS_RPZ_POLICY_TCP_ONLY); 2866 } 2867 2868 /* 2869 * CNAME rpz-drop. means "do not respond." 2870 */ 2871 if (dns_name_equal(&cname.cname, &rpz->drop)) { 2872 return (DNS_RPZ_POLICY_DROP); 2873 } 2874 2875 /* 2876 * CNAME rpz-passthru. means "do not rewrite." 2877 */ 2878 if (dns_name_equal(&cname.cname, &rpz->passthru)) { 2879 return (DNS_RPZ_POLICY_PASSTHRU); 2880 } 2881 2882 /* 2883 * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU 2884 */ 2885 if (selfname != NULL && dns_name_equal(&cname.cname, selfname)) { 2886 return (DNS_RPZ_POLICY_PASSTHRU); 2887 } 2888 2889 /* 2890 * Any other rdata gives a response consisting of the rdata. 2891 */ 2892 return (DNS_RPZ_POLICY_RECORD); 2893 } 2894