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