1 /* $NetBSD: rpz.c,v 1.9 2015/07/08 17:28:59 christos Exp $ */
4 * Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
23 #include <isc/buffer.h>
26 #include <isc/netaddr.h>
27 #include <isc/print.h>
28 #include <isc/rwlock.h>
29 #include <isc/stdlib.h>
30 #include <isc/string.h>
34 #include <dns/fixedname.h>
36 #include <dns/rdata.h>
37 #include <dns/rdataset.h>
38 #include <dns/rdatastruct.h>
39 #include <dns/result.h>
46 * Parallel radix trees for databases of response policy IP addresses
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.
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.
64 * The response policy zone canonical form of an IPv6 address is one of:
65 * prefix.W.W.W.W.W.W.W.W
67 * prefix.WORDS.zz.WORDS
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
75 * The canonical form of IPv4 addresses is:
78 * prefix is the prefix length of the address between 1 and 32
79 * B is a number between 0 and 255
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.
87 * Use a private definition of IPv6 addresses because s6_addr32 is not
88 * always defined and our IPv6 addresses are in non-standard byte order
90 typedef isc_uint32_t dns_rpz_cidr_word_t
;
91 #define DNS_RPZ_CIDR_WORD_BITS ((int)sizeof(dns_rpz_cidr_word_t)*8)
92 #define DNS_RPZ_CIDR_KEY_BITS ((int)sizeof(dns_rpz_cidr_key_t)*8)
93 #define DNS_RPZ_CIDR_WORDS (128/DNS_RPZ_CIDR_WORD_BITS)
95 dns_rpz_cidr_word_t w
[DNS_RPZ_CIDR_WORDS
];
98 #define ADDR_V4MAPPED 0xffff
99 #define KEY_IS_IPV4(prefix,ip) ((prefix) >= 96 && (ip)->w[0] == 0 && \
100 (ip)->w[1] == 0 && (ip)->w[2] == ADDR_V4MAPPED)
102 #define DNS_RPZ_WORD_MASK(b) ((b) == 0 ? (dns_rpz_cidr_word_t)(-1) \
103 : ((dns_rpz_cidr_word_t)(-1) \
104 << (DNS_RPZ_CIDR_WORD_BITS - (b))))
107 * Get bit #n from the array of words of an IP address.
109 #define DNS_RPZ_IP_BIT(ip, n) (1 & ((ip)->w[(n)/DNS_RPZ_CIDR_WORD_BITS] >> \
110 (DNS_RPZ_CIDR_WORD_BITS \
111 - 1 - ((n) % DNS_RPZ_CIDR_WORD_BITS))))
114 * A triplet of arrays of bits flagging the existence of
115 * client-IP, IP, and NSIP policy triggers.
117 typedef struct dns_rpz_addr_zbits dns_rpz_addr_zbits_t
;
118 struct dns_rpz_addr_zbits
{
119 dns_rpz_zbits_t client_ip
;
121 dns_rpz_zbits_t nsip
;
125 * A CIDR or radix tree node.
127 struct dns_rpz_cidr_node
{
128 dns_rpz_cidr_node_t
*parent
;
129 dns_rpz_cidr_node_t
*child
[2];
130 dns_rpz_cidr_key_t ip
;
131 dns_rpz_prefix_t prefix
;
132 dns_rpz_addr_zbits_t set
;
133 dns_rpz_addr_zbits_t sum
;
137 * A pair of arrays of bits flagging the existence of
138 * QNAME and NSDNAME policy triggers.
140 typedef struct dns_rpz_nm_zbits dns_rpz_nm_zbits_t
;
141 struct dns_rpz_nm_zbits
{
142 dns_rpz_zbits_t qname
;
147 * The data in a RBT node has two pairs of bits for policy zones.
148 * One pair is for the corresponding name of the node such as example.com
149 * and the other pair is for a wildcard child such as *.example.com.
151 typedef struct dns_rpz_nm_data dns_rpz_nm_data_t
;
152 struct dns_rpz_nm_data
{
153 dns_rpz_nm_zbits_t set
;
154 dns_rpz_nm_zbits_t wild
;
159 * Catch a name while debugging.
162 catch_name(const dns_name_t
*src_name
, const char *tgt
, const char *str
) {
163 dns_fixedname_t tgt_namef
;
164 dns_name_t
*tgt_name
;
166 dns_fixedname_init(&tgt_namef
);
167 tgt_name
= dns_fixedname_name(&tgt_namef
);
168 dns_name_fromstring(tgt_name
, tgt
, DNS_NAME_DOWNCASE
, NULL
);
169 if (dns_name_equal(src_name
, tgt_name
)) {
170 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
171 DNS_LOGMODULE_RBTDB
, DNS_RPZ_ERROR_LEVEL
,
172 "rpz hit failed: %s %s", str
, tgt
);
178 dns_rpz_type2str(dns_rpz_type_t type
) {
180 case DNS_RPZ_TYPE_CLIENT_IP
:
181 return ("CLIENT-IP");
182 case DNS_RPZ_TYPE_QNAME
:
184 case DNS_RPZ_TYPE_IP
:
186 case DNS_RPZ_TYPE_NSIP
:
188 case DNS_RPZ_TYPE_NSDNAME
:
190 case DNS_RPZ_TYPE_BAD
:
193 FATAL_ERROR(__FILE__
, __LINE__
, "impossible rpz type %d", type
);
194 return ("impossible");
198 dns_rpz_str2policy(const char *str
) {
201 dns_rpz_policy_t policy
;
203 {"given", DNS_RPZ_POLICY_GIVEN
},
204 {"disabled", DNS_RPZ_POLICY_DISABLED
},
205 {"passthru", DNS_RPZ_POLICY_PASSTHRU
},
206 {"drop", DNS_RPZ_POLICY_DROP
},
207 {"tcp-only", DNS_RPZ_POLICY_TCP_ONLY
},
208 {"nxdomain", DNS_RPZ_POLICY_NXDOMAIN
},
209 {"nodata", DNS_RPZ_POLICY_NODATA
},
210 {"cname", DNS_RPZ_POLICY_CNAME
},
211 {"no-op", DNS_RPZ_POLICY_PASSTHRU
}, /* old passthru */
216 return (DNS_RPZ_POLICY_ERROR
);
217 for (n
= 0; n
< sizeof(tbl
)/sizeof(tbl
[0]); ++n
) {
218 if (!strcasecmp(tbl
[n
].str
, str
))
219 return (tbl
[n
].policy
);
221 return (DNS_RPZ_POLICY_ERROR
);
225 dns_rpz_policy2str(dns_rpz_policy_t policy
) {
229 case DNS_RPZ_POLICY_PASSTHRU
:
232 case DNS_RPZ_POLICY_DROP
:
235 case DNS_RPZ_POLICY_TCP_ONLY
:
238 case DNS_RPZ_POLICY_NXDOMAIN
:
241 case DNS_RPZ_POLICY_NODATA
:
244 case DNS_RPZ_POLICY_RECORD
:
247 case DNS_RPZ_POLICY_CNAME
:
248 case DNS_RPZ_POLICY_WILDCNAME
:
251 case DNS_RPZ_POLICY_MISS
:
263 * Return the bit number of the highest set bit in 'zbit'.
264 * (for example, 0x01 returns 0, 0xFF returns 7, etc.)
267 zbit_to_num(dns_rpz_zbits_t zbit
) {
268 dns_rpz_num_t rpz_num
;
272 #if DNS_RPZ_MAX_ZONES > 32
273 if ((zbit
& 0xffffffff00000000L
) != 0) {
278 if ((zbit
& 0xffff0000) != 0) {
282 if ((zbit
& 0xff00) != 0) {
286 if ((zbit
& 0xf0) != 0) {
290 if ((zbit
& 0xc) != 0) {
300 * Make a set of bit masks given one or more bits and their type.
303 make_addr_set(dns_rpz_addr_zbits_t
*tgt_set
, dns_rpz_zbits_t zbits
,
307 case DNS_RPZ_TYPE_CLIENT_IP
:
308 tgt_set
->client_ip
= zbits
;
312 case DNS_RPZ_TYPE_IP
:
313 tgt_set
->client_ip
= 0;
317 case DNS_RPZ_TYPE_NSIP
:
318 tgt_set
->client_ip
= 0;
320 tgt_set
->nsip
= zbits
;
329 make_nm_set(dns_rpz_nm_zbits_t
*tgt_set
,
330 dns_rpz_num_t rpz_num
, dns_rpz_type_t type
)
333 case DNS_RPZ_TYPE_QNAME
:
334 tgt_set
->qname
= DNS_RPZ_ZBIT(rpz_num
);
337 case DNS_RPZ_TYPE_NSDNAME
:
339 tgt_set
->ns
= DNS_RPZ_ZBIT(rpz_num
);
348 * Mark a node and all of its parents as having client-IP, IP, or NSIP data
351 set_sum_pair(dns_rpz_cidr_node_t
*cnode
) {
352 dns_rpz_cidr_node_t
*child
;
353 dns_rpz_addr_zbits_t sum
;
358 child
= cnode
->child
[0];
360 sum
.client_ip
|= child
->sum
.client_ip
;
361 sum
.ip
|= child
->sum
.ip
;
362 sum
.nsip
|= child
->sum
.nsip
;
365 child
= cnode
->child
[1];
367 sum
.client_ip
|= child
->sum
.client_ip
;
368 sum
.ip
|= child
->sum
.ip
;
369 sum
.nsip
|= child
->sum
.nsip
;
372 if (cnode
->sum
.client_ip
== sum
.client_ip
&&
373 cnode
->sum
.ip
== sum
.ip
&&
374 cnode
->sum
.nsip
== sum
.nsip
)
377 cnode
= cnode
->parent
;
378 } while (cnode
!= NULL
);
381 /* Caller must hold rpzs->maint_lock */
383 fix_qname_skip_recurse(dns_rpz_zones_t
*rpzs
) {
384 dns_rpz_zbits_t mask
;
387 * qname_wait_recurse and qname_skip_recurse are used to
388 * implement the "qname-wait-recurse" config option.
390 * By default, "qname-wait-recurse" is yes, so no
391 * processing happens without recursion. In this case,
392 * qname_wait_recurse is true, and qname_skip_recurse
393 * (a bit field indicating which policy zones can be
394 * processed without recursion) is set to all 0's by
395 * fix_qname_skip_recurse().
397 * When "qname-wait-recurse" is no, qname_skip_recurse may be
398 * set to a non-zero value by fix_qname_skip_recurse(). The mask
399 * has to have bits set for the policy zones for which
400 * processing may continue without recursion, and bits cleared
405 * The "qname-wait-recurse no" option overrides that default
406 * behavior when recursion cannot change a non-error
407 * response. The option does not affect QNAME or client-IP
408 * triggers in policy zones listed after other zones
409 * containing IP, NSIP and NSDNAME triggers, because those may
410 * depend on the A, AAAA, and NS records that would be found
411 * during recursive resolution.
413 * Let's consider the following:
415 * zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 |
416 * rpzs->have.nsdname |
417 * rpzs->have.nsipv4 | rpzs->have.nsipv6);
419 * zbits_req now contains bits set for zones which require
422 * But going by the description in the ARM, if the first policy
423 * zone requires recursion, then all zones after that (higher
424 * order bits) have to wait as well. If the Nth zone requires
425 * recursion, then (N+1)th zone onwards all need to wait.
427 * So mapping this, examples:
429 * zbits_req = 0b000 mask = 0xffffffff (no zones have to wait for
431 * zbits_req = 0b001 mask = 0x00000000 (all zones have to wait)
432 * zbits_req = 0b010 mask = 0x00000001 (the first zone doesn't have to
433 * wait, second zone onwards need
435 * zbits_req = 0b011 mask = 0x00000000 (all zones have to wait)
436 * zbits_req = 0b100 mask = 0x00000011 (the 1st and 2nd zones don't
437 * have to wait, third zone
438 * onwards need to wait)
440 * More generally, we have to count the number of trailing 0
441 * bits in zbits_req and only these can be processed without
442 * recursion. All the rest need to wait.
444 * (2) The ARM says that "qname-wait-recurse no" option
445 * overrides the default behavior when recursion cannot change a
446 * non-error response. So, in the order of listing of policy
447 * zones, within the first policy zone where recursion may be
448 * required, we should first allow CLIENT-IP and QNAME policy
449 * records to be attempted without recursion.
453 * Get a mask covering all policy zones that are not subordinate to
454 * other policy zones containing triggers that require that the
455 * qname be resolved before they can be checked.
457 rpzs
->have
.client_ip
= rpzs
->have
.client_ipv4
| rpzs
->have
.client_ipv6
;
458 rpzs
->have
.ip
= rpzs
->have
.ipv4
| rpzs
->have
.ipv6
;
459 rpzs
->have
.nsip
= rpzs
->have
.nsipv4
| rpzs
->have
.nsipv6
;
461 if (rpzs
->p
.qname_wait_recurse
) {
464 dns_rpz_zbits_t zbits_req
;
465 dns_rpz_zbits_t zbits_notreq
;
466 dns_rpz_zbits_t mask2
;
467 dns_rpz_zbits_t req_mask
;
470 * Get the masks of zones with policies that
471 * do/don't require recursion
474 zbits_req
= (rpzs
->have
.ipv4
| rpzs
->have
.ipv6
|
476 rpzs
->have
.nsipv4
| rpzs
->have
.nsipv6
);
477 zbits_notreq
= (rpzs
->have
.client_ip
| rpzs
->have
.qname
);
479 if (zbits_req
== 0) {
480 mask
= DNS_RPZ_ALL_ZBITS
;
485 * req_mask is a mask covering used bits in
486 * zbits_req. (For instance, 0b1 => 0b1, 0b101 => 0b111,
487 * 0b11010101 => 0b11111111).
489 req_mask
= zbits_req
;
490 req_mask
|= req_mask
>> 1;
491 req_mask
|= req_mask
>> 2;
492 req_mask
|= req_mask
>> 4;
493 req_mask
|= req_mask
>> 8;
494 req_mask
|= req_mask
>> 16;
495 #if DNS_RPZ_MAX_ZONES > 32
496 req_mask
|= req_mask
>> 32;
500 * There's no point in skipping recursion for a later
501 * zone if it is required in a previous zone.
503 if ((zbits_notreq
& req_mask
) == 0) {
509 * This bit arithmetic creates a mask of zones in which
510 * it is okay to skip recursion. After the first zone
511 * that has to wait for recursion, all the others have
512 * to wait as well, so we want to create a mask in which
513 * all the trailing zeroes in zbits_req are are 1, and
514 * more significant bits are 0. (For instance,
515 * 0x0700 => 0x00ff, 0x0007 => 0x0000)
517 mask
= ~(zbits_req
| -zbits_req
);
520 * As mentioned in (2) above, the zone corresponding to
521 * the least significant zero could have its CLIENT-IP
522 * and QNAME policies checked before recursion, if it
523 * has any of those policies. So if it does, we
524 * can set its 0 to 1.
526 * Locate the least significant 0 bit in the mask (for
527 * instance, 0xff => 0x100)...
529 mask2
= (mask
<< 1) & ~mask
;
532 * Also set the bit for zone 0, because if it's in
533 * zbits_notreq then it's definitely okay to attempt to
534 * skip recursion for zone 0...
538 /* Clear any bits *not* in zbits_notreq... */
539 mask2
&= zbits_notreq
;
541 /* And merge the result into the skip-recursion mask */
546 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
, DNS_LOGMODULE_RBTDB
,
548 "computed RPZ qname_skip_recurse mask=0x%llx",
549 (isc_uint64_t
) mask
);
550 rpzs
->have
.qname_skip_recurse
= mask
;
554 adj_trigger_cnt(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
,
555 dns_rpz_type_t rpz_type
,
556 const dns_rpz_cidr_key_t
*tgt_ip
, dns_rpz_prefix_t tgt_prefix
,
559 dns_rpz_trigger_counter_t
*cnt
;
560 dns_rpz_zbits_t
*have
;
563 case DNS_RPZ_TYPE_CLIENT_IP
:
564 REQUIRE(tgt_ip
!= NULL
);
565 if (KEY_IS_IPV4(tgt_prefix
, tgt_ip
)) {
566 cnt
= &rpzs
->triggers
[rpz_num
].client_ipv4
;
567 have
= &rpzs
->have
.client_ipv4
;
569 cnt
= &rpzs
->triggers
[rpz_num
].client_ipv6
;
570 have
= &rpzs
->have
.client_ipv6
;
573 case DNS_RPZ_TYPE_QNAME
:
574 cnt
= &rpzs
->triggers
[rpz_num
].qname
;
575 have
= &rpzs
->have
.qname
;
577 case DNS_RPZ_TYPE_IP
:
578 REQUIRE(tgt_ip
!= NULL
);
579 if (KEY_IS_IPV4(tgt_prefix
, tgt_ip
)) {
580 cnt
= &rpzs
->triggers
[rpz_num
].ipv4
;
581 have
= &rpzs
->have
.ipv4
;
583 cnt
= &rpzs
->triggers
[rpz_num
].ipv6
;
584 have
= &rpzs
->have
.ipv6
;
587 case DNS_RPZ_TYPE_NSDNAME
:
588 cnt
= &rpzs
->triggers
[rpz_num
].nsdname
;
589 have
= &rpzs
->have
.nsdname
;
591 case DNS_RPZ_TYPE_NSIP
:
592 REQUIRE(tgt_ip
!= NULL
);
593 if (KEY_IS_IPV4(tgt_prefix
, tgt_ip
)) {
594 cnt
= &rpzs
->triggers
[rpz_num
].nsipv4
;
595 have
= &rpzs
->have
.nsipv4
;
597 cnt
= &rpzs
->triggers
[rpz_num
].nsipv6
;
598 have
= &rpzs
->have
.nsipv6
;
607 *have
|= DNS_RPZ_ZBIT(rpz_num
);
608 fix_qname_skip_recurse(rpzs
);
613 *have
&= ~DNS_RPZ_ZBIT(rpz_num
);
614 fix_qname_skip_recurse(rpzs
);
619 static dns_rpz_cidr_node_t
*
620 new_node(dns_rpz_zones_t
*rpzs
,
621 const dns_rpz_cidr_key_t
*ip
, dns_rpz_prefix_t prefix
,
622 const dns_rpz_cidr_node_t
*child
)
624 dns_rpz_cidr_node_t
*new;
627 new = isc_mem_get(rpzs
->mctx
, sizeof(*new));
630 memset(new, 0, sizeof(*new));
633 new->sum
= child
->sum
;
635 new->prefix
= prefix
;
636 words
= prefix
/ DNS_RPZ_CIDR_WORD_BITS
;
637 wlen
= prefix
% DNS_RPZ_CIDR_WORD_BITS
;
640 new->ip
.w
[i
] = ip
->w
[i
];
644 new->ip
.w
[i
] = ip
->w
[i
] & DNS_RPZ_WORD_MASK(wlen
);
647 while (i
< DNS_RPZ_CIDR_WORDS
)
654 badname(int level
, dns_name_t
*name
, const char *str1
, const char *str2
) {
655 char namebuf
[DNS_NAME_FORMATSIZE
];
658 * bin/tests/system/rpz/tests.sh looks for "invalid rpz".
660 if (level
< DNS_RPZ_DEBUG_QUIET
&&
661 isc_log_wouldlog(dns_lctx
, level
)) {
662 dns_name_format(name
, namebuf
, sizeof(namebuf
));
663 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
664 DNS_LOGMODULE_RBTDB
, level
,
665 "invalid rpz IP address \"%s\"%s%s",
666 namebuf
, str1
, str2
);
671 * Convert an IP address from radix tree binary (host byte order) to
672 * to its canonical response policy domain name without the origin of the
676 ip2name(const dns_rpz_cidr_key_t
*tgt_ip
, dns_rpz_prefix_t tgt_prefix
,
677 dns_name_t
*base_name
, dns_name_t
*ip_name
)
679 #ifndef INET6_ADDRSTRLEN
680 #define INET6_ADDRSTRLEN 46
682 int w
[DNS_RPZ_CIDR_WORDS
*2];
683 char str
[1+8+1+INET6_ADDRSTRLEN
+1];
689 if (KEY_IS_IPV4(tgt_prefix
, tgt_ip
)) {
690 len
= snprintf(str
, sizeof(str
), "%d.%d.%d.%d.%d",
693 (tgt_ip
->w
[3]>>8) & 0xff,
694 (tgt_ip
->w
[3]>>16) & 0xff,
695 (tgt_ip
->w
[3]>>24) & 0xff);
696 if (len
< 0 || len
> (int)sizeof(str
))
697 return (ISC_R_FAILURE
);
699 for (i
= 0; i
< DNS_RPZ_CIDR_WORDS
; i
++) {
700 w
[i
*2+1] = ((tgt_ip
->w
[DNS_RPZ_CIDR_WORDS
-1-i
] >> 16)
702 w
[i
*2] = tgt_ip
->w
[DNS_RPZ_CIDR_WORDS
-1-i
] & 0xffff;
705 len
= snprintf(str
, sizeof(str
), "%d", tgt_prefix
);
707 return (ISC_R_FAILURE
);
709 while (i
< DNS_RPZ_CIDR_WORDS
* 2) {
710 if (w
[i
] != 0 || zeros
||
711 i
>= DNS_RPZ_CIDR_WORDS
* 2 - 1 ||
713 INSIST((size_t)len
<= sizeof(str
));
714 n
= snprintf(&str
[len
], sizeof(str
) - len
,
717 return (ISC_R_FAILURE
);
721 INSIST((size_t)len
<= sizeof(str
));
722 n
= snprintf(&str
[len
], sizeof(str
) - len
,
725 return (ISC_R_FAILURE
);
728 while (i
< DNS_RPZ_CIDR_WORDS
* 2 && w
[i
] == 0)
731 if (len
>= (int)sizeof(str
))
732 return (ISC_R_FAILURE
);
736 isc_buffer_init(&buffer
, str
, sizeof(str
));
737 isc_buffer_add(&buffer
, len
);
738 result
= dns_name_fromtext(ip_name
, &buffer
, base_name
, 0, NULL
);
743 * Determine the type a of a name in a response policy zone.
745 static dns_rpz_type_t
746 type_from_name(dns_rpz_zone_t
*rpz
, dns_name_t
*name
) {
748 if (dns_name_issubdomain(name
, &rpz
->ip
))
749 return (DNS_RPZ_TYPE_IP
);
751 if (dns_name_issubdomain(name
, &rpz
->client_ip
))
752 return (DNS_RPZ_TYPE_CLIENT_IP
);
754 #ifdef ENABLE_RPZ_NSIP
755 if (dns_name_issubdomain(name
, &rpz
->nsip
))
756 return (DNS_RPZ_TYPE_NSIP
);
759 #ifdef ENABLE_RPZ_NSDNAME
760 if (dns_name_issubdomain(name
, &rpz
->nsdname
))
761 return (DNS_RPZ_TYPE_NSDNAME
);
764 return (DNS_RPZ_TYPE_QNAME
);
768 * Convert an IP address from canonical response policy domain name form
769 * to radix tree binary (host byte order) for adding or deleting IP or NSIP
773 name2ipkey(int log_level
,
774 const dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
,
775 dns_rpz_type_t rpz_type
, dns_name_t
*src_name
,
776 dns_rpz_cidr_key_t
*tgt_ip
, dns_rpz_prefix_t
*tgt_prefix
,
777 dns_rpz_addr_zbits_t
*new_set
)
780 char ip_str
[DNS_NAME_FORMATSIZE
];
781 dns_offsets_t ip_name_offsets
;
782 dns_fixedname_t ip_name2f
;
783 dns_name_t ip_name
, *ip_name2
;
784 const char *prefix_str
, *cp
, *end
;
787 dns_rpz_prefix_t prefix
;
788 unsigned long prefix_num
, l
;
792 REQUIRE(rpzs
!= NULL
&& rpz_num
< rpzs
->p
.num_zones
);
793 rpz
= rpzs
->zones
[rpz_num
];
794 REQUIRE(rpz
!= NULL
);
796 make_addr_set(new_set
, DNS_RPZ_ZBIT(rpz_num
), rpz_type
);
798 ip_labels
= dns_name_countlabels(src_name
);
799 if (rpz_type
== DNS_RPZ_TYPE_QNAME
)
800 ip_labels
-= dns_name_countlabels(&rpz
->origin
);
802 ip_labels
-= dns_name_countlabels(&rpz
->nsdname
);
804 badname(log_level
, src_name
, "; too short", "");
805 return (ISC_R_FAILURE
);
807 dns_name_init(&ip_name
, ip_name_offsets
);
808 dns_name_getlabelsequence(src_name
, 0, ip_labels
, &ip_name
);
811 * Get text for the IP address
813 dns_name_format(&ip_name
, ip_str
, sizeof(ip_str
));
814 end
= &ip_str
[strlen(ip_str
)+1];
817 prefix_num
= strtoul(prefix_str
, &cp2
, 10);
819 badname(log_level
, src_name
,
820 "; invalid leading prefix length", "");
821 return (ISC_R_FAILURE
);
824 if (prefix_num
< 1U || prefix_num
> 128U) {
825 badname(log_level
, src_name
,
826 "; invalid prefix length of ", prefix_str
);
827 return (ISC_R_FAILURE
);
831 if (--ip_labels
== 4 && !strchr(cp
, 'z')) {
833 * Convert an IPv4 address
834 * from the form "prefix.z.y.x.w"
836 if (prefix_num
> 32U) {
837 badname(log_level
, src_name
,
838 "; invalid IPv4 prefix length of ", prefix_str
);
839 return (ISC_R_FAILURE
);
842 *tgt_prefix
= (dns_rpz_prefix_t
)prefix_num
;
845 tgt_ip
->w
[2] = ADDR_V4MAPPED
;
847 for (i
= 0; i
< 32; i
+= 8) {
848 l
= strtoul(cp
, &cp2
, 10);
849 if (l
> 255U || (*cp2
!= '.' && *cp2
!= '\0')) {
852 badname(log_level
, src_name
,
853 "; invalid IPv4 octet ", cp
);
854 return (ISC_R_FAILURE
);
856 tgt_ip
->w
[3] |= l
<< i
;
861 * Convert a text IPv6 address.
863 *tgt_prefix
= (dns_rpz_prefix_t
)prefix_num
;
865 ip_labels
> 0 && i
< DNS_RPZ_CIDR_WORDS
* 2;
867 if (cp
[0] == 'z' && cp
[1] == 'z' &&
868 (cp
[2] == '.' || cp
[2] == '\0') &&
872 tgt_ip
->w
[3-i
/2] = 0;
874 } while (ip_labels
+ i
<= 8);
877 l
= strtoul(cp
, &cp2
, 16);
879 (*cp2
!= '.' && *cp2
!= '\0')) {
882 badname(log_level
, src_name
,
883 "; invalid IPv6 word ", cp
);
884 return (ISC_R_FAILURE
);
887 tgt_ip
->w
[3-i
/2] = l
;
889 tgt_ip
->w
[3-i
/2] |= l
<< 16;
896 badname(log_level
, src_name
, "", "");
897 return (ISC_R_FAILURE
);
901 * Check for 1s after the prefix length.
903 prefix
= (dns_rpz_prefix_t
)prefix_num
;
904 while (prefix
< DNS_RPZ_CIDR_KEY_BITS
) {
905 dns_rpz_cidr_word_t aword
;
907 i
= prefix
% DNS_RPZ_CIDR_WORD_BITS
;
908 aword
= tgt_ip
->w
[prefix
/ DNS_RPZ_CIDR_WORD_BITS
];
909 if ((aword
& ~DNS_RPZ_WORD_MASK(i
)) != 0) {
910 badname(log_level
, src_name
,
911 "; too small prefix length of ", prefix_str
);
912 return (ISC_R_FAILURE
);
915 prefix
+= DNS_RPZ_CIDR_WORD_BITS
;
919 * XXXMUKS: Should the following check be enabled in a
920 * production build? It can be expensive for large IP zones
925 * Convert the address back to a canonical domain name
926 * to ensure that the original name is in canonical form.
928 dns_fixedname_init(&ip_name2f
);
929 ip_name2
= dns_fixedname_name(&ip_name2f
);
930 result
= ip2name(tgt_ip
, (dns_rpz_prefix_t
)prefix_num
, NULL
, ip_name2
);
931 if (result
!= ISC_R_SUCCESS
|| !dns_name_equal(&ip_name
, ip_name2
)) {
932 badname(log_level
, src_name
, "; not canonical", "");
933 return (ISC_R_FAILURE
);
936 return (ISC_R_SUCCESS
);
940 * Get trigger name and data bits for adding or deleting summary NSDNAME
944 name2data(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
,
945 dns_rpz_type_t rpz_type
, const dns_name_t
*src_name
,
946 dns_name_t
*trig_name
, dns_rpz_nm_data_t
*new_data
)
949 dns_offsets_t tmp_name_offsets
;
951 unsigned int prefix_len
, n
;
953 REQUIRE(rpzs
!= NULL
&& rpz_num
< rpzs
->p
.num_zones
);
954 rpz
= rpzs
->zones
[rpz_num
];
955 REQUIRE(rpz
!= NULL
);
958 * Handle wildcards by putting only the parent into the
959 * summary RBT. The summary database only causes a check of the
960 * real policy zone where wildcards will be handled.
962 if (dns_name_iswildcard(src_name
)) {
964 memset(&new_data
->set
, 0, sizeof(new_data
->set
));
965 make_nm_set(&new_data
->wild
, rpz_num
, rpz_type
);
968 make_nm_set(&new_data
->set
, rpz_num
, rpz_type
);
969 memset(&new_data
->wild
, 0, sizeof(new_data
->wild
));
972 dns_name_init(&tmp_name
, tmp_name_offsets
);
973 n
= dns_name_countlabels(src_name
);
975 if (rpz_type
== DNS_RPZ_TYPE_QNAME
)
976 n
-= dns_name_countlabels(&rpz
->origin
);
978 n
-= dns_name_countlabels(&rpz
->nsdname
);
979 dns_name_getlabelsequence(src_name
, prefix_len
, n
, &tmp_name
);
980 (void)dns_name_concatenate(&tmp_name
, dns_rootname
, trig_name
, NULL
);
984 * Find the first differing bit in a key (IP address) word.
987 ffs_keybit(dns_rpz_cidr_word_t w
) {
990 bit
= DNS_RPZ_CIDR_WORD_BITS
-1;
991 if ((w
& 0xffff0000) != 0) {
995 if ((w
& 0xff00) != 0) {
999 if ((w
& 0xf0) != 0) {
1003 if ((w
& 0xc) != 0) {
1013 * Find the first differing bit in two keys (IP addresses).
1016 diff_keys(const dns_rpz_cidr_key_t
*key1
, dns_rpz_prefix_t prefix1
,
1017 const dns_rpz_cidr_key_t
*key2
, dns_rpz_prefix_t prefix2
)
1019 dns_rpz_cidr_word_t delta
;
1020 dns_rpz_prefix_t maxbit
, bit
;
1024 maxbit
= ISC_MIN(prefix1
, prefix2
);
1027 * find the first differing words
1031 i
++, bit
+= DNS_RPZ_CIDR_WORD_BITS
) {
1032 delta
= key1
->w
[i
] ^ key2
->w
[i
];
1034 bit
+= ffs_keybit(delta
);
1038 return (ISC_MIN(bit
, maxbit
));
1042 * Given a hit while searching the radix trees,
1043 * clear all bits for higher numbered zones.
1045 static inline dns_rpz_zbits_t
1046 trim_zbits(dns_rpz_zbits_t zbits
, dns_rpz_zbits_t found
) {
1050 * Isolate the first or smallest numbered hit bit.
1051 * Make a mask of that bit and all smaller numbered bits.
1056 return (zbits
&= x
);
1060 * Search a radix tree for an IP address for ordinary lookup
1061 * or for a CIDR block adding or deleting an entry
1063 * Return ISC_R_SUCCESS, DNS_R_PARTIALMATCH, ISC_R_NOTFOUND,
1064 * and *found=longest match node
1065 * or with create==ISC_TRUE, ISC_R_EXISTS or ISC_R_NOMEMORY
1068 search(dns_rpz_zones_t
*rpzs
,
1069 const dns_rpz_cidr_key_t
*tgt_ip
, dns_rpz_prefix_t tgt_prefix
,
1070 const dns_rpz_addr_zbits_t
*tgt_set
, isc_boolean_t create
,
1071 dns_rpz_cidr_node_t
**found
)
1073 dns_rpz_cidr_node_t
*cur
, *parent
, *child
, *new_parent
, *sibling
;
1074 dns_rpz_addr_zbits_t set
;
1075 int cur_num
, child_num
;
1076 dns_rpz_prefix_t dbit
;
1077 isc_result_t find_result
;
1080 find_result
= ISC_R_NOTFOUND
;
1088 * No child so we cannot go down.
1089 * Quit with whatever we already found
1090 * or add the target as a child of the current parent.
1093 return (find_result
);
1094 child
= new_node(rpzs
, tgt_ip
, tgt_prefix
, NULL
);
1096 return (ISC_R_NOMEMORY
);
1100 parent
->child
[cur_num
] = child
;
1101 child
->parent
= parent
;
1102 child
->set
.client_ip
|= tgt_set
->client_ip
;
1103 child
->set
.ip
|= tgt_set
->ip
;
1104 child
->set
.nsip
|= tgt_set
->nsip
;
1105 set_sum_pair(child
);
1107 return (ISC_R_SUCCESS
);
1110 if ((cur
->sum
.client_ip
& set
.client_ip
) == 0 &&
1111 (cur
->sum
.ip
& set
.ip
) == 0 &&
1112 (cur
->sum
.nsip
& set
.nsip
) == 0) {
1114 * This node has no relevant data
1115 * and is in none of the target trees.
1116 * Pretend it does not exist if we are not adding.
1118 * If we are adding, continue down to eventually add
1119 * a node and mark/put this node in the correct tree.
1122 return (find_result
);
1125 dbit
= diff_keys(tgt_ip
, tgt_prefix
, &cur
->ip
, cur
->prefix
);
1127 * dbit <= tgt_prefix and dbit <= cur->prefix always.
1128 * We are finished searching if we matched all of the target.
1130 if (dbit
== tgt_prefix
) {
1131 if (tgt_prefix
== cur
->prefix
) {
1133 * The node's key matches the target exactly.
1135 if ((cur
->set
.client_ip
& set
.client_ip
) != 0 ||
1136 (cur
->set
.ip
& set
.ip
) != 0 ||
1137 (cur
->set
.nsip
& set
.nsip
) != 0) {
1139 * It is the answer if it has data.
1143 find_result
= ISC_R_EXISTS
;
1145 find_result
= ISC_R_SUCCESS
;
1147 } else if (create
) {
1149 * The node lacked relevant data,
1150 * but will have it now.
1152 cur
->set
.client_ip
|= tgt_set
->client_ip
;
1153 cur
->set
.ip
|= tgt_set
->ip
;
1154 cur
->set
.nsip
|= tgt_set
->nsip
;
1157 find_result
= ISC_R_SUCCESS
;
1159 return (find_result
);
1163 * We know tgt_prefix < cur->prefix which means that
1164 * the target is shorter than the current node.
1165 * Add the target as the current node's parent.
1168 return (find_result
);
1170 new_parent
= new_node(rpzs
, tgt_ip
, tgt_prefix
, cur
);
1171 if (new_parent
== NULL
)
1172 return (ISC_R_NOMEMORY
);
1173 new_parent
->parent
= parent
;
1175 rpzs
->cidr
= new_parent
;
1177 parent
->child
[cur_num
] = new_parent
;
1178 child_num
= DNS_RPZ_IP_BIT(&cur
->ip
, tgt_prefix
+1);
1179 new_parent
->child
[child_num
] = cur
;
1180 cur
->parent
= new_parent
;
1181 new_parent
->set
= *tgt_set
;
1182 set_sum_pair(new_parent
);
1183 *found
= new_parent
;
1184 return (ISC_R_SUCCESS
);
1187 if (dbit
== cur
->prefix
) {
1188 if ((cur
->set
.client_ip
& set
.client_ip
) != 0 ||
1189 (cur
->set
.ip
& set
.ip
) != 0 ||
1190 (cur
->set
.nsip
& set
.nsip
) != 0) {
1192 * We have a partial match between of all of the
1193 * current node but only part of the target.
1194 * Continue searching for other hits in the
1195 * same or lower numbered trees.
1197 find_result
= DNS_R_PARTIALMATCH
;
1199 set
.client_ip
= trim_zbits(set
.client_ip
,
1200 cur
->set
.client_ip
);
1201 set
.ip
= trim_zbits(set
.ip
,
1203 set
.nsip
= trim_zbits(set
.nsip
,
1207 cur_num
= DNS_RPZ_IP_BIT(tgt_ip
, dbit
);
1208 cur
= cur
->child
[cur_num
];
1214 * dbit < tgt_prefix and dbit < cur->prefix,
1215 * so we failed to match both the target and the current node.
1216 * Insert a fork of a parent above the current node and
1217 * add the target as a sibling of the current node
1220 return (find_result
);
1222 sibling
= new_node(rpzs
, tgt_ip
, tgt_prefix
, NULL
);
1223 if (sibling
== NULL
)
1224 return (ISC_R_NOMEMORY
);
1225 new_parent
= new_node(rpzs
, tgt_ip
, dbit
, cur
);
1226 if (new_parent
== NULL
) {
1227 isc_mem_put(rpzs
->mctx
, sibling
, sizeof(*sibling
));
1228 return (ISC_R_NOMEMORY
);
1230 new_parent
->parent
= parent
;
1232 rpzs
->cidr
= new_parent
;
1234 parent
->child
[cur_num
] = new_parent
;
1235 child_num
= DNS_RPZ_IP_BIT(tgt_ip
, dbit
);
1236 new_parent
->child
[child_num
] = sibling
;
1237 new_parent
->child
[1-child_num
] = cur
;
1238 cur
->parent
= new_parent
;
1239 sibling
->parent
= new_parent
;
1240 sibling
->set
= *tgt_set
;
1241 set_sum_pair(sibling
);
1243 return (ISC_R_SUCCESS
);
1248 * Add an IP address to the radix tree.
1251 add_cidr(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
,
1252 dns_rpz_type_t rpz_type
, dns_name_t
*src_name
)
1254 dns_rpz_cidr_key_t tgt_ip
;
1255 dns_rpz_prefix_t tgt_prefix
;
1256 dns_rpz_addr_zbits_t set
;
1257 dns_rpz_cidr_node_t
*found
;
1258 isc_result_t result
;
1260 result
= name2ipkey(DNS_RPZ_ERROR_LEVEL
, rpzs
, rpz_num
, rpz_type
,
1261 src_name
, &tgt_ip
, &tgt_prefix
, &set
);
1263 * Log complaints about bad owner names but let the zone load.
1265 if (result
!= ISC_R_SUCCESS
)
1266 return (ISC_R_SUCCESS
);
1268 result
= search(rpzs
, &tgt_ip
, tgt_prefix
, &set
, ISC_TRUE
, &found
);
1269 if (result
!= ISC_R_SUCCESS
) {
1270 char namebuf
[DNS_NAME_FORMATSIZE
];
1273 * Do not worry if the radix tree already exists,
1274 * because diff_apply() likes to add nodes before deleting.
1276 if (result
== ISC_R_EXISTS
)
1277 return (ISC_R_SUCCESS
);
1280 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
1282 dns_name_format(src_name
, namebuf
, sizeof(namebuf
));
1283 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
1284 DNS_LOGMODULE_RBTDB
, DNS_RPZ_ERROR_LEVEL
,
1285 "rpz add_cidr(%s) failed: %s",
1286 namebuf
, isc_result_totext(result
));
1290 adj_trigger_cnt(rpzs
, rpz_num
, rpz_type
, &tgt_ip
, tgt_prefix
, ISC_TRUE
);
1295 add_nm(dns_rpz_zones_t
*rpzs
, dns_name_t
*trig_name
,
1296 const dns_rpz_nm_data_t
*new_data
)
1298 dns_rbtnode_t
*nmnode
;
1299 dns_rpz_nm_data_t
*nm_data
;
1300 isc_result_t result
;
1303 result
= dns_rbt_addnode(rpzs
->rbt
, trig_name
, &nmnode
);
1307 nm_data
= nmnode
->data
;
1308 if (nm_data
== NULL
) {
1309 nm_data
= isc_mem_get(rpzs
->mctx
, sizeof(*nm_data
));
1310 if (nm_data
== NULL
)
1311 return (ISC_R_NOMEMORY
);
1312 *nm_data
= *new_data
;
1313 nmnode
->data
= nm_data
;
1314 return (ISC_R_SUCCESS
);
1322 * Do not count bits that are already present
1324 if ((nm_data
->set
.qname
& new_data
->set
.qname
) != 0 ||
1325 (nm_data
->set
.ns
& new_data
->set
.ns
) != 0 ||
1326 (nm_data
->wild
.qname
& new_data
->wild
.qname
) != 0 ||
1327 (nm_data
->wild
.ns
& new_data
->wild
.ns
) != 0)
1328 return (ISC_R_EXISTS
);
1330 nm_data
->set
.qname
|= new_data
->set
.qname
;
1331 nm_data
->set
.ns
|= new_data
->set
.ns
;
1332 nm_data
->wild
.qname
|= new_data
->wild
.qname
;
1333 nm_data
->wild
.ns
|= new_data
->wild
.ns
;
1334 return (ISC_R_SUCCESS
);
1338 add_name(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
,
1339 dns_rpz_type_t rpz_type
, dns_name_t
*src_name
)
1341 dns_rpz_nm_data_t new_data
;
1342 dns_fixedname_t trig_namef
;
1343 dns_name_t
*trig_name
;
1344 isc_result_t result
;
1347 * No need for a summary database of names with only 1 policy zone.
1349 if (rpzs
->p
.num_zones
<= 1) {
1350 adj_trigger_cnt(rpzs
, rpz_num
, rpz_type
, NULL
, 0, ISC_TRUE
);
1351 return (ISC_R_SUCCESS
);
1354 dns_fixedname_init(&trig_namef
);
1355 trig_name
= dns_fixedname_name(&trig_namef
);
1356 name2data(rpzs
, rpz_num
, rpz_type
, src_name
, trig_name
, &new_data
);
1358 result
= add_nm(rpzs
, trig_name
, &new_data
);
1361 * Do not worry if the node already exists,
1362 * because diff_apply() likes to add nodes before deleting.
1364 if (result
== ISC_R_EXISTS
)
1365 return (ISC_R_SUCCESS
);
1366 if (result
== ISC_R_SUCCESS
)
1367 adj_trigger_cnt(rpzs
, rpz_num
, rpz_type
, NULL
, 0, ISC_TRUE
);
1372 * Callback to free the data for a node in the summary RBT database.
1375 rpz_node_deleter(void *nm_data
, void *mctx
) {
1376 isc_mem_put(mctx
, nm_data
, sizeof(dns_rpz_nm_data_t
));
1380 * Get ready for a new set of policy zones.
1383 dns_rpz_new_zones(dns_rpz_zones_t
**rpzsp
, isc_mem_t
*mctx
) {
1384 dns_rpz_zones_t
*new;
1385 isc_result_t result
;
1387 REQUIRE(rpzsp
!= NULL
&& *rpzsp
== NULL
);
1391 new = isc_mem_get(mctx
, sizeof(*new));
1393 return (ISC_R_NOMEMORY
);
1394 memset(new, 0, sizeof(*new));
1396 result
= isc_rwlock_init(&new->search_lock
, 0, 0);
1397 if (result
!= ISC_R_SUCCESS
) {
1398 isc_mem_put(mctx
, new, sizeof(*new));
1402 result
= isc_mutex_init(&new->maint_lock
);
1403 if (result
!= ISC_R_SUCCESS
) {
1404 isc_rwlock_destroy(&new->search_lock
);
1405 isc_mem_put(mctx
, new, sizeof(*new));
1409 result
= isc_refcount_init(&new->refs
, 1);
1410 if (result
!= ISC_R_SUCCESS
) {
1411 DESTROYLOCK(&new->maint_lock
);
1412 isc_rwlock_destroy(&new->search_lock
);
1413 isc_mem_put(mctx
, new, sizeof(*new));
1417 result
= dns_rbt_create(mctx
, rpz_node_deleter
, mctx
, &new->rbt
);
1418 if (result
!= ISC_R_SUCCESS
) {
1419 isc_refcount_decrement(&new->refs
, NULL
);
1420 isc_refcount_destroy(&new->refs
);
1421 DESTROYLOCK(&new->maint_lock
);
1422 isc_rwlock_destroy(&new->search_lock
);
1423 isc_mem_put(mctx
, new, sizeof(*new));
1427 isc_mem_attach(mctx
, &new->mctx
);
1430 return (ISC_R_SUCCESS
);
1434 * Free the radix tree of a response policy database.
1437 cidr_free(dns_rpz_zones_t
*rpzs
) {
1438 dns_rpz_cidr_node_t
*cur
, *child
, *parent
;
1441 while (cur
!= NULL
) {
1443 child
= cur
->child
[0];
1444 if (child
!= NULL
) {
1448 child
= cur
->child
[1];
1449 if (child
!= NULL
) {
1454 /* Delete this leaf and go up. */
1455 parent
= cur
->parent
;
1459 parent
->child
[parent
->child
[1] == cur
] = NULL
;
1460 isc_mem_put(rpzs
->mctx
, cur
, sizeof(*cur
));
1466 * Discard a response policy zone blob
1467 * before discarding the overall rpz structure.
1470 rpz_detach(dns_rpz_zone_t
**rpzp
, dns_rpz_zones_t
*rpzs
) {
1471 dns_rpz_zone_t
*rpz
;
1476 isc_refcount_decrement(&rpz
->refs
, &refs
);
1479 isc_refcount_destroy(&rpz
->refs
);
1481 if (dns_name_dynamic(&rpz
->origin
))
1482 dns_name_free(&rpz
->origin
, rpzs
->mctx
);
1483 if (dns_name_dynamic(&rpz
->client_ip
))
1484 dns_name_free(&rpz
->client_ip
, rpzs
->mctx
);
1485 if (dns_name_dynamic(&rpz
->ip
))
1486 dns_name_free(&rpz
->ip
, rpzs
->mctx
);
1487 if (dns_name_dynamic(&rpz
->nsdname
))
1488 dns_name_free(&rpz
->nsdname
, rpzs
->mctx
);
1489 if (dns_name_dynamic(&rpz
->nsip
))
1490 dns_name_free(&rpz
->nsip
, rpzs
->mctx
);
1491 if (dns_name_dynamic(&rpz
->passthru
))
1492 dns_name_free(&rpz
->passthru
, rpzs
->mctx
);
1493 if (dns_name_dynamic(&rpz
->drop
))
1494 dns_name_free(&rpz
->drop
, rpzs
->mctx
);
1495 if (dns_name_dynamic(&rpz
->tcp_only
))
1496 dns_name_free(&rpz
->tcp_only
, rpzs
->mctx
);
1497 if (dns_name_dynamic(&rpz
->cname
))
1498 dns_name_free(&rpz
->cname
, rpzs
->mctx
);
1500 isc_mem_put(rpzs
->mctx
, rpz
, sizeof(*rpz
));
1504 dns_rpz_attach_rpzs(dns_rpz_zones_t
*rpzs
, dns_rpz_zones_t
**rpzsp
) {
1505 REQUIRE(rpzsp
!= NULL
&& *rpzsp
== NULL
);
1506 isc_refcount_increment(&rpzs
->refs
, NULL
);
1511 * Forget a view's policy zones.
1514 dns_rpz_detach_rpzs(dns_rpz_zones_t
**rpzsp
) {
1515 dns_rpz_zones_t
*rpzs
;
1516 dns_rpz_zone_t
*rpz
;
1517 dns_rpz_num_t rpz_num
;
1520 REQUIRE(rpzsp
!= NULL
);
1522 REQUIRE(rpzs
!= NULL
);
1525 isc_refcount_decrement(&rpzs
->refs
, &refs
);
1528 * Forget the last of view's rpz machinery after the last reference.
1531 for (rpz_num
= 0; rpz_num
< DNS_RPZ_MAX_ZONES
; ++rpz_num
) {
1532 rpz
= rpzs
->zones
[rpz_num
];
1533 rpzs
->zones
[rpz_num
] = NULL
;
1535 rpz_detach(&rpz
, rpzs
);
1539 dns_rbt_destroy(&rpzs
->rbt
);
1540 DESTROYLOCK(&rpzs
->maint_lock
);
1541 isc_rwlock_destroy(&rpzs
->search_lock
);
1542 isc_refcount_destroy(&rpzs
->refs
);
1543 isc_mem_putanddetach(&rpzs
->mctx
, rpzs
, sizeof(*rpzs
));
1548 * Create empty summary database to load one zone.
1549 * The RBTDB write tree lock must be held.
1552 dns_rpz_beginload(dns_rpz_zones_t
**load_rpzsp
,
1553 dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
)
1555 dns_rpz_zones_t
*load_rpzs
;
1556 dns_rpz_zone_t
*rpz
;
1557 dns_rpz_zbits_t tgt
;
1558 isc_result_t result
;
1560 REQUIRE(rpz_num
< rpzs
->p
.num_zones
);
1561 rpz
= rpzs
->zones
[rpz_num
];
1562 REQUIRE(rpz
!= NULL
);
1565 * When reloading a zone, there are usually records among the summary
1566 * data for the zone. Some of those records might be deleted by the
1567 * reloaded zone data. To deal with that case:
1568 * reload the new zone data into a new blank summary database
1569 * if the reload fails, discard the new summary database
1570 * if the new zone data is acceptable, copy the records for the
1571 * other zones into the new summary CIDR and RBT databases
1572 * and replace the old summary databases with the new, and
1573 * correct the triggers and have values for the updated
1576 * At the first attempt to load a zone, there is no summary data
1577 * for the zone and so no records that need to be deleted.
1578 * This is also the most common case of policy zone loading.
1579 * Most policy zone maintenance should be by incremental changes
1580 * and so by the addition and deletion of individual records.
1581 * Detect that case and load records the first time into the
1582 * operational summary database
1584 tgt
= DNS_RPZ_ZBIT(rpz_num
);
1585 LOCK(&rpzs
->maint_lock
);
1586 RWLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
1587 if ((rpzs
->load_begun
& tgt
) == 0) {
1589 * There is no existing version of the target zone.
1591 rpzs
->load_begun
|= tgt
;
1592 dns_rpz_attach_rpzs(rpzs
, load_rpzsp
);
1595 * Setup the new RPZ struct with empty summary trees.
1597 result
= dns_rpz_new_zones(load_rpzsp
, rpzs
->mctx
);
1598 if (result
!= ISC_R_SUCCESS
)
1600 load_rpzs
= *load_rpzsp
;
1602 * Initialize some members so that dns_rpz_add() works.
1604 load_rpzs
->p
.num_zones
= rpzs
->p
.num_zones
;
1605 memset(&load_rpzs
->triggers
, 0, sizeof(load_rpzs
->triggers
));
1606 load_rpzs
->zones
[rpz_num
] = rpz
;
1607 isc_refcount_increment(&rpz
->refs
, NULL
);
1610 RWUNLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
1611 UNLOCK(&rpzs
->maint_lock
);
1613 return (ISC_R_SUCCESS
);
1617 * This function updates "have" bits and also the qname_skip_recurse
1618 * mask. It must be called when holding a write lock on rpzs->search_lock.
1621 fix_triggers(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
) {
1623 dns_rpz_triggers_t old_totals
;
1624 dns_rpz_zbits_t zbit
;
1625 char namebuf
[DNS_NAME_FORMATSIZE
];
1628 * rpzs->total_triggers is only used to log a message below.
1631 memmove(&old_totals
, &rpzs
->total_triggers
, sizeof(old_totals
));
1632 memset(&rpzs
->total_triggers
, 0, sizeof(rpzs
->total_triggers
));
1634 #define SET_TRIG(n, zbit, type) \
1635 if (rpzs->triggers[n].type == 0) { \
1636 rpzs->have.type &= ~zbit; \
1638 rpzs->total_triggers.type += rpzs->triggers[n].type; \
1639 rpzs->have.type |= zbit; \
1642 for (n
= 0; n
< rpzs
->p
.num_zones
; ++n
) {
1643 zbit
= DNS_RPZ_ZBIT(n
);
1644 SET_TRIG(n
, zbit
, client_ipv4
);
1645 SET_TRIG(n
, zbit
, client_ipv6
);
1646 SET_TRIG(n
, zbit
, qname
);
1647 SET_TRIG(n
, zbit
, ipv4
);
1648 SET_TRIG(n
, zbit
, ipv6
);
1649 SET_TRIG(n
, zbit
, nsdname
);
1650 SET_TRIG(n
, zbit
, nsipv4
);
1651 SET_TRIG(n
, zbit
, nsipv6
);
1656 fix_qname_skip_recurse(rpzs
);
1658 dns_name_format(&rpzs
->zones
[rpz_num
]->origin
,
1659 namebuf
, sizeof(namebuf
));
1660 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
1661 DNS_LOGMODULE_RBTDB
, DNS_RPZ_INFO_LEVEL
,
1662 "(re)loading policy zone '%s' changed from"
1663 " %lu to %lu qname, %lu to %lu nsdname,"
1664 " %lu to %lu IP, %lu to %lu NSIP,"
1665 " %lu to %lu CLIENTIP entries",
1667 (unsigned long) old_totals
.qname
,
1668 (unsigned long) rpzs
->total_triggers
.qname
,
1669 (unsigned long) old_totals
.nsdname
,
1670 (unsigned long) rpzs
->total_triggers
.nsdname
,
1671 (unsigned long) old_totals
.ipv4
+ old_totals
.ipv6
,
1672 (unsigned long) (rpzs
->total_triggers
.ipv4
+
1673 rpzs
->total_triggers
.ipv6
),
1674 (unsigned long) old_totals
.nsipv4
+ old_totals
.nsipv6
,
1675 (unsigned long) (rpzs
->total_triggers
.nsipv4
+
1676 rpzs
->total_triggers
.nsipv6
),
1677 (unsigned long) old_totals
.client_ipv4
+
1678 old_totals
.client_ipv6
,
1679 (unsigned long) (rpzs
->total_triggers
.client_ipv4
+
1680 rpzs
->total_triggers
.client_ipv6
));
1684 * Finish loading one zone. This function is called during a commit when
1685 * a RPZ zone loading is complete. The RBTDB write tree lock must be
1688 * Here, rpzs is a pointer to the view's common rpzs
1689 * structure. *load_rpzsp is a rpzs structure that is local to the
1690 * RBTDB, which is used during a single zone's load.
1692 * During the zone load, i.e., between dns_rpz_beginload() and
1693 * dns_rpz_ready(), only the zone that is being loaded updates
1694 * *load_rpzsp. These updates in the summary databases inside load_rpzsp
1695 * are made only for the rpz_num (and corresponding bit) of that
1696 * zone. Nothing else reads or writes *load_rpzsp. The view's common
1697 * rpzs is used during this time for queries.
1699 * When zone loading is complete and we arrive here, the parts of the
1700 * summary databases (CIDR and nsdname+qname RBT trees) from the view's
1701 * common rpzs struct have to be merged into the summary databases of
1702 * *load_rpzsp, as the summary databases of the view's common rpzs
1703 * struct may have changed during the time the zone was being loaded.
1705 * The function below carries out the merge. During the merge, it holds
1706 * the maint_lock of the view's common rpzs struct so that it is not
1707 * updated while the merging is taking place.
1709 * After the merging is carried out, *load_rpzsp contains the most
1710 * current state of the rpzs structure, i.e., the summary trees contain
1711 * data for the new zone that was just loaded, as well as all other
1714 * Pointers to the summary databases of *load_rpzsp (CIDR and
1715 * nsdname+qname RBT trees) are then swapped into the view's common rpz
1716 * struct, so that the query path can continue using it. During the
1717 * swap, the search_lock of the view's common rpz struct is acquired so
1718 * that queries are paused while this swap occurs.
1720 * The trigger counts for the new zone are also copied into the view's
1721 * common rpz struct, and some other summary counts and masks are
1725 dns_rpz_ready(dns_rpz_zones_t
*rpzs
,
1726 dns_rpz_zones_t
**load_rpzsp
, dns_rpz_num_t rpz_num
)
1728 dns_rpz_zones_t
*load_rpzs
;
1729 const dns_rpz_cidr_node_t
*cnode
, *next_cnode
, *parent_cnode
;
1730 dns_rpz_cidr_node_t
*found
;
1731 dns_rpz_zbits_t new_bit
;
1732 dns_rpz_addr_zbits_t new_ip
;
1734 dns_rbtnodechain_t chain
;
1735 dns_rbtnode_t
*nmnode
;
1736 dns_rpz_nm_data_t
*nm_data
, new_data
;
1737 dns_fixedname_t labelf
, originf
, namef
;
1738 dns_name_t
*label
, *origin
, *name
;
1739 isc_result_t result
;
1741 INSIST(rpzs
!= NULL
);
1742 LOCK(&rpzs
->maint_lock
);
1743 load_rpzs
= *load_rpzsp
;
1744 INSIST(load_rpzs
!= NULL
);
1746 if (load_rpzs
== rpzs
) {
1748 * This is a successful initial zone loading, perhaps
1749 * for a new instance of a view.
1751 RWLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
1752 fix_triggers(rpzs
, rpz_num
);
1753 RWUNLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
1754 UNLOCK(&rpzs
->maint_lock
);
1755 dns_rpz_detach_rpzs(load_rpzsp
);
1756 return (ISC_R_SUCCESS
);
1759 LOCK(&load_rpzs
->maint_lock
);
1760 RWLOCK(&load_rpzs
->search_lock
, isc_rwlocktype_write
);
1763 * Unless there is only one policy zone, copy the other policy zones
1764 * from the old policy structure to the new summary databases.
1766 if (rpzs
->p
.num_zones
> 1) {
1767 new_bit
= ~DNS_RPZ_ZBIT(rpz_num
);
1770 * Copy to the radix tree.
1772 for (cnode
= rpzs
->cidr
; cnode
!= NULL
; cnode
= next_cnode
) {
1773 new_ip
.ip
= cnode
->set
.ip
& new_bit
;
1774 new_ip
.client_ip
= cnode
->set
.client_ip
& new_bit
;
1775 new_ip
.nsip
= cnode
->set
.nsip
& new_bit
;
1776 if (new_ip
.client_ip
!= 0 ||
1779 result
= search(load_rpzs
,
1780 &cnode
->ip
, cnode
->prefix
,
1781 &new_ip
, ISC_TRUE
, &found
);
1782 if (result
== ISC_R_NOMEMORY
)
1783 goto unlock_and_detach
;
1784 INSIST(result
== ISC_R_SUCCESS
);
1787 * Do down and to the left as far as possible.
1789 next_cnode
= cnode
->child
[0];
1790 if (next_cnode
!= NULL
)
1793 * Go up until we find a branch to the right where
1794 * we previously took the branch to the left.
1797 parent_cnode
= cnode
->parent
;
1798 if (parent_cnode
== NULL
)
1800 if (parent_cnode
->child
[0] == cnode
) {
1801 next_cnode
= parent_cnode
->child
[1];
1802 if (next_cnode
!= NULL
)
1805 cnode
= parent_cnode
;
1810 * Copy to the summary RBT.
1812 dns_fixedname_init(&namef
);
1813 name
= dns_fixedname_name(&namef
);
1814 dns_fixedname_init(&labelf
);
1815 label
= dns_fixedname_name(&labelf
);
1816 dns_fixedname_init(&originf
);
1817 origin
= dns_fixedname_name(&originf
);
1818 dns_rbtnodechain_init(&chain
, NULL
);
1819 result
= dns_rbtnodechain_first(&chain
, rpzs
->rbt
, NULL
, NULL
);
1820 while (result
== DNS_R_NEWORIGIN
|| result
== ISC_R_SUCCESS
) {
1821 result
= dns_rbtnodechain_current(&chain
, label
, origin
,
1823 INSIST(result
== ISC_R_SUCCESS
);
1824 nm_data
= nmnode
->data
;
1825 if (nm_data
!= NULL
) {
1826 new_data
.set
.qname
= (nm_data
->set
.qname
&
1828 new_data
.set
.ns
= nm_data
->set
.ns
& new_bit
;
1829 new_data
.wild
.qname
= (nm_data
->wild
.qname
&
1831 new_data
.wild
.ns
= nm_data
->wild
.ns
& new_bit
;
1832 if (new_data
.set
.qname
!= 0 ||
1833 new_data
.set
.ns
!= 0 ||
1834 new_data
.wild
.qname
!= 0 ||
1835 new_data
.wild
.ns
!= 0) {
1836 result
= dns_name_concatenate(label
,
1837 origin
, name
, NULL
);
1838 INSIST(result
== ISC_R_SUCCESS
);
1839 result
= add_nm(load_rpzs
, name
,
1841 if (result
!= ISC_R_SUCCESS
)
1842 goto unlock_and_detach
;
1845 result
= dns_rbtnodechain_next(&chain
, NULL
, NULL
);
1847 if (result
!= ISC_R_NOMORE
&& result
!= ISC_R_NOTFOUND
) {
1848 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
1849 DNS_LOGMODULE_RBTDB
, DNS_RPZ_ERROR_LEVEL
,
1850 "dns_rpz_ready(): unexpected %s",
1851 isc_result_totext(result
));
1852 goto unlock_and_detach
;
1857 * Exchange the summary databases.
1859 RWLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
1861 rpzs
->triggers
[rpz_num
] = load_rpzs
->triggers
[rpz_num
];
1862 fix_triggers(rpzs
, rpz_num
);
1865 rpzs
->cidr
= load_rpzs
->cidr
;
1866 load_rpzs
->cidr
= found
;
1869 rpzs
->rbt
= load_rpzs
->rbt
;
1870 load_rpzs
->rbt
= rbt
;
1872 RWUNLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
1874 result
= ISC_R_SUCCESS
;
1877 UNLOCK(&rpzs
->maint_lock
);
1878 RWUNLOCK(&load_rpzs
->search_lock
, isc_rwlocktype_write
);
1879 UNLOCK(&load_rpzs
->maint_lock
);
1880 dns_rpz_detach_rpzs(load_rpzsp
);
1885 * Add an IP address to the radix tree or a name to the summary database.
1888 dns_rpz_add(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
, dns_name_t
*src_name
)
1890 dns_rpz_zone_t
*rpz
;
1891 dns_rpz_type_t rpz_type
;
1892 isc_result_t result
= ISC_R_FAILURE
;
1894 REQUIRE(rpzs
!= NULL
&& rpz_num
< rpzs
->p
.num_zones
);
1895 rpz
= rpzs
->zones
[rpz_num
];
1896 REQUIRE(rpz
!= NULL
);
1898 rpz_type
= type_from_name(rpz
, src_name
);
1900 LOCK(&rpzs
->maint_lock
);
1901 RWLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
1904 case DNS_RPZ_TYPE_QNAME
:
1905 case DNS_RPZ_TYPE_NSDNAME
:
1906 result
= add_name(rpzs
, rpz_num
, rpz_type
, src_name
);
1908 case DNS_RPZ_TYPE_CLIENT_IP
:
1909 case DNS_RPZ_TYPE_IP
:
1910 case DNS_RPZ_TYPE_NSIP
:
1911 result
= add_cidr(rpzs
, rpz_num
, rpz_type
, src_name
);
1913 case DNS_RPZ_TYPE_BAD
:
1917 RWUNLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
1918 UNLOCK(&rpzs
->maint_lock
);
1923 * Remove an IP address from the radix tree.
1926 del_cidr(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
,
1927 dns_rpz_type_t rpz_type
, dns_name_t
*src_name
)
1929 isc_result_t result
;
1930 dns_rpz_cidr_key_t tgt_ip
;
1931 dns_rpz_prefix_t tgt_prefix
;
1932 dns_rpz_addr_zbits_t tgt_set
;
1933 dns_rpz_cidr_node_t
*tgt
, *parent
, *child
;
1936 * Do not worry about invalid rpz IP address names. If we
1937 * are here, then something relevant was added and so was
1938 * valid. Invalid names here are usually internal RBTDB nodes.
1940 result
= name2ipkey(DNS_RPZ_DEBUG_QUIET
, rpzs
, rpz_num
, rpz_type
,
1941 src_name
, &tgt_ip
, &tgt_prefix
, &tgt_set
);
1942 if (result
!= ISC_R_SUCCESS
)
1945 result
= search(rpzs
, &tgt_ip
, tgt_prefix
, &tgt_set
, ISC_FALSE
, &tgt
);
1946 if (result
!= ISC_R_SUCCESS
) {
1947 INSIST(result
== ISC_R_NOTFOUND
||
1948 result
== DNS_R_PARTIALMATCH
);
1950 * Do not worry about missing summary RBT nodes that probably
1951 * correspond to RBTDB nodes that were implicit RBT nodes
1952 * that were later added for (often empty) wildcards
1953 * and then to the RBTDB deferred cleanup list.
1959 * Mark the node and its parents to reflect the deleted IP address.
1960 * Do not count bits that are already clear for internal RBTDB nodes.
1962 tgt_set
.client_ip
&= tgt
->set
.client_ip
;
1963 tgt_set
.ip
&= tgt
->set
.ip
;
1964 tgt_set
.nsip
&= tgt
->set
.nsip
;
1965 tgt
->set
.client_ip
&= ~tgt_set
.client_ip
;
1966 tgt
->set
.ip
&= ~tgt_set
.ip
;
1967 tgt
->set
.nsip
&= ~tgt_set
.nsip
;
1970 adj_trigger_cnt(rpzs
, rpz_num
, rpz_type
, &tgt_ip
, tgt_prefix
, ISC_FALSE
);
1973 * We might need to delete 2 nodes.
1977 * The node is now useless if it has no data of its own
1978 * and 0 or 1 children. We are finished if it is not useless.
1980 if ((child
= tgt
->child
[0]) != NULL
) {
1981 if (tgt
->child
[1] != NULL
)
1984 child
= tgt
->child
[1];
1986 if (tgt
->set
.client_ip
!= 0 ||
1992 * Replace the pointer to this node in the parent with
1993 * the remaining child or NULL.
1995 parent
= tgt
->parent
;
1996 if (parent
== NULL
) {
1999 parent
->child
[parent
->child
[1] == tgt
] = child
;
2002 * If the child exists fix up its parent pointer.
2005 child
->parent
= parent
;
2006 isc_mem_put(rpzs
->mctx
, tgt
, sizeof(*tgt
));
2009 } while (tgt
!= NULL
);
2013 del_name(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
,
2014 dns_rpz_type_t rpz_type
, dns_name_t
*src_name
)
2016 char namebuf
[DNS_NAME_FORMATSIZE
];
2017 dns_fixedname_t trig_namef
;
2018 dns_name_t
*trig_name
;
2019 dns_rbtnode_t
*nmnode
;
2020 dns_rpz_nm_data_t
*nm_data
, del_data
;
2021 isc_result_t result
;
2024 * No need for a summary database of names with only 1 policy zone.
2026 if (rpzs
->p
.num_zones
<= 1) {
2027 adj_trigger_cnt(rpzs
, rpz_num
, rpz_type
, NULL
, 0, ISC_FALSE
);
2031 dns_fixedname_init(&trig_namef
);
2032 trig_name
= dns_fixedname_name(&trig_namef
);
2033 name2data(rpzs
, rpz_num
, rpz_type
, src_name
, trig_name
, &del_data
);
2036 result
= dns_rbt_findnode(rpzs
->rbt
, trig_name
, NULL
, &nmnode
, NULL
, 0,
2038 if (result
!= ISC_R_SUCCESS
) {
2040 * Do not worry about missing summary RBT nodes that probably
2041 * correspond to RBTDB nodes that were implicit RBT nodes
2042 * that were later added for (often empty) wildcards
2043 * and then to the RBTDB deferred cleanup list.
2045 if (result
== ISC_R_NOTFOUND
||
2046 result
== DNS_R_PARTIALMATCH
)
2048 dns_name_format(src_name
, namebuf
, sizeof(namebuf
));
2049 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
2050 DNS_LOGMODULE_RBTDB
, DNS_RPZ_ERROR_LEVEL
,
2051 "rpz del_name(%s) node search failed: %s",
2052 namebuf
, isc_result_totext(result
));
2056 nm_data
= nmnode
->data
;
2057 INSIST(nm_data
!= NULL
);
2060 * Do not count bits that next existed for RBT nodes that would we
2061 * would not have found in a summary for a single RBTDB tree.
2063 del_data
.set
.qname
&= nm_data
->set
.qname
;
2064 del_data
.set
.ns
&= nm_data
->set
.ns
;
2065 del_data
.wild
.qname
&= nm_data
->wild
.qname
;
2066 del_data
.wild
.ns
&= nm_data
->wild
.ns
;
2068 nm_data
->set
.qname
&= ~del_data
.set
.qname
;
2069 nm_data
->set
.ns
&= ~del_data
.set
.ns
;
2070 nm_data
->wild
.qname
&= ~del_data
.wild
.qname
;
2071 nm_data
->wild
.ns
&= ~del_data
.wild
.ns
;
2073 if (nm_data
->set
.qname
== 0 && nm_data
->set
.ns
== 0 &&
2074 nm_data
->wild
.qname
== 0 && nm_data
->wild
.ns
== 0) {
2075 result
= dns_rbt_deletenode(rpzs
->rbt
, nmnode
, ISC_FALSE
);
2076 if (result
!= ISC_R_SUCCESS
) {
2078 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2080 dns_name_format(src_name
, namebuf
, sizeof(namebuf
));
2081 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
2082 DNS_LOGMODULE_RBTDB
, DNS_RPZ_ERROR_LEVEL
,
2083 "rpz del_name(%s) node delete failed: %s",
2084 namebuf
, isc_result_totext(result
));
2088 adj_trigger_cnt(rpzs
, rpz_num
, rpz_type
, NULL
, 0, ISC_FALSE
);
2092 * Remove an IP address from the radix tree or a name from the summary database.
2095 dns_rpz_delete(dns_rpz_zones_t
*rpzs
, dns_rpz_num_t rpz_num
,
2096 dns_name_t
*src_name
) {
2097 dns_rpz_zone_t
*rpz
;
2098 dns_rpz_type_t rpz_type
;
2100 REQUIRE(rpzs
!= NULL
&& rpz_num
< rpzs
->p
.num_zones
);
2101 rpz
= rpzs
->zones
[rpz_num
];
2102 REQUIRE(rpz
!= NULL
);
2104 rpz_type
= type_from_name(rpz
, src_name
);
2106 LOCK(&rpzs
->maint_lock
);
2107 RWLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
2110 case DNS_RPZ_TYPE_QNAME
:
2111 case DNS_RPZ_TYPE_NSDNAME
:
2112 del_name(rpzs
, rpz_num
, rpz_type
, src_name
);
2114 case DNS_RPZ_TYPE_CLIENT_IP
:
2115 case DNS_RPZ_TYPE_IP
:
2116 case DNS_RPZ_TYPE_NSIP
:
2117 del_cidr(rpzs
, rpz_num
, rpz_type
, src_name
);
2119 case DNS_RPZ_TYPE_BAD
:
2123 RWUNLOCK(&rpzs
->search_lock
, isc_rwlocktype_write
);
2124 UNLOCK(&rpzs
->maint_lock
);
2128 * Search the summary radix tree to get a relative owner name in a
2129 * policy zone relevant to a triggering IP address.
2130 * rpz_type and zbits limit the search for IP address netaddr
2131 * return the policy zone's number or DNS_RPZ_INVALID_NUM
2132 * ip_name is the relative owner name found and
2133 * *prefixp is its prefix length.
2136 dns_rpz_find_ip(dns_rpz_zones_t
*rpzs
, dns_rpz_type_t rpz_type
,
2137 dns_rpz_zbits_t zbits
, const isc_netaddr_t
*netaddr
,
2138 dns_name_t
*ip_name
, dns_rpz_prefix_t
*prefixp
)
2140 dns_rpz_cidr_key_t tgt_ip
;
2141 dns_rpz_addr_zbits_t tgt_set
;
2142 dns_rpz_cidr_node_t
*found
;
2143 isc_result_t result
;
2144 dns_rpz_num_t rpz_num
;
2145 dns_rpz_have_t have
;
2148 LOCK(&rpzs
->maint_lock
);
2150 UNLOCK(&rpzs
->maint_lock
);
2153 * Convert IP address to CIDR tree key.
2155 if (netaddr
->family
== AF_INET
) {
2158 tgt_ip
.w
[2] = ADDR_V4MAPPED
;
2159 tgt_ip
.w
[3] = ntohl(netaddr
->type
.in
.s_addr
);
2161 case DNS_RPZ_TYPE_CLIENT_IP
:
2162 zbits
&= have
.client_ipv4
;
2164 case DNS_RPZ_TYPE_IP
:
2167 case DNS_RPZ_TYPE_NSIP
:
2168 zbits
&= have
.nsipv4
;
2174 } else if (netaddr
->family
== AF_INET6
) {
2175 dns_rpz_cidr_key_t src_ip6
;
2178 * Given the int aligned struct in_addr member of netaddr->type
2179 * one could cast netaddr->type.in6 to dns_rpz_cidr_key_t *,
2180 * but some people object.
2182 memmove(src_ip6
.w
, &netaddr
->type
.in6
, sizeof(src_ip6
.w
));
2183 for (i
= 0; i
< 4; i
++) {
2184 tgt_ip
.w
[i
] = ntohl(src_ip6
.w
[i
]);
2187 case DNS_RPZ_TYPE_CLIENT_IP
:
2188 zbits
&= have
.client_ipv6
;
2190 case DNS_RPZ_TYPE_IP
:
2193 case DNS_RPZ_TYPE_NSIP
:
2194 zbits
&= have
.nsipv6
;
2201 return (DNS_RPZ_INVALID_NUM
);
2205 return (DNS_RPZ_INVALID_NUM
);
2206 make_addr_set(&tgt_set
, zbits
, rpz_type
);
2208 RWLOCK(&rpzs
->search_lock
, isc_rwlocktype_read
);
2209 result
= search(rpzs
, &tgt_ip
, 128, &tgt_set
, ISC_FALSE
, &found
);
2210 if (result
== ISC_R_NOTFOUND
) {
2212 * There are no eligible zones for this IP address.
2214 RWUNLOCK(&rpzs
->search_lock
, isc_rwlocktype_read
);
2215 return (DNS_RPZ_INVALID_NUM
);
2219 * Construct the trigger name for the longest matching trigger
2220 * in the first eligible zone with a match.
2222 *prefixp
= found
->prefix
;
2224 case DNS_RPZ_TYPE_CLIENT_IP
:
2225 rpz_num
= zbit_to_num(found
->set
.client_ip
& tgt_set
.client_ip
);
2227 case DNS_RPZ_TYPE_IP
:
2228 rpz_num
= zbit_to_num(found
->set
.ip
& tgt_set
.ip
);
2230 case DNS_RPZ_TYPE_NSIP
:
2231 rpz_num
= zbit_to_num(found
->set
.nsip
& tgt_set
.nsip
);
2237 result
= ip2name(&found
->ip
, found
->prefix
, dns_rootname
, ip_name
);
2238 RWUNLOCK(&rpzs
->search_lock
, isc_rwlocktype_read
);
2239 if (result
!= ISC_R_SUCCESS
) {
2241 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2243 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
2244 DNS_LOGMODULE_RBTDB
, DNS_RPZ_ERROR_LEVEL
,
2245 "rpz ip2name() failed: %s",
2246 isc_result_totext(result
));
2247 return (DNS_RPZ_INVALID_NUM
);
2253 * Search the summary radix tree for policy zones with triggers matching
2257 dns_rpz_find_name(dns_rpz_zones_t
*rpzs
, dns_rpz_type_t rpz_type
,
2258 dns_rpz_zbits_t zbits
, dns_name_t
*trig_name
)
2260 char namebuf
[DNS_NAME_FORMATSIZE
];
2261 dns_rbtnode_t
*nmnode
;
2262 const dns_rpz_nm_data_t
*nm_data
;
2263 dns_rpz_zbits_t found_zbits
;
2264 isc_result_t result
;
2271 RWLOCK(&rpzs
->search_lock
, isc_rwlocktype_read
);
2274 result
= dns_rbt_findnode(rpzs
->rbt
, trig_name
, NULL
, &nmnode
, NULL
,
2275 DNS_RBTFIND_EMPTYDATA
, NULL
, NULL
);
2278 nm_data
= nmnode
->data
;
2279 if (nm_data
!= NULL
) {
2280 if (rpz_type
== DNS_RPZ_TYPE_QNAME
)
2281 found_zbits
= nm_data
->set
.qname
;
2283 found_zbits
= nm_data
->set
.ns
;
2285 nmnode
= nmnode
->parent
;
2287 case DNS_R_PARTIALMATCH
:
2288 while (nmnode
!= NULL
) {
2289 nm_data
= nmnode
->data
;
2290 if (nm_data
!= NULL
) {
2291 if (rpz_type
== DNS_RPZ_TYPE_QNAME
)
2292 found_zbits
|= nm_data
->wild
.qname
;
2294 found_zbits
|= nm_data
->wild
.ns
;
2296 nmnode
= nmnode
->parent
;
2300 case ISC_R_NOTFOUND
:
2305 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2307 dns_name_format(trig_name
, namebuf
, sizeof(namebuf
));
2308 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_RPZ
,
2309 DNS_LOGMODULE_RBTDB
, DNS_RPZ_ERROR_LEVEL
,
2310 "dns_rpz_find_name(%s) failed: %s",
2311 namebuf
, isc_result_totext(result
));
2315 RWUNLOCK(&rpzs
->search_lock
, isc_rwlocktype_read
);
2316 return (zbits
& found_zbits
);
2320 * Translate CNAME rdata to a QNAME response policy action.
2323 dns_rpz_decode_cname(dns_rpz_zone_t
*rpz
, dns_rdataset_t
*rdataset
,
2324 dns_name_t
*selfname
)
2326 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2327 dns_rdata_cname_t cname
;
2328 isc_result_t result
;
2330 result
= dns_rdataset_first(rdataset
);
2331 INSIST(result
== ISC_R_SUCCESS
);
2332 dns_rdataset_current(rdataset
, &rdata
);
2333 result
= dns_rdata_tostruct(&rdata
, &cname
, NULL
);
2334 INSIST(result
== ISC_R_SUCCESS
);
2335 dns_rdata_reset(&rdata
);
2338 * CNAME . means NXDOMAIN
2340 if (dns_name_equal(&cname
.cname
, dns_rootname
))
2341 return (DNS_RPZ_POLICY_NXDOMAIN
);
2343 if (dns_name_iswildcard(&cname
.cname
)) {
2345 * CNAME *. means NODATA
2347 if (dns_name_countlabels(&cname
.cname
) == 2)
2348 return (DNS_RPZ_POLICY_NODATA
);
2351 * A qname of www.evil.com and a policy of
2352 * *.evil.com CNAME *.garden.net
2354 * evil.com CNAME evil.com.garden.net
2356 if (dns_name_countlabels(&cname
.cname
) > 2)
2357 return (DNS_RPZ_POLICY_WILDCNAME
);
2361 * CNAME rpz-tcp-only. means "send truncated UDP responses."
2363 if (dns_name_equal(&cname
.cname
, &rpz
->tcp_only
))
2364 return (DNS_RPZ_POLICY_TCP_ONLY
);
2367 * CNAME rpz-drop. means "do not respond."
2369 if (dns_name_equal(&cname
.cname
, &rpz
->drop
))
2370 return (DNS_RPZ_POLICY_DROP
);
2373 * CNAME rpz-passthru. means "do not rewrite."
2375 if (dns_name_equal(&cname
.cname
, &rpz
->passthru
))
2376 return (DNS_RPZ_POLICY_PASSTHRU
);
2379 * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU
2381 if (selfname
!= NULL
&& dns_name_equal(&cname
.cname
, selfname
))
2382 return (DNS_RPZ_POLICY_PASSTHRU
);
2385 * Any other rdata gives a response consisting of the rdata.
2387 return (DNS_RPZ_POLICY_RECORD
);