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