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