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