rpz.c revision 1.6 1 /* $NetBSD: rpz.c,v 1.6 2019/10/17 16:47:00 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",
1661 dname);
1662 if (zone->dbversion != NULL) {
1663 dns_db_closeversion(zone->db, &zone->dbversion,
1664 false);
1665 }
1666 dns_db_currentversion(zone->db, &zone->dbversion);
1667 }
1668
1669 cleanup:
1670 UNLOCK(&zone->rpzs->maint_lock);
1671
1672 return (result);
1673 }
1674
1675 static void
1676 dns_rpz_update_taskaction(isc_task_t *task, isc_event_t *event) {
1677 isc_result_t result;
1678 dns_rpz_zone_t *zone;
1679
1680 REQUIRE(event != NULL);
1681 REQUIRE(event->ev_arg != NULL);
1682
1683 UNUSED(task);
1684 zone = (dns_rpz_zone_t *) event->ev_arg;
1685 isc_event_free(&event);
1686 LOCK(&zone->rpzs->maint_lock);
1687 zone->updatepending = false;
1688 zone->updaterunning = true;
1689 dns_rpz_update_from_db(zone);
1690 result = isc_timer_reset(zone->updatetimer, isc_timertype_inactive,
1691 NULL, NULL, true);
1692 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1693 result = isc_time_now(&zone->lastupdated);
1694 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1695 UNLOCK(&zone->rpzs->maint_lock);
1696 }
1697
1698 static isc_result_t
1699 setup_update(dns_rpz_zone_t *rpz) {
1700 isc_result_t result;
1701 char domain[DNS_NAME_FORMATSIZE];
1702 unsigned int nodecount;
1703 uint32_t hashsize;
1704
1705 dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE);
1706 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1707 DNS_LOGMODULE_MASTER, ISC_LOG_INFO,
1708 "rpz: %s: reload start", domain);
1709
1710 nodecount = dns_db_nodecount(rpz->updb);
1711 hashsize = 1;
1712 while (nodecount != 0 &&
1713 hashsize <= (DNS_RPZ_HTSIZE_MAX + DNS_RPZ_HTSIZE_DIV))
1714 {
1715 hashsize++;
1716 nodecount >>=1;
1717 }
1718
1719 if (hashsize > DNS_RPZ_HTSIZE_DIV)
1720 hashsize -= DNS_RPZ_HTSIZE_DIV;
1721
1722 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1723 DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(1),
1724 "rpz: %s: using hashtable size %d",
1725 domain, hashsize);
1726
1727 result = isc_ht_init(&rpz->newnodes, rpz->rpzs->mctx, hashsize);
1728 if (result != ISC_R_SUCCESS) {
1729 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1730 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1731 "rpz: %s: failed to initialize hashtable - %s",
1732 domain, isc_result_totext(result));
1733 goto cleanup;
1734 }
1735
1736 result = dns_db_createiterator(rpz->updb, DNS_DB_NONSEC3, &rpz->updbit);
1737 if (result != ISC_R_SUCCESS) {
1738 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1739 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1740 "rpz: %s: failed to create DB iterator - %s",
1741 domain, isc_result_totext(result));
1742 goto cleanup;
1743 }
1744
1745 result = dns_dbiterator_first(rpz->updbit);
1746 if (result != ISC_R_SUCCESS) {
1747 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1748 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1749 "rpz: %s: failed to get db iterator - %s",
1750 domain, isc_result_totext(result));
1751 goto cleanup;
1752 }
1753
1754 result = dns_dbiterator_pause(rpz->updbit);
1755 if (result != ISC_R_SUCCESS) {
1756 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1757 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1758 "rpz: %s: failed to pause db iterator - %s",
1759 domain, isc_result_totext(result));
1760 goto cleanup;
1761 }
1762
1763
1764 cleanup:
1765 if (result != ISC_R_SUCCESS) {
1766 if (rpz->updbit != NULL)
1767 dns_dbiterator_destroy(&rpz->updbit);
1768 if (rpz->newnodes != NULL)
1769 isc_ht_destroy(&rpz->newnodes);
1770 dns_db_closeversion(rpz->updb, &rpz->updbversion, false);
1771 }
1772
1773 return (result);
1774 }
1775
1776 static void
1777 finish_update(dns_rpz_zone_t *rpz) {
1778 isc_result_t result;
1779 isc_ht_t *tmpht = NULL;
1780 isc_ht_iter_t *iter = NULL;
1781 dns_fixedname_t fname;
1782 char dname[DNS_NAME_FORMATSIZE];
1783 dns_name_t *name;
1784
1785 /*
1786 * Iterate over old ht with existing nodes deleted to delete
1787 * deleted nodes from RPZ
1788 */
1789 result = isc_ht_iter_create(rpz->nodes, &iter);
1790 if (result != ISC_R_SUCCESS) {
1791 char domain[DNS_NAME_FORMATSIZE];
1792
1793 dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE);
1794 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1795 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1796 "rpz: %s: failed to create HT iterator - %s",
1797 domain, isc_result_totext(result));
1798 goto cleanup;
1799 }
1800
1801 name = dns_fixedname_initname(&fname);
1802
1803 for (result = isc_ht_iter_first(iter);
1804 result == ISC_R_SUCCESS;
1805 result = isc_ht_iter_delcurrent_next(iter))
1806 {
1807 isc_region_t region;
1808 unsigned char *key = NULL;
1809 size_t keysize;
1810
1811 isc_ht_iter_currentkey(iter, &key, &keysize);
1812 region.base = key;
1813 region.length = (unsigned int)keysize;
1814 dns_name_fromregion(name, ®ion);
1815 dns_rpz_delete(rpz->rpzs, rpz->num, name);
1816 }
1817
1818 tmpht = rpz->nodes;
1819 rpz->nodes = rpz->newnodes;
1820 rpz->newnodes = tmpht;
1821
1822 LOCK(&rpz->rpzs->maint_lock);
1823 rpz->updaterunning = false;
1824 /*
1825 * If there's an update pending schedule it
1826 */
1827 if (rpz->updatepending == true) {
1828 if (rpz->min_update_interval > 0) {
1829 uint64_t defer = rpz->min_update_interval;
1830 isc_interval_t interval;
1831 dns_name_format(&rpz->origin, dname,
1832 DNS_NAME_FORMATSIZE);
1833 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1834 DNS_LOGMODULE_MASTER, ISC_LOG_INFO,
1835 "rpz: %s: new zone version came "
1836 "too soon, deferring update for "
1837 "%" PRIu64 " seconds", dname, defer);
1838 isc_interval_set(&interval, (unsigned int)defer, 0);
1839 isc_timer_reset(rpz->updatetimer, isc_timertype_once,
1840 NULL, &interval, true);
1841 } else {
1842 isc_event_t *event;
1843 INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link));
1844 ISC_EVENT_INIT(&rpz->updateevent,
1845 sizeof(rpz->updateevent), 0, NULL,
1846 DNS_EVENT_RPZUPDATED,
1847 dns_rpz_update_taskaction,
1848 rpz, rpz, NULL, NULL);
1849 event = &rpz->updateevent;
1850 isc_task_send(rpz->rpzs->updater, &event);
1851 }
1852 }
1853 UNLOCK(&rpz->rpzs->maint_lock);
1854
1855 cleanup:
1856 if (iter != NULL)
1857 isc_ht_iter_destroy(&iter);
1858 }
1859
1860 static void
1861 update_quantum(isc_task_t *task, isc_event_t *event) {
1862 isc_result_t result = ISC_R_SUCCESS;
1863 dns_dbnode_t *node = NULL;
1864 dns_rpz_zone_t *rpz;
1865 char domain[DNS_NAME_FORMATSIZE];
1866 dns_fixedname_t fixname;
1867 dns_name_t *name;
1868 int count = 0;
1869
1870 UNUSED(task);
1871
1872 REQUIRE(event != NULL);
1873 REQUIRE(event->ev_arg != NULL);
1874
1875 rpz = (dns_rpz_zone_t *) event->ev_arg;
1876 isc_event_free(&event);
1877
1878 REQUIRE(rpz->updbit != NULL);
1879 REQUIRE(rpz->newnodes != NULL);
1880
1881 name = dns_fixedname_initname(&fixname);
1882
1883 dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE);
1884
1885 while (result == ISC_R_SUCCESS && count++ < DNS_RPZ_QUANTUM) {
1886 char namebuf[DNS_NAME_FORMATSIZE];
1887 dns_rdatasetiter_t *rdsiter = NULL;
1888
1889 result = dns_dbiterator_current(rpz->updbit, &node, name);
1890 if (result != ISC_R_SUCCESS) {
1891 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1892 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1893 "rpz: %s: failed to get dbiterator - %s",
1894 domain, isc_result_totext(result));
1895 dns_db_detachnode(rpz->updb, &node);
1896 break;
1897 }
1898
1899 result = dns_db_allrdatasets(rpz->updb, node, rpz->updbversion,
1900 0, &rdsiter);
1901 if (result != ISC_R_SUCCESS) {
1902 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1903 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1904 "rpz: %s: failed to fetch "
1905 "rrdatasets - %s",
1906 domain, isc_result_totext(result));
1907 dns_db_detachnode(rpz->updb, &node);
1908 break;
1909 }
1910
1911 result = dns_rdatasetiter_first(rdsiter);
1912 dns_rdatasetiter_destroy(&rdsiter);
1913 if (result != ISC_R_SUCCESS) { /* empty non-terminal */
1914 if (result != ISC_R_NOMORE)
1915 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1916 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1917 "rpz: %s: error %s while creating "
1918 "rdatasetiter",
1919 domain, isc_result_totext(result));
1920 dns_db_detachnode(rpz->updb, &node);
1921 result = dns_dbiterator_next(rpz->updbit);
1922 continue;
1923 }
1924
1925 result = isc_ht_add(rpz->newnodes, name->ndata,
1926 name->length, rpz);
1927 if (result != ISC_R_SUCCESS) {
1928 dns_name_format(name, namebuf, sizeof(namebuf));
1929 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1930 DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1931 "rpz: %s, adding node %s to HT error %s",
1932 domain, namebuf,
1933 isc_result_totext(result));
1934 dns_db_detachnode(rpz->updb, &node);
1935 result = dns_dbiterator_next(rpz->updbit);
1936 continue;
1937 }
1938
1939 result = isc_ht_find(rpz->nodes, name->ndata,
1940 name->length, NULL);
1941 if (result == ISC_R_SUCCESS) {
1942 isc_ht_delete(rpz->nodes, name->ndata, name->length);
1943 } else { /* not found */
1944 result = dns_rpz_add(rpz->rpzs, rpz->num, name);
1945 if (result != ISC_R_SUCCESS) {
1946 dns_name_format(name, namebuf, sizeof(namebuf));
1947 isc_log_write(dns_lctx,
1948 DNS_LOGCATEGORY_GENERAL,
1949 DNS_LOGMODULE_MASTER,
1950 ISC_LOG_ERROR,
1951 "rpz: %s: adding node %s "
1952 "to RPZ error %s",
1953 domain, namebuf,
1954 isc_result_totext(result));
1955 } else {
1956 dns_name_format(name, namebuf, sizeof(namebuf));
1957 isc_log_write(dns_lctx,
1958 DNS_LOGCATEGORY_GENERAL,
1959 DNS_LOGMODULE_MASTER,
1960 ISC_LOG_DEBUG(3),
1961 "rpz: %s: adding node %s",
1962 domain, namebuf);
1963 }
1964 }
1965
1966 dns_db_detachnode(rpz->updb, &node);
1967 result = dns_dbiterator_next(rpz->updbit);
1968 }
1969
1970 if (result == ISC_R_SUCCESS) {
1971 isc_event_t *nevent;
1972 /*
1973 * Pause the iterator so that the DB is not locked
1974 */
1975 dns_dbiterator_pause(rpz->updbit);
1976 /*
1977 * We finished a quantum; trigger the next one and return
1978 */
1979 INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link));
1980 ISC_EVENT_INIT(&rpz->updateevent,
1981 sizeof(rpz->updateevent), 0, NULL,
1982 DNS_EVENT_RPZUPDATED,
1983 update_quantum,
1984 rpz, rpz, NULL, NULL);
1985 nevent = &rpz->updateevent;
1986 isc_task_send(rpz->rpzs->updater, &nevent);
1987 return;
1988 } else if (result == ISC_R_NOMORE) {
1989 /*
1990 * All done.
1991 */
1992 finish_update(rpz);
1993 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1994 DNS_LOGMODULE_MASTER, ISC_LOG_INFO,
1995 "rpz: %s: reload done", domain);
1996 }
1997
1998 /*
1999 * If we're here, we've either finished or something went wrong,
2000 * so clean up.
2001 */
2002 if (rpz->updbit != NULL)
2003 dns_dbiterator_destroy(&rpz->updbit);
2004 if (rpz->newnodes != NULL)
2005 isc_ht_destroy(&rpz->newnodes);
2006 dns_db_closeversion(rpz->updb, &rpz->updbversion, false);
2007 dns_db_detach(&rpz->updb);
2008 rpz_detach(&rpz);
2009 }
2010
2011 static void
2012 dns_rpz_update_from_db(dns_rpz_zone_t *rpz) {
2013 isc_result_t result;
2014 isc_event_t *event;
2015
2016 REQUIRE(rpz != NULL);
2017 REQUIRE(DNS_DB_VALID(rpz->db));
2018 REQUIRE(rpz->updb == NULL);
2019 REQUIRE(rpz->updbversion == NULL);
2020 REQUIRE(rpz->updbit == NULL);
2021 REQUIRE(rpz->newnodes == NULL);
2022
2023 isc_refcount_increment(&rpz->refs);
2024 dns_db_attach(rpz->db, &rpz->updb);
2025 rpz->updbversion = rpz->dbversion;
2026 rpz->dbversion = NULL;
2027
2028 result = setup_update(rpz);
2029 if (result != ISC_R_SUCCESS) {
2030 goto cleanup;
2031 }
2032
2033 event = &rpz->updateevent;
2034 INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link));
2035 ISC_EVENT_INIT(&rpz->updateevent, sizeof(rpz->updateevent),
2036 0, NULL, DNS_EVENT_RPZUPDATED,
2037 update_quantum, rpz, rpz, NULL, NULL);
2038 isc_task_send(rpz->rpzs->updater, &event);
2039 return;
2040
2041 cleanup:
2042 if (rpz->updbit != NULL)
2043 dns_dbiterator_destroy(&rpz->updbit);
2044 if (rpz->newnodes != NULL)
2045 isc_ht_destroy(&rpz->newnodes);
2046 dns_db_closeversion(rpz->updb, &rpz->updbversion, false);
2047 dns_db_detach(&rpz->updb);
2048 rpz_detach(&rpz);
2049 }
2050
2051 /*
2052 * Free the radix tree of a response policy database.
2053 */
2054 static void
2055 cidr_free(dns_rpz_zones_t *rpzs) {
2056 dns_rpz_cidr_node_t *cur, *child, *parent;
2057
2058 cur = rpzs->cidr;
2059 while (cur != NULL) {
2060 /* Depth first. */
2061 child = cur->child[0];
2062 if (child != NULL) {
2063 cur = child;
2064 continue;
2065 }
2066 child = cur->child[1];
2067 if (child != NULL) {
2068 cur = child;
2069 continue;
2070 }
2071
2072 /* Delete this leaf and go up. */
2073 parent = cur->parent;
2074 if (parent == NULL)
2075 rpzs->cidr = NULL;
2076 else
2077 parent->child[parent->child[1] == cur] = NULL;
2078 isc_mem_put(rpzs->mctx, cur, sizeof(*cur));
2079 cur = parent;
2080 }
2081 }
2082
2083 /*
2084 * Discard a response policy zone blob
2085 * before discarding the overall rpz structure.
2086 */
2087 static void
2088 rpz_detach(dns_rpz_zone_t **rpzp) {
2089 dns_rpz_zone_t *rpz;
2090 dns_rpz_zones_t *rpzs;
2091
2092 REQUIRE(rpzp != NULL && *rpzp != NULL);
2093
2094 rpz = *rpzp;
2095 *rpzp = NULL;
2096
2097 if (isc_refcount_decrement(&rpz->refs) != 1) {
2098 return;
2099 }
2100
2101 isc_refcount_destroy(&rpz->refs);
2102
2103 rpzs = rpz->rpzs;
2104 rpz->rpzs = NULL;
2105
2106 if (dns_name_dynamic(&rpz->origin)) {
2107 dns_name_free(&rpz->origin, rpzs->mctx);
2108 }
2109 if (dns_name_dynamic(&rpz->client_ip)) {
2110 dns_name_free(&rpz->client_ip, rpzs->mctx);
2111 }
2112 if (dns_name_dynamic(&rpz->ip)) {
2113 dns_name_free(&rpz->ip, rpzs->mctx);
2114 }
2115 if (dns_name_dynamic(&rpz->nsdname)) {
2116 dns_name_free(&rpz->nsdname, rpzs->mctx);
2117 }
2118 if (dns_name_dynamic(&rpz->nsip)) {
2119 dns_name_free(&rpz->nsip, rpzs->mctx);
2120 }
2121 if (dns_name_dynamic(&rpz->passthru)) {
2122 dns_name_free(&rpz->passthru, rpzs->mctx);
2123 }
2124 if (dns_name_dynamic(&rpz->drop)) {
2125 dns_name_free(&rpz->drop, rpzs->mctx);
2126 }
2127 if (dns_name_dynamic(&rpz->tcp_only)) {
2128 dns_name_free(&rpz->tcp_only, rpzs->mctx);
2129 }
2130 if (dns_name_dynamic(&rpz->cname)) {
2131 dns_name_free(&rpz->cname, rpzs->mctx);
2132 }
2133 if (rpz->dbversion != NULL) {
2134 dns_db_closeversion(rpz->db, &rpz->dbversion, false);
2135 }
2136 if (rpz->db != NULL) {
2137 dns_db_updatenotify_unregister(
2138 rpz->db, dns_rpz_dbupdate_callback, rpz);
2139 dns_db_detach(&rpz->db);
2140 }
2141 if (rpz->updaterunning) {
2142 isc_task_purgeevent(rpzs->updater, &rpz->updateevent);
2143 if (rpz->updbit != NULL) {
2144 dns_dbiterator_destroy(&rpz->updbit);
2145 }
2146 if (rpz->newnodes != NULL) {
2147 isc_ht_destroy(&rpz->newnodes);
2148 }
2149 dns_db_closeversion(rpz->updb, &rpz->updbversion, false);
2150 dns_db_detach(&rpz->updb);
2151 }
2152
2153 isc_timer_reset(rpz->updatetimer, isc_timertype_inactive,
2154 NULL, NULL, true);
2155 isc_timer_detach(&rpz->updatetimer);
2156
2157 isc_ht_destroy(&rpz->nodes);
2158
2159 isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
2160 rpz_detach_rpzs(&rpzs);
2161 }
2162
2163 void
2164 dns_rpz_attach_rpzs(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **rpzsp) {
2165 REQUIRE(rpzsp != NULL && *rpzsp == NULL);
2166 isc_refcount_increment(&rpzs->refs);
2167 *rpzsp = rpzs;
2168 }
2169
2170 /*
2171 * Forget a view's policy zones.
2172 */
2173 void
2174 dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) {
2175 REQUIRE(rpzsp != NULL && *rpzsp != NULL);
2176 dns_rpz_zones_t *rpzs = *rpzsp;
2177 *rpzsp = NULL;
2178
2179 if (isc_refcount_decrement(&rpzs->refs) == 1) {
2180
2181 isc_task_destroy(&rpzs->updater);
2182
2183 /*
2184 * Forget the last of view's rpz machinery after
2185 * the last reference.
2186 */
2187 for (dns_rpz_num_t rpz_num = 0;
2188 rpz_num < DNS_RPZ_MAX_ZONES;
2189 ++rpz_num)
2190 {
2191 dns_rpz_zone_t *rpz = rpzs->zones[rpz_num];
2192 rpzs->zones[rpz_num] = NULL;
2193 if (rpz != NULL) {
2194 rpz_detach(&rpz);
2195 }
2196 }
2197 rpz_detach_rpzs(&rpzs);
2198 }
2199 }
2200
2201 static void
2202 rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) {
2203 REQUIRE(rpzsp != NULL && *rpzsp != NULL);
2204 dns_rpz_zones_t *rpzs = *rpzsp;
2205 *rpzsp = NULL;
2206
2207 if (isc_refcount_decrement(&rpzs->irefs) == 1) {
2208 if (rpzs->rps_cstr_size != 0) {
2209 #ifdef USE_DNSRPS
2210 librpz->client_detach(&rpzs->rps_client);
2211 #endif
2212 isc_mem_put(rpzs->mctx, rpzs->rps_cstr,
2213 rpzs->rps_cstr_size);
2214 }
2215
2216 cidr_free(rpzs);
2217 if (rpzs->rbt != NULL) {
2218 dns_rbt_destroy(&rpzs->rbt);
2219 }
2220 isc_mutex_destroy(&rpzs->maint_lock);
2221 isc_rwlock_destroy(&rpzs->search_lock);
2222 isc_refcount_destroy(&rpzs->refs);
2223 isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs));
2224 }
2225 }
2226
2227 /*
2228 * Deprecated and removed.
2229 */
2230 isc_result_t
2231 dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp,
2232 dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num)
2233 {
2234 UNUSED(load_rpzsp);
2235 UNUSED(rpzs);
2236 UNUSED(rpz_num);
2237
2238 return (ISC_R_NOTIMPLEMENTED);
2239 }
2240
2241 /*
2242 * Deprecated and removed.
2243 */
2244 isc_result_t
2245 dns_rpz_ready(dns_rpz_zones_t *rpzs,
2246 dns_rpz_zones_t **load_rpzsp, dns_rpz_num_t rpz_num)
2247 {
2248 UNUSED(rpzs);
2249 UNUSED(load_rpzsp);
2250 UNUSED(rpz_num);
2251
2252 return (ISC_R_NOTIMPLEMENTED);
2253 }
2254
2255 /*
2256 * Add an IP address to the radix tree or a name to the summary database.
2257 */
2258 isc_result_t
2259 dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
2260 const dns_name_t *src_name)
2261 {
2262 dns_rpz_zone_t *rpz;
2263 dns_rpz_type_t rpz_type;
2264 isc_result_t result = ISC_R_FAILURE;
2265
2266 REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones);
2267 rpz = rpzs->zones[rpz_num];
2268 REQUIRE(rpz != NULL);
2269 RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2270
2271 rpz_type = type_from_name(rpzs, rpz, src_name);
2272
2273
2274 switch (rpz_type) {
2275 case DNS_RPZ_TYPE_QNAME:
2276 case DNS_RPZ_TYPE_NSDNAME:
2277 result = add_name(rpzs, rpz_num, rpz_type, src_name);
2278 break;
2279 case DNS_RPZ_TYPE_CLIENT_IP:
2280 case DNS_RPZ_TYPE_IP:
2281 case DNS_RPZ_TYPE_NSIP:
2282 result = add_cidr(rpzs, rpz_num, rpz_type, src_name);
2283 break;
2284 case DNS_RPZ_TYPE_BAD:
2285 break;
2286 }
2287 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2288
2289 return (result);
2290 }
2291
2292 /*
2293 * Remove an IP address from the radix tree.
2294 */
2295 static void
2296 del_cidr(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
2297 dns_rpz_type_t rpz_type, const dns_name_t *src_name)
2298 {
2299 isc_result_t result;
2300 dns_rpz_cidr_key_t tgt_ip;
2301 dns_rpz_prefix_t tgt_prefix;
2302 dns_rpz_addr_zbits_t tgt_set;
2303 dns_rpz_cidr_node_t *tgt, *parent, *child;
2304
2305 /*
2306 * Do not worry about invalid rpz IP address names. If we
2307 * are here, then something relevant was added and so was
2308 * valid. Invalid names here are usually internal RBTDB nodes.
2309 */
2310 result = name2ipkey(DNS_RPZ_DEBUG_QUIET, rpzs, rpz_num, rpz_type,
2311 src_name, &tgt_ip, &tgt_prefix, &tgt_set);
2312 if (result != ISC_R_SUCCESS)
2313 return;
2314
2315 result = search(rpzs, &tgt_ip, tgt_prefix, &tgt_set, false, &tgt);
2316 if (result != ISC_R_SUCCESS) {
2317 INSIST(result == ISC_R_NOTFOUND ||
2318 result == DNS_R_PARTIALMATCH);
2319 /*
2320 * Do not worry about missing summary RBT nodes that probably
2321 * correspond to RBTDB nodes that were implicit RBT nodes
2322 * that were later added for (often empty) wildcards
2323 * and then to the RBTDB deferred cleanup list.
2324 */
2325 return;
2326 }
2327
2328 /*
2329 * Mark the node and its parents to reflect the deleted IP address.
2330 * Do not count bits that are already clear for internal RBTDB nodes.
2331 */
2332 tgt_set.client_ip &= tgt->set.client_ip;
2333 tgt_set.ip &= tgt->set.ip;
2334 tgt_set.nsip &= tgt->set.nsip;
2335 tgt->set.client_ip &= ~tgt_set.client_ip;
2336 tgt->set.ip &= ~tgt_set.ip;
2337 tgt->set.nsip &= ~tgt_set.nsip;
2338 set_sum_pair(tgt);
2339
2340 adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix,
2341 false);
2342
2343 /*
2344 * We might need to delete 2 nodes.
2345 */
2346 do {
2347 /*
2348 * The node is now useless if it has no data of its own
2349 * and 0 or 1 children. We are finished if it is not useless.
2350 */
2351 if ((child = tgt->child[0]) != NULL) {
2352 if (tgt->child[1] != NULL)
2353 break;
2354 } else {
2355 child = tgt->child[1];
2356 }
2357 if (tgt->set.client_ip != 0 ||
2358 tgt->set.ip != 0 ||
2359 tgt->set.nsip != 0)
2360 break;
2361
2362 /*
2363 * Replace the pointer to this node in the parent with
2364 * the remaining child or NULL.
2365 */
2366 parent = tgt->parent;
2367 if (parent == NULL) {
2368 rpzs->cidr = child;
2369 } else {
2370 parent->child[parent->child[1] == tgt] = child;
2371 }
2372 /*
2373 * If the child exists fix up its parent pointer.
2374 */
2375 if (child != NULL)
2376 child->parent = parent;
2377 isc_mem_put(rpzs->mctx, tgt, sizeof(*tgt));
2378
2379 tgt = parent;
2380 } while (tgt != NULL);
2381 }
2382
2383 static void
2384 del_name(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
2385 dns_rpz_type_t rpz_type, const dns_name_t *src_name)
2386 {
2387 char namebuf[DNS_NAME_FORMATSIZE];
2388 dns_fixedname_t trig_namef;
2389 dns_name_t *trig_name;
2390 dns_rbtnode_t *nmnode;
2391 dns_rpz_nm_data_t *nm_data, del_data;
2392 isc_result_t result;
2393 bool exists;
2394
2395 /*
2396 * We need a summary database of names even with 1 policy zone,
2397 * because wildcard triggers are handled differently.
2398 */
2399
2400 trig_name = dns_fixedname_initname(&trig_namef);
2401 name2data(rpzs, rpz_num, rpz_type, src_name, trig_name, &del_data);
2402
2403 nmnode = NULL;
2404 result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, NULL, 0,
2405 NULL, NULL);
2406 if (result != ISC_R_SUCCESS) {
2407 /*
2408 * Do not worry about missing summary RBT nodes that probably
2409 * correspond to RBTDB nodes that were implicit RBT nodes
2410 * that were later added for (often empty) wildcards
2411 * and then to the RBTDB deferred cleanup list.
2412 */
2413 if (result == ISC_R_NOTFOUND ||
2414 result == DNS_R_PARTIALMATCH)
2415 return;
2416 dns_name_format(src_name, namebuf, sizeof(namebuf));
2417 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
2418 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
2419 "rpz del_name(%s) node search failed: %s",
2420 namebuf, isc_result_totext(result));
2421 return;
2422 }
2423
2424 nm_data = nmnode->data;
2425 INSIST(nm_data != NULL);
2426
2427 /*
2428 * Do not count bits that next existed for RBT nodes that would we
2429 * would not have found in a summary for a single RBTDB tree.
2430 */
2431 del_data.set.qname &= nm_data->set.qname;
2432 del_data.set.ns &= nm_data->set.ns;
2433 del_data.wild.qname &= nm_data->wild.qname;
2434 del_data.wild.ns &= nm_data->wild.ns;
2435
2436 exists = (del_data.set.qname != 0 || del_data.set.ns != 0 ||
2437 del_data.wild.qname != 0 || del_data.wild.ns != 0);
2438
2439 nm_data->set.qname &= ~del_data.set.qname;
2440 nm_data->set.ns &= ~del_data.set.ns;
2441 nm_data->wild.qname &= ~del_data.wild.qname;
2442 nm_data->wild.ns &= ~del_data.wild.ns;
2443
2444 if (nm_data->set.qname == 0 && nm_data->set.ns == 0 &&
2445 nm_data->wild.qname == 0 && nm_data->wild.ns == 0) {
2446 result = dns_rbt_deletenode(rpzs->rbt, nmnode, false);
2447 if (result != ISC_R_SUCCESS) {
2448 /*
2449 * bin/tests/system/rpz/tests.sh looks for
2450 * "rpz.*failed".
2451 */
2452 dns_name_format(src_name, namebuf, sizeof(namebuf));
2453 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
2454 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
2455 "rpz del_name(%s) node delete failed: %s",
2456 namebuf, isc_result_totext(result));
2457 }
2458 }
2459
2460 if (exists)
2461 adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, false);
2462 }
2463
2464 /*
2465 * Remove an IP address from the radix tree or a name from the summary database.
2466 */
2467 void
2468 dns_rpz_delete(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
2469 const dns_name_t *src_name)
2470 {
2471 dns_rpz_zone_t *rpz;
2472 dns_rpz_type_t rpz_type;
2473
2474 REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones);
2475 rpz = rpzs->zones[rpz_num];
2476 REQUIRE(rpz != NULL);
2477
2478 RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2479
2480 rpz_type = type_from_name(rpzs, rpz, src_name);
2481
2482 switch (rpz_type) {
2483 case DNS_RPZ_TYPE_QNAME:
2484 case DNS_RPZ_TYPE_NSDNAME:
2485 del_name(rpzs, rpz_num, rpz_type, src_name);
2486 break;
2487 case DNS_RPZ_TYPE_CLIENT_IP:
2488 case DNS_RPZ_TYPE_IP:
2489 case DNS_RPZ_TYPE_NSIP:
2490 del_cidr(rpzs, rpz_num, rpz_type, src_name);
2491 break;
2492 case DNS_RPZ_TYPE_BAD:
2493 break;
2494 }
2495
2496 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2497 }
2498
2499 /*
2500 * Search the summary radix tree to get a relative owner name in a
2501 * policy zone relevant to a triggering IP address.
2502 * rpz_type and zbits limit the search for IP address netaddr
2503 * return the policy zone's number or DNS_RPZ_INVALID_NUM
2504 * ip_name is the relative owner name found and
2505 * *prefixp is its prefix length.
2506 */
2507 dns_rpz_num_t
2508 dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
2509 dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr,
2510 dns_name_t *ip_name, dns_rpz_prefix_t *prefixp)
2511 {
2512 dns_rpz_cidr_key_t tgt_ip;
2513 dns_rpz_addr_zbits_t tgt_set;
2514 dns_rpz_cidr_node_t *found;
2515 isc_result_t result;
2516 dns_rpz_num_t rpz_num = 0;
2517 dns_rpz_have_t have;
2518 int i;
2519
2520 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2521 have = rpzs->have;
2522 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2523
2524 /*
2525 * Convert IP address to CIDR tree key.
2526 */
2527 if (netaddr->family == AF_INET) {
2528 tgt_ip.w[0] = 0;
2529 tgt_ip.w[1] = 0;
2530 tgt_ip.w[2] = ADDR_V4MAPPED;
2531 tgt_ip.w[3] = ntohl(netaddr->type.in.s_addr);
2532 switch (rpz_type) {
2533 case DNS_RPZ_TYPE_CLIENT_IP:
2534 zbits &= have.client_ipv4;
2535 break;
2536 case DNS_RPZ_TYPE_IP:
2537 zbits &= have.ipv4;
2538 break;
2539 case DNS_RPZ_TYPE_NSIP:
2540 zbits &= have.nsipv4;
2541 break;
2542 default:
2543 INSIST(0);
2544 break;
2545 }
2546 } else if (netaddr->family == AF_INET6) {
2547 dns_rpz_cidr_key_t src_ip6;
2548
2549 /*
2550 * Given the int aligned struct in_addr member of netaddr->type
2551 * one could cast netaddr->type.in6 to dns_rpz_cidr_key_t *,
2552 * but some people object.
2553 */
2554 memmove(src_ip6.w, &netaddr->type.in6, sizeof(src_ip6.w));
2555 for (i = 0; i < 4; i++) {
2556 tgt_ip.w[i] = ntohl(src_ip6.w[i]);
2557 }
2558 switch (rpz_type) {
2559 case DNS_RPZ_TYPE_CLIENT_IP:
2560 zbits &= have.client_ipv6;
2561 break;
2562 case DNS_RPZ_TYPE_IP:
2563 zbits &= have.ipv6;
2564 break;
2565 case DNS_RPZ_TYPE_NSIP:
2566 zbits &= have.nsipv6;
2567 break;
2568 default:
2569 INSIST(0);
2570 break;
2571 }
2572 } else {
2573 return (DNS_RPZ_INVALID_NUM);
2574 }
2575
2576 if (zbits == 0)
2577 return (DNS_RPZ_INVALID_NUM);
2578 make_addr_set(&tgt_set, zbits, rpz_type);
2579
2580 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2581 result = search(rpzs, &tgt_ip, 128, &tgt_set, false, &found);
2582 if (result == ISC_R_NOTFOUND) {
2583 /*
2584 * There are no eligible zones for this IP address.
2585 */
2586 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2587 return (DNS_RPZ_INVALID_NUM);
2588 }
2589
2590 /*
2591 * Construct the trigger name for the longest matching trigger
2592 * in the first eligible zone with a match.
2593 */
2594 *prefixp = found->prefix;
2595 switch (rpz_type) {
2596 case DNS_RPZ_TYPE_CLIENT_IP:
2597 rpz_num = zbit_to_num(found->set.client_ip & tgt_set.client_ip);
2598 break;
2599 case DNS_RPZ_TYPE_IP:
2600 rpz_num = zbit_to_num(found->set.ip & tgt_set.ip);
2601 break;
2602 case DNS_RPZ_TYPE_NSIP:
2603 rpz_num = zbit_to_num(found->set.nsip & tgt_set.nsip);
2604 break;
2605 default:
2606 INSIST(0);
2607 ISC_UNREACHABLE();
2608 }
2609 result = ip2name(&found->ip, found->prefix, dns_rootname, ip_name);
2610 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2611 if (result != ISC_R_SUCCESS) {
2612 /*
2613 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2614 */
2615 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
2616 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
2617 "rpz ip2name() failed: %s",
2618 isc_result_totext(result));
2619 return (DNS_RPZ_INVALID_NUM);
2620 }
2621 return (rpz_num);
2622 }
2623
2624 /*
2625 * Search the summary radix tree for policy zones with triggers matching
2626 * a name.
2627 */
2628 dns_rpz_zbits_t
2629 dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
2630 dns_rpz_zbits_t zbits, dns_name_t *trig_name)
2631 {
2632 char namebuf[DNS_NAME_FORMATSIZE];
2633 dns_rbtnode_t *nmnode;
2634 const dns_rpz_nm_data_t *nm_data;
2635 dns_rpz_zbits_t found_zbits;
2636 dns_rbtnodechain_t chain;
2637 isc_result_t result;
2638 int i;
2639
2640 if (zbits == 0) {
2641 return (0);
2642 }
2643
2644 found_zbits = 0;
2645
2646 dns_rbtnodechain_init(&chain, NULL);
2647
2648 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2649
2650 nmnode = NULL;
2651 result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode,
2652 &chain, DNS_RBTFIND_EMPTYDATA, NULL, NULL);
2653 switch (result) {
2654 case ISC_R_SUCCESS:
2655 nm_data = nmnode->data;
2656 if (nm_data != NULL) {
2657 if (rpz_type == DNS_RPZ_TYPE_QNAME) {
2658 found_zbits = nm_data->set.qname;
2659 } else {
2660 found_zbits = nm_data->set.ns;
2661 }
2662 }
2663 /* FALLTHROUGH */
2664
2665 case DNS_R_PARTIALMATCH:
2666 i = chain.level_matches;
2667 while (i >= 0 && (nmnode = chain.levels[i]) != NULL) {
2668 nm_data = nmnode->data;
2669 if (nm_data != NULL) {
2670 if (rpz_type == DNS_RPZ_TYPE_QNAME) {
2671 found_zbits |= nm_data->wild.qname;
2672 } else {
2673 found_zbits |= nm_data->wild.ns;
2674 }
2675 }
2676 i--;
2677 }
2678 break;
2679
2680 case ISC_R_NOTFOUND:
2681 break;
2682
2683 default:
2684 /*
2685 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2686 */
2687 dns_name_format(trig_name, namebuf, sizeof(namebuf));
2688 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
2689 DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
2690 "dns_rpz_find_name(%s) failed: %s",
2691 namebuf, isc_result_totext(result));
2692 break;
2693 }
2694
2695 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2696
2697 dns_rbtnodechain_invalidate(&chain);
2698
2699 return (zbits & found_zbits);
2700 }
2701
2702 /*
2703 * Translate CNAME rdata to a QNAME response policy action.
2704 */
2705 dns_rpz_policy_t
2706 dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
2707 dns_name_t *selfname)
2708 {
2709 dns_rdata_t rdata = DNS_RDATA_INIT;
2710 dns_rdata_cname_t cname;
2711 isc_result_t result;
2712
2713 result = dns_rdataset_first(rdataset);
2714 INSIST(result == ISC_R_SUCCESS);
2715 dns_rdataset_current(rdataset, &rdata);
2716 result = dns_rdata_tostruct(&rdata, &cname, NULL);
2717 INSIST(result == ISC_R_SUCCESS);
2718 dns_rdata_reset(&rdata);
2719
2720 /*
2721 * CNAME . means NXDOMAIN
2722 */
2723 if (dns_name_equal(&cname.cname, dns_rootname))
2724 return (DNS_RPZ_POLICY_NXDOMAIN);
2725
2726 if (dns_name_iswildcard(&cname.cname)) {
2727 /*
2728 * CNAME *. means NODATA
2729 */
2730 if (dns_name_countlabels(&cname.cname) == 2)
2731 return (DNS_RPZ_POLICY_NODATA);
2732
2733 /*
2734 * A qname of www.evil.com and a policy of
2735 * *.evil.com CNAME *.garden.net
2736 * gives a result of
2737 * evil.com CNAME evil.com.garden.net
2738 */
2739 if (dns_name_countlabels(&cname.cname) > 2)
2740 return (DNS_RPZ_POLICY_WILDCNAME);
2741 }
2742
2743 /*
2744 * CNAME rpz-tcp-only. means "send truncated UDP responses."
2745 */
2746 if (dns_name_equal(&cname.cname, &rpz->tcp_only))
2747 return (DNS_RPZ_POLICY_TCP_ONLY);
2748
2749 /*
2750 * CNAME rpz-drop. means "do not respond."
2751 */
2752 if (dns_name_equal(&cname.cname, &rpz->drop))
2753 return (DNS_RPZ_POLICY_DROP);
2754
2755 /*
2756 * CNAME rpz-passthru. means "do not rewrite."
2757 */
2758 if (dns_name_equal(&cname.cname, &rpz->passthru))
2759 return (DNS_RPZ_POLICY_PASSTHRU);
2760
2761 /*
2762 * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU
2763 */
2764 if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
2765 return (DNS_RPZ_POLICY_PASSTHRU);
2766
2767 /*
2768 * Any other rdata gives a response consisting of the rdata.
2769 */
2770 return (DNS_RPZ_POLICY_RECORD);
2771 }
2772