xref: /minix/external/bsd/bind/dist/lib/dns/rpz.c (revision 00b67f09)
1 /*	$NetBSD: rpz.c,v 1.9 2015/07/08 17:28:59 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2011-2015  Internet Systems Consortium, Inc. ("ISC")
5  *
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.
9  *
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.
17  */
18 
19 /*! \file */
20 
21 #include <config.h>
22 
23 #include <isc/buffer.h>
24 #include <isc/mem.h>
25 #include <isc/net.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>
31 #include <isc/util.h>
32 
33 #include <dns/db.h>
34 #include <dns/fixedname.h>
35 #include <dns/log.h>
36 #include <dns/rdata.h>
37 #include <dns/rdataset.h>
38 #include <dns/rdatastruct.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 /*
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
89  */
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)
94 typedef struct {
95 	dns_rpz_cidr_word_t	w[DNS_RPZ_CIDR_WORDS];
96 } dns_rpz_cidr_key_t;
97 
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)
101 
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))))
105 
106 /*
107  * Get bit #n from the array of words of an IP address.
108  */
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))))
112 
113 /*
114  * A triplet of arrays of bits flagging the existence of
115  * client-IP, IP, and NSIP policy triggers.
116  */
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;
120 	dns_rpz_zbits_t		ip;
121 	dns_rpz_zbits_t		nsip;
122 };
123 
124 /*
125  * A CIDR or radix tree node.
126  */
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;
134 };
135 
136 /*
137  * A pair of arrays of bits flagging the existence of
138  * QNAME and NSDNAME policy triggers.
139  */
140 typedef struct dns_rpz_nm_zbits dns_rpz_nm_zbits_t;
141 struct dns_rpz_nm_zbits {
142 	dns_rpz_zbits_t		qname;
143 	dns_rpz_zbits_t		ns;
144 };
145 
146 /*
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.
150  */
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;
155 };
156 
157 #if 0
158 /*
159  * Catch a name while debugging.
160  */
161 static void
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;
165 
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);
173 	}
174 }
175 #endif
176 
177 const char *
dns_rpz_type2str(dns_rpz_type_t type)178 dns_rpz_type2str(dns_rpz_type_t type) {
179 	switch (type) {
180 	case DNS_RPZ_TYPE_CLIENT_IP:
181 		return ("CLIENT-IP");
182 	case DNS_RPZ_TYPE_QNAME:
183 		return ("QNAME");
184 	case DNS_RPZ_TYPE_IP:
185 		return ("IP");
186 	case DNS_RPZ_TYPE_NSIP:
187 		return ("NSIP");
188 	case DNS_RPZ_TYPE_NSDNAME:
189 		return ("NSDNAME");
190 	case DNS_RPZ_TYPE_BAD:
191 		break;
192 	}
193 	FATAL_ERROR(__FILE__, __LINE__, "impossible rpz type %d", type);
194 	return ("impossible");
195 }
196 
197 dns_rpz_policy_t
dns_rpz_str2policy(const char * str)198 dns_rpz_str2policy(const char *str) {
199 	static struct {
200 		const char *str;
201 		dns_rpz_policy_t policy;
202 	} tbl[] = {
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 */
212 	};
213 	unsigned int n;
214 
215 	if (str == NULL)
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);
220 	}
221 	return (DNS_RPZ_POLICY_ERROR);
222 }
223 
224 const char *
dns_rpz_policy2str(dns_rpz_policy_t policy)225 dns_rpz_policy2str(dns_rpz_policy_t policy) {
226 	const char *str;
227 
228 	switch (policy) {
229 	case DNS_RPZ_POLICY_PASSTHRU:
230 		str = "PASSTHRU";
231 		break;
232 	case DNS_RPZ_POLICY_DROP:
233 		str = "DROP";
234 		break;
235 	case DNS_RPZ_POLICY_TCP_ONLY:
236 		str = "TCP-ONLY";
237 		break;
238 	case DNS_RPZ_POLICY_NXDOMAIN:
239 		str = "NXDOMAIN";
240 		break;
241 	case DNS_RPZ_POLICY_NODATA:
242 		str = "NODATA";
243 		break;
244 	case DNS_RPZ_POLICY_RECORD:
245 		str = "Local-Data";
246 		break;
247 	case DNS_RPZ_POLICY_CNAME:
248 	case DNS_RPZ_POLICY_WILDCNAME:
249 		str = "CNAME";
250 		break;
251 	case DNS_RPZ_POLICY_MISS:
252 		str = "MISS";
253 		break;
254 	default:
255 		str = "";
256 		POST(str);
257 		INSIST(0);
258 	}
259 	return (str);
260 }
261 
262 /*
263  * Return the bit number of the highest set bit in 'zbit'.
264  * (for example, 0x01 returns 0, 0xFF returns 7, etc.)
265  */
266 static int
zbit_to_num(dns_rpz_zbits_t zbit)267 zbit_to_num(dns_rpz_zbits_t zbit) {
268 	dns_rpz_num_t rpz_num;
269 
270 	REQUIRE(zbit != 0);
271 	rpz_num = 0;
272 #if DNS_RPZ_MAX_ZONES > 32
273 	if ((zbit & 0xffffffff00000000L) != 0) {
274 		zbit >>= 32;
275 		rpz_num += 32;
276 	}
277 #endif
278 	if ((zbit & 0xffff0000) != 0) {
279 		zbit >>= 16;
280 		rpz_num += 16;
281 	}
282 	if ((zbit & 0xff00) != 0) {
283 		zbit >>= 8;
284 		rpz_num += 8;
285 	}
286 	if ((zbit & 0xf0) != 0) {
287 		zbit >>= 4;
288 		rpz_num += 4;
289 	}
290 	if ((zbit & 0xc) != 0) {
291 		zbit >>= 2;
292 		rpz_num += 2;
293 	}
294 	if ((zbit & 2) != 0)
295 		++rpz_num;
296 	return (rpz_num);
297 }
298 
299 /*
300  * Make a set of bit masks given one or more bits and their type.
301  */
302 static void
make_addr_set(dns_rpz_addr_zbits_t * tgt_set,dns_rpz_zbits_t zbits,dns_rpz_type_t type)303 make_addr_set(dns_rpz_addr_zbits_t *tgt_set, dns_rpz_zbits_t zbits,
304 	      dns_rpz_type_t type)
305 {
306 	switch (type) {
307 	case DNS_RPZ_TYPE_CLIENT_IP:
308 		tgt_set->client_ip = zbits;
309 		tgt_set->ip = 0;
310 		tgt_set->nsip = 0;
311 		break;
312 	case DNS_RPZ_TYPE_IP:
313 		tgt_set->client_ip = 0;
314 		tgt_set->ip = zbits;
315 		tgt_set->nsip = 0;
316 		break;
317 	case DNS_RPZ_TYPE_NSIP:
318 		tgt_set->client_ip = 0;
319 		tgt_set->ip = 0;
320 		tgt_set->nsip = zbits;
321 		break;
322 	default:
323 		INSIST(0);
324 		break;
325 	}
326 }
327 
328 static void
make_nm_set(dns_rpz_nm_zbits_t * tgt_set,dns_rpz_num_t rpz_num,dns_rpz_type_t type)329 make_nm_set(dns_rpz_nm_zbits_t *tgt_set,
330 	    dns_rpz_num_t rpz_num, dns_rpz_type_t type)
331 {
332 	switch (type) {
333 	case DNS_RPZ_TYPE_QNAME:
334 		tgt_set->qname = DNS_RPZ_ZBIT(rpz_num);
335 		tgt_set->ns = 0;
336 		break;
337 	case DNS_RPZ_TYPE_NSDNAME:
338 		tgt_set->qname = 0;
339 		tgt_set->ns = DNS_RPZ_ZBIT(rpz_num);
340 		break;
341 	default:
342 		INSIST(0);
343 		break;
344 	}
345 }
346 
347 /*
348  * Mark a node and all of its parents as having client-IP, IP, or NSIP data
349  */
350 static void
set_sum_pair(dns_rpz_cidr_node_t * cnode)351 set_sum_pair(dns_rpz_cidr_node_t *cnode) {
352 	dns_rpz_cidr_node_t *child;
353 	dns_rpz_addr_zbits_t sum;
354 
355 	do {
356 		sum = cnode->set;
357 
358 		child = cnode->child[0];
359 		if (child != NULL) {
360 			sum.client_ip |= child->sum.client_ip;
361 			sum.ip |= child->sum.ip;
362 			sum.nsip |= child->sum.nsip;
363 		}
364 
365 		child = cnode->child[1];
366 		if (child != NULL) {
367 			sum.client_ip |= child->sum.client_ip;
368 			sum.ip |= child->sum.ip;
369 			sum.nsip |= child->sum.nsip;
370 		}
371 
372 		if (cnode->sum.client_ip == sum.client_ip &&
373 		    cnode->sum.ip == sum.ip &&
374 		    cnode->sum.nsip == sum.nsip)
375 			break;
376 		cnode->sum = sum;
377 		cnode = cnode->parent;
378 	} while (cnode != NULL);
379 }
380 
381 /* Caller must hold rpzs->maint_lock */
382 static void
fix_qname_skip_recurse(dns_rpz_zones_t * rpzs)383 fix_qname_skip_recurse(dns_rpz_zones_t *rpzs) {
384 	dns_rpz_zbits_t mask;
385 
386 	/*
387 	 * qname_wait_recurse and qname_skip_recurse are used to
388 	 * implement the "qname-wait-recurse" config option.
389 	 *
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().
396 	 *
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
401 	 * for the rest.
402 	 *
403 	 * (1) The ARM says:
404 	 *
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.
412 	 *
413 	 * Let's consider the following:
414 	 *
415 	 *     zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 |
416 	 *		    rpzs->have.nsdname |
417 	 *		    rpzs->have.nsipv4 | rpzs->have.nsipv6);
418 	 *
419 	 * zbits_req now contains bits set for zones which require
420 	 * recursion.
421 	 *
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.
426 	 *
427 	 * So mapping this, examples:
428 	 *
429 	 * zbits_req = 0b000  mask = 0xffffffff (no zones have to wait for
430 	 *					 recursion)
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
434 	 *					 to wait)
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)
439 	 *
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.
443 	 *
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.
450 	 */
451 
452 	/*
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.
456 	 */
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;
460 
461 	if (rpzs->p.qname_wait_recurse) {
462 		mask = 0;
463 	} else {
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;
468 
469 		/*
470 		 * Get the masks of zones with policies that
471 		 * do/don't require recursion
472 		 */
473 
474 		zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 |
475 			     rpzs->have.nsdname |
476 			     rpzs->have.nsipv4 | rpzs->have.nsipv6);
477 		zbits_notreq = (rpzs->have.client_ip | rpzs->have.qname);
478 
479 		if (zbits_req == 0) {
480 			mask = DNS_RPZ_ALL_ZBITS;
481 			goto set;
482 		}
483 
484 		/*
485 		 * req_mask is a mask covering used bits in
486 		 * zbits_req. (For instance, 0b1 => 0b1, 0b101 => 0b111,
487 		 * 0b11010101 => 0b11111111).
488 		 */
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;
497 #endif
498 
499 		/*
500 		 * There's no point in skipping recursion for a later
501 		 * zone if it is required in a previous zone.
502 		 */
503 		if ((zbits_notreq & req_mask) == 0) {
504 			mask = 0;
505 			goto set;
506 		}
507 
508 		/*
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)
516 		 */
517 		mask = ~(zbits_req | -zbits_req);
518 
519 		/*
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.
525 		 *
526 		 * Locate the least significant 0 bit in the mask (for
527 		 * instance, 0xff => 0x100)...
528 		 */
529 		mask2 = (mask << 1) & ~mask;
530 
531 		/*
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...
535 		 */
536 		mask2 |= 1;
537 
538 		/* Clear any bits *not* in zbits_notreq... */
539 		mask2 &= zbits_notreq;
540 
541 		/* And merge the result into the skip-recursion mask */
542 		mask |= mask2;
543 	}
544 
545  set:
546 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB,
547 		      DNS_RPZ_DEBUG_QUIET,
548 		      "computed RPZ qname_skip_recurse mask=0x%llx",
549 		      (isc_uint64_t) mask);
550 	rpzs->have.qname_skip_recurse = mask;
551 }
552 
553 static void
adj_trigger_cnt(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_rpz_type_t rpz_type,const dns_rpz_cidr_key_t * tgt_ip,dns_rpz_prefix_t tgt_prefix,isc_boolean_t inc)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,
557 		isc_boolean_t inc)
558 {
559 	dns_rpz_trigger_counter_t *cnt;
560 	dns_rpz_zbits_t *have;
561 
562 	switch (rpz_type) {
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;
568 		} else {
569 			cnt = &rpzs->triggers[rpz_num].client_ipv6;
570 			have = &rpzs->have.client_ipv6;
571 		}
572 		break;
573 	case DNS_RPZ_TYPE_QNAME:
574 		cnt = &rpzs->triggers[rpz_num].qname;
575 		have = &rpzs->have.qname;
576 		break;
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;
582 		} else {
583 			cnt = &rpzs->triggers[rpz_num].ipv6;
584 			have = &rpzs->have.ipv6;
585 		}
586 		break;
587 	case DNS_RPZ_TYPE_NSDNAME:
588 		cnt = &rpzs->triggers[rpz_num].nsdname;
589 		have = &rpzs->have.nsdname;
590 		break;
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;
596 		} else {
597 			cnt = &rpzs->triggers[rpz_num].nsipv6;
598 			have = &rpzs->have.nsipv6;
599 		}
600 		break;
601 	default:
602 		INSIST(0);
603 	}
604 
605 	if (inc) {
606 		if (++*cnt == 1) {
607 			*have |= DNS_RPZ_ZBIT(rpz_num);
608 			fix_qname_skip_recurse(rpzs);
609 		}
610 	} else {
611 		REQUIRE(*cnt != 0);
612 		if (--*cnt == 0) {
613 			*have &= ~DNS_RPZ_ZBIT(rpz_num);
614 			fix_qname_skip_recurse(rpzs);
615 		}
616 	}
617 }
618 
619 static dns_rpz_cidr_node_t *
new_node(dns_rpz_zones_t * rpzs,const dns_rpz_cidr_key_t * ip,dns_rpz_prefix_t prefix,const dns_rpz_cidr_node_t * child)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)
623 {
624 	dns_rpz_cidr_node_t *new;
625 	int i, words, wlen;
626 
627 	new = isc_mem_get(rpzs->mctx, sizeof(*new));
628 	if (new == NULL)
629 		return (NULL);
630 	memset(new, 0, sizeof(*new));
631 
632 	if (child != NULL)
633 		new->sum = child->sum;
634 
635 	new->prefix = prefix;
636 	words = prefix / DNS_RPZ_CIDR_WORD_BITS;
637 	wlen = prefix % DNS_RPZ_CIDR_WORD_BITS;
638 	i = 0;
639 	while (i < words) {
640 		new->ip.w[i] = ip->w[i];
641 		++i;
642 	}
643 	if (wlen != 0) {
644 		new->ip.w[i] = ip->w[i] & DNS_RPZ_WORD_MASK(wlen);
645 		++i;
646 	}
647 	while (i < DNS_RPZ_CIDR_WORDS)
648 		new->ip.w[i++] = 0;
649 
650 	return (new);
651 }
652 
653 static void
badname(int level,dns_name_t * name,const char * str1,const char * str2)654 badname(int level, dns_name_t *name, const char *str1, const char *str2) {
655 	char namebuf[DNS_NAME_FORMATSIZE];
656 
657 	/*
658 	 * bin/tests/system/rpz/tests.sh looks for "invalid rpz".
659 	 */
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);
667 	}
668 }
669 
670 /*
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
673  * policy zone.
674  */
675 static isc_result_t
ip2name(const dns_rpz_cidr_key_t * tgt_ip,dns_rpz_prefix_t tgt_prefix,dns_name_t * base_name,dns_name_t * ip_name)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)
678 {
679 #ifndef INET6_ADDRSTRLEN
680 #define INET6_ADDRSTRLEN 46
681 #endif
682 	int w[DNS_RPZ_CIDR_WORDS*2];
683 	char str[1+8+1+INET6_ADDRSTRLEN+1];
684 	isc_buffer_t buffer;
685 	isc_result_t result;
686 	isc_boolean_t zeros;
687 	int i, n, len;
688 
689 	if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) {
690 		len = snprintf(str, sizeof(str), "%d.%d.%d.%d.%d",
691 			       tgt_prefix - 96,
692 			       tgt_ip->w[3] & 0xff,
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);
698 	} else {
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)
701 				    & 0xffff);
702 			w[i*2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS-1-i] & 0xffff;
703 		}
704 		zeros = ISC_FALSE;
705 		len = snprintf(str, sizeof(str), "%d", tgt_prefix);
706 		if (len == -1)
707 			return (ISC_R_FAILURE);
708 		i = 0;
709 		while (i < DNS_RPZ_CIDR_WORDS * 2) {
710 			if (w[i] != 0 || zeros ||
711 			    i >= DNS_RPZ_CIDR_WORDS * 2 - 1 ||
712 			    w[i+1] != 0) {
713 				INSIST((size_t)len <= sizeof(str));
714 				n = snprintf(&str[len], sizeof(str) - len,
715 					     ".%x", w[i++]);
716 				if (n < 0)
717 					return (ISC_R_FAILURE);
718 				len += n;
719 			} else {
720 				zeros = ISC_TRUE;
721 				INSIST((size_t)len <= sizeof(str));
722 				n = snprintf(&str[len], sizeof(str) - len,
723 					     ".zz");
724 				if (n < 0)
725 					return (ISC_R_FAILURE);
726 				len += n;
727 				i += 2;
728 				while (i < DNS_RPZ_CIDR_WORDS * 2 && w[i] == 0)
729 					++i;
730 			}
731 			if (len >= (int)sizeof(str))
732 				return (ISC_R_FAILURE);
733 		}
734 	}
735 
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);
739 	return (result);
740 }
741 
742 /*
743  * Determine the type a of a name in a response policy zone.
744  */
745 static dns_rpz_type_t
type_from_name(dns_rpz_zone_t * rpz,dns_name_t * name)746 type_from_name(dns_rpz_zone_t *rpz, dns_name_t *name) {
747 
748 	if (dns_name_issubdomain(name, &rpz->ip))
749 		return (DNS_RPZ_TYPE_IP);
750 
751 	if (dns_name_issubdomain(name, &rpz->client_ip))
752 		return (DNS_RPZ_TYPE_CLIENT_IP);
753 
754 #ifdef ENABLE_RPZ_NSIP
755 	if (dns_name_issubdomain(name, &rpz->nsip))
756 		return (DNS_RPZ_TYPE_NSIP);
757 #endif
758 
759 #ifdef ENABLE_RPZ_NSDNAME
760 	if (dns_name_issubdomain(name, &rpz->nsdname))
761 		return (DNS_RPZ_TYPE_NSDNAME);
762 #endif
763 
764 	return (DNS_RPZ_TYPE_QNAME);
765 }
766 
767 /*
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
770  * data.
771  */
772 static isc_result_t
name2ipkey(int log_level,const dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_rpz_type_t rpz_type,dns_name_t * src_name,dns_rpz_cidr_key_t * tgt_ip,dns_rpz_prefix_t * tgt_prefix,dns_rpz_addr_zbits_t * new_set)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)
778 {
779 	dns_rpz_zone_t *rpz;
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;
785 	char *cp2;
786 	int ip_labels;
787 	dns_rpz_prefix_t prefix;
788 	unsigned long prefix_num, l;
789 	isc_result_t result;
790 	int i;
791 
792 	REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones);
793 	rpz = rpzs->zones[rpz_num];
794 	REQUIRE(rpz != NULL);
795 
796 	make_addr_set(new_set, DNS_RPZ_ZBIT(rpz_num), rpz_type);
797 
798 	ip_labels = dns_name_countlabels(src_name);
799 	if (rpz_type == DNS_RPZ_TYPE_QNAME)
800 		ip_labels -= dns_name_countlabels(&rpz->origin);
801 	else
802 		ip_labels -= dns_name_countlabels(&rpz->nsdname);
803 	if (ip_labels < 2) {
804 		badname(log_level, src_name, "; too short", "");
805 		return (ISC_R_FAILURE);
806 	}
807 	dns_name_init(&ip_name, ip_name_offsets);
808 	dns_name_getlabelsequence(src_name, 0, ip_labels, &ip_name);
809 
810 	/*
811 	 * Get text for the IP address
812 	 */
813 	dns_name_format(&ip_name, ip_str, sizeof(ip_str));
814 	end = &ip_str[strlen(ip_str)+1];
815 	prefix_str = ip_str;
816 
817 	prefix_num = strtoul(prefix_str, &cp2, 10);
818 	if (*cp2 != '.') {
819 		badname(log_level, src_name,
820 			"; invalid leading prefix length", "");
821 		return (ISC_R_FAILURE);
822 	}
823 	*cp2 = '\0';
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);
828 	}
829 	cp = cp2+1;
830 
831 	if (--ip_labels == 4 && !strchr(cp, 'z')) {
832 		/*
833 		 * Convert an IPv4 address
834 		 * from the form "prefix.z.y.x.w"
835 		 */
836 		if (prefix_num > 32U) {
837 			badname(log_level, src_name,
838 				"; invalid IPv4 prefix length of ", prefix_str);
839 			return (ISC_R_FAILURE);
840 		}
841 		prefix_num += 96;
842 		*tgt_prefix = (dns_rpz_prefix_t)prefix_num;
843 		tgt_ip->w[0] = 0;
844 		tgt_ip->w[1] = 0;
845 		tgt_ip->w[2] = ADDR_V4MAPPED;
846 		tgt_ip->w[3] = 0;
847 		for (i = 0; i < 32; i += 8) {
848 			l = strtoul(cp, &cp2, 10);
849 			if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) {
850 				if (*cp2 == '.')
851 					*cp2 = '\0';
852 				badname(log_level, src_name,
853 					"; invalid IPv4 octet ", cp);
854 				return (ISC_R_FAILURE);
855 			}
856 			tgt_ip->w[3] |= l << i;
857 			cp = cp2 + 1;
858 		}
859 	} else {
860 		/*
861 		 * Convert a text IPv6 address.
862 		 */
863 		*tgt_prefix = (dns_rpz_prefix_t)prefix_num;
864 		for (i = 0;
865 		     ip_labels > 0 && i < DNS_RPZ_CIDR_WORDS * 2;
866 		     ip_labels--) {
867 			if (cp[0] == 'z' && cp[1] == 'z' &&
868 			    (cp[2] == '.' || cp[2] == '\0') &&
869 			    i <= 6) {
870 				do {
871 					if ((i & 1) == 0)
872 					    tgt_ip->w[3-i/2] = 0;
873 					++i;
874 				} while (ip_labels + i <= 8);
875 				cp += 3;
876 			} else {
877 				l = strtoul(cp, &cp2, 16);
878 				if (l > 0xffffu ||
879 				    (*cp2 != '.' && *cp2 != '\0')) {
880 					if (*cp2 == '.')
881 					    *cp2 = '\0';
882 					badname(log_level, src_name,
883 						"; invalid IPv6 word ", cp);
884 					return (ISC_R_FAILURE);
885 				}
886 				if ((i & 1) == 0)
887 					tgt_ip->w[3-i/2] = l;
888 				else
889 					tgt_ip->w[3-i/2] |= l << 16;
890 				i++;
891 				cp = cp2 + 1;
892 			}
893 		}
894 	}
895 	if (cp != end) {
896 		badname(log_level, src_name, "", "");
897 		return (ISC_R_FAILURE);
898 	}
899 
900 	/*
901 	 * Check for 1s after the prefix length.
902 	 */
903 	prefix = (dns_rpz_prefix_t)prefix_num;
904 	while (prefix < DNS_RPZ_CIDR_KEY_BITS) {
905 		dns_rpz_cidr_word_t aword;
906 
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);
913 		}
914 		prefix -= i;
915 		prefix += DNS_RPZ_CIDR_WORD_BITS;
916 	}
917 
918 	/*
919 	 * XXXMUKS: Should the following check be enabled in a
920 	 * production build?  It can be expensive for large IP zones
921 	 * from 3rd parties.
922 	 */
923 
924 	/*
925 	 * Convert the address back to a canonical domain name
926 	 * to ensure that the original name is in canonical form.
927 	 */
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);
934 	}
935 
936 	return (ISC_R_SUCCESS);
937 }
938 
939 /*
940  * Get trigger name and data bits for adding or deleting summary NSDNAME
941  * or QNAME data.
942  */
943 static void
name2data(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_rpz_type_t rpz_type,const dns_name_t * src_name,dns_name_t * trig_name,dns_rpz_nm_data_t * new_data)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)
947 {
948 	dns_rpz_zone_t *rpz;
949 	dns_offsets_t tmp_name_offsets;
950 	dns_name_t tmp_name;
951 	unsigned int prefix_len, n;
952 
953 	REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones);
954 	rpz = rpzs->zones[rpz_num];
955 	REQUIRE(rpz != NULL);
956 
957 	/*
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.
961 	 */
962 	if (dns_name_iswildcard(src_name)) {
963 		prefix_len = 1;
964 		memset(&new_data->set, 0, sizeof(new_data->set));
965 		make_nm_set(&new_data->wild, rpz_num, rpz_type);
966 	} else {
967 		prefix_len = 0;
968 		make_nm_set(&new_data->set, rpz_num, rpz_type);
969 		memset(&new_data->wild, 0, sizeof(new_data->wild));
970 	}
971 
972 	dns_name_init(&tmp_name, tmp_name_offsets);
973 	n = dns_name_countlabels(src_name);
974 	n -= prefix_len;
975 	if (rpz_type == DNS_RPZ_TYPE_QNAME)
976 		n -= dns_name_countlabels(&rpz->origin);
977 	else
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);
981 }
982 
983 /*
984  * Find the first differing bit in a key (IP address) word.
985  */
986 static inline int
ffs_keybit(dns_rpz_cidr_word_t w)987 ffs_keybit(dns_rpz_cidr_word_t w) {
988 	int bit;
989 
990 	bit = DNS_RPZ_CIDR_WORD_BITS-1;
991 	if ((w & 0xffff0000) != 0) {
992 		w >>= 16;
993 		bit -= 16;
994 	}
995 	if ((w & 0xff00) != 0) {
996 		w >>= 8;
997 		bit -= 8;
998 	}
999 	if ((w & 0xf0) != 0) {
1000 		w >>= 4;
1001 		bit -= 4;
1002 	}
1003 	if ((w & 0xc) != 0) {
1004 		w >>= 2;
1005 		bit -= 2;
1006 	}
1007 	if ((w & 2) != 0)
1008 		--bit;
1009 	return (bit);
1010 }
1011 
1012 /*
1013  * Find the first differing bit in two keys (IP addresses).
1014  */
1015 static int
diff_keys(const dns_rpz_cidr_key_t * key1,dns_rpz_prefix_t prefix1,const dns_rpz_cidr_key_t * key2,dns_rpz_prefix_t prefix2)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)
1018 {
1019 	dns_rpz_cidr_word_t delta;
1020 	dns_rpz_prefix_t maxbit, bit;
1021 	int i;
1022 
1023 	bit = 0;
1024 	maxbit = ISC_MIN(prefix1, prefix2);
1025 
1026 	/*
1027 	 * find the first differing words
1028 	 */
1029 	for (i = 0;
1030 	     bit < maxbit;
1031 	     i++, bit += DNS_RPZ_CIDR_WORD_BITS) {
1032 		delta = key1->w[i] ^ key2->w[i];
1033 		if (delta != 0) {
1034 			bit += ffs_keybit(delta);
1035 			break;
1036 		}
1037 	}
1038 	return (ISC_MIN(bit, maxbit));
1039 }
1040 
1041 /*
1042  * Given a hit while searching the radix trees,
1043  * clear all bits for higher numbered zones.
1044  */
1045 static inline dns_rpz_zbits_t
trim_zbits(dns_rpz_zbits_t zbits,dns_rpz_zbits_t found)1046 trim_zbits(dns_rpz_zbits_t zbits, dns_rpz_zbits_t found) {
1047 	dns_rpz_zbits_t x;
1048 
1049 	/*
1050 	 * Isolate the first or smallest numbered hit bit.
1051 	 * Make a mask of that bit and all smaller numbered bits.
1052 	 */
1053 	x = zbits & found;
1054 	x &= (~x + 1);
1055 	x = (x << 1) - 1;
1056 	return (zbits &= x);
1057 }
1058 
1059 /*
1060  * Search a radix tree for an IP address for ordinary lookup
1061  *	or for a CIDR block adding or deleting an entry
1062  *
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
1066  */
1067 static isc_result_t
search(dns_rpz_zones_t * rpzs,const dns_rpz_cidr_key_t * tgt_ip,dns_rpz_prefix_t tgt_prefix,const dns_rpz_addr_zbits_t * tgt_set,isc_boolean_t create,dns_rpz_cidr_node_t ** found)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)
1072 {
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;
1078 
1079 	set = *tgt_set;
1080 	find_result = ISC_R_NOTFOUND;
1081 	*found = NULL;
1082 	cur = rpzs->cidr;
1083 	parent = NULL;
1084 	cur_num = 0;
1085 	for (;;) {
1086 		if (cur == NULL) {
1087 			/*
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.
1091 			 */
1092 			if (!create)
1093 				return (find_result);
1094 			child = new_node(rpzs, tgt_ip, tgt_prefix, NULL);
1095 			if (child == NULL)
1096 				return (ISC_R_NOMEMORY);
1097 			if (parent == NULL)
1098 				rpzs->cidr = child;
1099 			else
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);
1106 			*found = child;
1107 			return (ISC_R_SUCCESS);
1108 		}
1109 
1110 		if ((cur->sum.client_ip & set.client_ip) == 0 &&
1111 		    (cur->sum.ip & set.ip) == 0 &&
1112 		    (cur->sum.nsip & set.nsip) == 0) {
1113 			/*
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.
1117 			 *
1118 			 * If we are adding, continue down to eventually add
1119 			 * a node and mark/put this node in the correct tree.
1120 			 */
1121 			if (!create)
1122 				return (find_result);
1123 		}
1124 
1125 		dbit = diff_keys(tgt_ip, tgt_prefix, &cur->ip, cur->prefix);
1126 		/*
1127 		 * dbit <= tgt_prefix and dbit <= cur->prefix always.
1128 		 * We are finished searching if we matched all of the target.
1129 		 */
1130 		if (dbit == tgt_prefix) {
1131 			if (tgt_prefix == cur->prefix) {
1132 				/*
1133 				 * The node's key matches the target exactly.
1134 				 */
1135 				if ((cur->set.client_ip & set.client_ip) != 0 ||
1136 				    (cur->set.ip & set.ip) != 0 ||
1137 				    (cur->set.nsip & set.nsip) != 0) {
1138 					/*
1139 					 * It is the answer if it has data.
1140 					 */
1141 					*found = cur;
1142 					if (create) {
1143 					    find_result = ISC_R_EXISTS;
1144 					} else {
1145 					    find_result = ISC_R_SUCCESS;
1146 					}
1147 				} else if (create) {
1148 					/*
1149 					 * The node lacked relevant data,
1150 					 * but will have it now.
1151 					 */
1152 					cur->set.client_ip |= tgt_set->client_ip;
1153 					cur->set.ip |= tgt_set->ip;
1154 					cur->set.nsip |= tgt_set->nsip;
1155 					set_sum_pair(cur);
1156 					*found = cur;
1157 					find_result = ISC_R_SUCCESS;
1158 				}
1159 				return (find_result);
1160 			}
1161 
1162 			/*
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.
1166 			 */
1167 			if (!create)
1168 				return (find_result);
1169 
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;
1174 			if (parent == NULL)
1175 				rpzs->cidr = new_parent;
1176 			else
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);
1185 		}
1186 
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) {
1191 				/*
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.
1196 				 */
1197 				find_result = DNS_R_PARTIALMATCH;
1198 				*found = cur;
1199 				set.client_ip = trim_zbits(set.client_ip,
1200 							   cur->set.client_ip);
1201 				set.ip = trim_zbits(set.ip,
1202 						    cur->set.ip);
1203 				set.nsip = trim_zbits(set.nsip,
1204 						      cur->set.nsip);
1205 			}
1206 			parent = cur;
1207 			cur_num = DNS_RPZ_IP_BIT(tgt_ip, dbit);
1208 			cur = cur->child[cur_num];
1209 			continue;
1210 		}
1211 
1212 
1213 		/*
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
1218 		 */
1219 		if (!create)
1220 			return (find_result);
1221 
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);
1229 		}
1230 		new_parent->parent = parent;
1231 		if (parent == NULL)
1232 			rpzs->cidr = new_parent;
1233 		else
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);
1242 		*found = sibling;
1243 		return (ISC_R_SUCCESS);
1244 	}
1245 }
1246 
1247 /*
1248  * Add an IP address to the radix tree.
1249  */
1250 static isc_result_t
add_cidr(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_rpz_type_t rpz_type,dns_name_t * src_name)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)
1253 {
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;
1259 
1260 	result = name2ipkey(DNS_RPZ_ERROR_LEVEL, rpzs, rpz_num, rpz_type,
1261 			    src_name, &tgt_ip, &tgt_prefix, &set);
1262 	/*
1263 	 * Log complaints about bad owner names but let the zone load.
1264 	 */
1265 	if (result != ISC_R_SUCCESS)
1266 		return (ISC_R_SUCCESS);
1267 
1268 	result = search(rpzs, &tgt_ip, tgt_prefix, &set, ISC_TRUE, &found);
1269 	if (result != ISC_R_SUCCESS) {
1270 		char namebuf[DNS_NAME_FORMATSIZE];
1271 
1272 		/*
1273 		 * Do not worry if the radix tree already exists,
1274 		 * because diff_apply() likes to add nodes before deleting.
1275 		 */
1276 		if (result == ISC_R_EXISTS)
1277 			return (ISC_R_SUCCESS);
1278 
1279 		/*
1280 		 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
1281 		 */
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));
1287 		return (result);
1288 	}
1289 
1290 	adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix, ISC_TRUE);
1291 	return (result);
1292 }
1293 
1294 static isc_result_t
add_nm(dns_rpz_zones_t * rpzs,dns_name_t * trig_name,const dns_rpz_nm_data_t * new_data)1295 add_nm(dns_rpz_zones_t *rpzs, dns_name_t *trig_name,
1296 	 const dns_rpz_nm_data_t *new_data)
1297 {
1298 	dns_rbtnode_t *nmnode;
1299 	dns_rpz_nm_data_t *nm_data;
1300 	isc_result_t result;
1301 
1302 	nmnode = NULL;
1303 	result = dns_rbt_addnode(rpzs->rbt, trig_name, &nmnode);
1304 	switch (result) {
1305 	case ISC_R_SUCCESS:
1306 	case ISC_R_EXISTS:
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);
1315 		}
1316 		break;
1317 	default:
1318 		return (result);
1319 	}
1320 
1321 	/*
1322 	 * Do not count bits that are already present
1323 	 */
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);
1329 
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);
1335 }
1336 
1337 static isc_result_t
add_name(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_rpz_type_t rpz_type,dns_name_t * src_name)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)
1340 {
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;
1345 
1346 	/*
1347 	 * No need for a summary database of names with only 1 policy zone.
1348 	 */
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);
1352 	}
1353 
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);
1357 
1358 	result = add_nm(rpzs, trig_name, &new_data);
1359 
1360 	/*
1361 	 * Do not worry if the node already exists,
1362 	 * because diff_apply() likes to add nodes before deleting.
1363 	 */
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);
1368 	return (result);
1369 }
1370 
1371 /*
1372  * Callback to free the data for a node in the summary RBT database.
1373  */
1374 static void
rpz_node_deleter(void * nm_data,void * mctx)1375 rpz_node_deleter(void *nm_data, void *mctx) {
1376 	isc_mem_put(mctx, nm_data, sizeof(dns_rpz_nm_data_t));
1377 }
1378 
1379 /*
1380  * Get ready for a new set of policy zones.
1381  */
1382 isc_result_t
dns_rpz_new_zones(dns_rpz_zones_t ** rpzsp,isc_mem_t * mctx)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;
1386 
1387 	REQUIRE(rpzsp != NULL && *rpzsp == NULL);
1388 
1389 	*rpzsp = NULL;
1390 
1391 	new = isc_mem_get(mctx, sizeof(*new));
1392 	if (new == NULL)
1393 		return (ISC_R_NOMEMORY);
1394 	memset(new, 0, sizeof(*new));
1395 
1396 	result = isc_rwlock_init(&new->search_lock, 0, 0);
1397 	if (result != ISC_R_SUCCESS) {
1398 		isc_mem_put(mctx, new, sizeof(*new));
1399 		return (result);
1400 	}
1401 
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));
1406 		return (result);
1407 	}
1408 
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));
1414 		return (result);
1415 	}
1416 
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));
1424 		return (result);
1425 	}
1426 
1427 	isc_mem_attach(mctx, &new->mctx);
1428 
1429 	*rpzsp = new;
1430 	return (ISC_R_SUCCESS);
1431 }
1432 
1433 /*
1434  * Free the radix tree of a response policy database.
1435  */
1436 static void
cidr_free(dns_rpz_zones_t * rpzs)1437 cidr_free(dns_rpz_zones_t *rpzs) {
1438 	dns_rpz_cidr_node_t *cur, *child, *parent;
1439 
1440 	cur = rpzs->cidr;
1441 	while (cur != NULL) {
1442 		/* Depth first. */
1443 		child = cur->child[0];
1444 		if (child != NULL) {
1445 			cur = child;
1446 			continue;
1447 		}
1448 		child = cur->child[1];
1449 		if (child != NULL) {
1450 			cur = child;
1451 			continue;
1452 		}
1453 
1454 		/* Delete this leaf and go up. */
1455 		parent = cur->parent;
1456 		if (parent == NULL)
1457 			rpzs->cidr = NULL;
1458 		else
1459 			parent->child[parent->child[1] == cur] = NULL;
1460 		isc_mem_put(rpzs->mctx, cur, sizeof(*cur));
1461 		cur = parent;
1462 	}
1463 }
1464 
1465 /*
1466  * Discard a response policy zone blob
1467  * before discarding the overall rpz structure.
1468  */
1469 static void
rpz_detach(dns_rpz_zone_t ** rpzp,dns_rpz_zones_t * rpzs)1470 rpz_detach(dns_rpz_zone_t **rpzp, dns_rpz_zones_t *rpzs) {
1471 	dns_rpz_zone_t *rpz;
1472 	unsigned int refs;
1473 
1474 	rpz = *rpzp;
1475 	*rpzp = NULL;
1476 	isc_refcount_decrement(&rpz->refs, &refs);
1477 	if (refs != 0)
1478 		return;
1479 	isc_refcount_destroy(&rpz->refs);
1480 
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);
1499 
1500 	isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
1501 }
1502 
1503 void
dns_rpz_attach_rpzs(dns_rpz_zones_t * rpzs,dns_rpz_zones_t ** rpzsp)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);
1507 	*rpzsp = rpzs;
1508 }
1509 
1510 /*
1511  * Forget a view's policy zones.
1512  */
1513 void
dns_rpz_detach_rpzs(dns_rpz_zones_t ** rpzsp)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;
1518 	unsigned int refs;
1519 
1520 	REQUIRE(rpzsp != NULL);
1521 	rpzs = *rpzsp;
1522 	REQUIRE(rpzs != NULL);
1523 
1524 	*rpzsp = NULL;
1525 	isc_refcount_decrement(&rpzs->refs, &refs);
1526 
1527 	/*
1528 	 * Forget the last of view's rpz machinery after the last reference.
1529 	 */
1530 	if (refs == 0) {
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;
1534 			if (rpz != NULL)
1535 				rpz_detach(&rpz, rpzs);
1536 		}
1537 
1538 		cidr_free(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));
1544 	}
1545 }
1546 
1547 /*
1548  * Create empty summary database to load one zone.
1549  * The RBTDB write tree lock must be held.
1550  */
1551 isc_result_t
dns_rpz_beginload(dns_rpz_zones_t ** load_rpzsp,dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num)1552 dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp,
1553 		  dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num)
1554 {
1555 	dns_rpz_zones_t *load_rpzs;
1556 	dns_rpz_zone_t *rpz;
1557 	dns_rpz_zbits_t tgt;
1558 	isc_result_t result;
1559 
1560 	REQUIRE(rpz_num < rpzs->p.num_zones);
1561 	rpz = rpzs->zones[rpz_num];
1562 	REQUIRE(rpz != NULL);
1563 
1564 	/*
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
1574 	 *	zone.
1575 	 *
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
1583 	 */
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) {
1588 		/*
1589 		 * There is no existing version of the target zone.
1590 		 */
1591 		rpzs->load_begun |= tgt;
1592 		dns_rpz_attach_rpzs(rpzs, load_rpzsp);
1593 	} else {
1594 		/*
1595 		 * Setup the new RPZ struct with empty summary trees.
1596 		 */
1597 		result = dns_rpz_new_zones(load_rpzsp, rpzs->mctx);
1598 		if (result != ISC_R_SUCCESS)
1599 			return (result);
1600 		load_rpzs = *load_rpzsp;
1601 		/*
1602 		 * Initialize some members so that dns_rpz_add() works.
1603 		 */
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);
1608 	}
1609 
1610 	RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
1611 	UNLOCK(&rpzs->maint_lock);
1612 
1613 	return (ISC_R_SUCCESS);
1614 }
1615 
1616 /*
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.
1619  */
1620 static void
fix_triggers(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num)1621 fix_triggers(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) {
1622 	dns_rpz_num_t n;
1623 	dns_rpz_triggers_t old_totals;
1624 	dns_rpz_zbits_t zbit;
1625 	char namebuf[DNS_NAME_FORMATSIZE];
1626 
1627 	/*
1628 	 * rpzs->total_triggers is only used to log a message below.
1629 	 */
1630 
1631 	memmove(&old_totals, &rpzs->total_triggers, sizeof(old_totals));
1632 	memset(&rpzs->total_triggers, 0, sizeof(rpzs->total_triggers));
1633 
1634 #define SET_TRIG(n, zbit, type)						\
1635 	if (rpzs->triggers[n].type == 0) {				\
1636 		rpzs->have.type &= ~zbit;				\
1637 	} else {							\
1638 		rpzs->total_triggers.type += rpzs->triggers[n].type;	\
1639 		rpzs->have.type |= zbit;				\
1640 	}
1641 
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);
1652 	}
1653 
1654 #undef SET_TRIG
1655 
1656 	fix_qname_skip_recurse(rpzs);
1657 
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",
1666 		      namebuf,
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));
1681 }
1682 
1683 /*
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
1686  * held.
1687  *
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.
1691  *
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.
1698  *
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.
1704  *
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.
1708  *
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
1712  * zones.
1713  *
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.
1719  *
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
1722  * updated.
1723  */
1724 isc_result_t
dns_rpz_ready(dns_rpz_zones_t * rpzs,dns_rpz_zones_t ** load_rpzsp,dns_rpz_num_t rpz_num)1725 dns_rpz_ready(dns_rpz_zones_t *rpzs,
1726 	      dns_rpz_zones_t **load_rpzsp, dns_rpz_num_t rpz_num)
1727 {
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;
1733 	dns_rbt_t *rbt;
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;
1740 
1741 	INSIST(rpzs != NULL);
1742 	LOCK(&rpzs->maint_lock);
1743 	load_rpzs = *load_rpzsp;
1744 	INSIST(load_rpzs != NULL);
1745 
1746 	if (load_rpzs == rpzs) {
1747 		/*
1748 		 * This is a successful initial zone loading, perhaps
1749 		 * for a new instance of a view.
1750 		 */
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);
1757 	}
1758 
1759 	LOCK(&load_rpzs->maint_lock);
1760 	RWLOCK(&load_rpzs->search_lock, isc_rwlocktype_write);
1761 
1762 	/*
1763 	 * Unless there is only one policy zone, copy the other policy zones
1764 	 * from the old policy structure to the new summary databases.
1765 	 */
1766 	if (rpzs->p.num_zones > 1) {
1767 		new_bit = ~DNS_RPZ_ZBIT(rpz_num);
1768 
1769 		/*
1770 		 * Copy to the radix tree.
1771 		 */
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 ||
1777 			    new_ip.ip != 0 ||
1778 			    new_ip.nsip != 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);
1785 			}
1786 			/*
1787 			 * Do down and to the left as far as possible.
1788 			 */
1789 			next_cnode = cnode->child[0];
1790 			if (next_cnode != NULL)
1791 				continue;
1792 			/*
1793 			 * Go up until we find a branch to the right where
1794 			 * we previously took the branch to the left.
1795 			 */
1796 			for (;;) {
1797 				parent_cnode = cnode->parent;
1798 				if (parent_cnode == NULL)
1799 					break;
1800 				if (parent_cnode->child[0] == cnode) {
1801 					next_cnode = parent_cnode->child[1];
1802 					if (next_cnode != NULL)
1803 					    break;
1804 				}
1805 				cnode = parent_cnode;
1806 			}
1807 		}
1808 
1809 		/*
1810 		 * Copy to the summary RBT.
1811 		 */
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,
1822 							&nmnode);
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 &
1827 						      new_bit);
1828 				new_data.set.ns = nm_data->set.ns & new_bit;
1829 				new_data.wild.qname = (nm_data->wild.qname &
1830 						       new_bit);
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,
1840 							&new_data);
1841 					if (result != ISC_R_SUCCESS)
1842 						goto unlock_and_detach;
1843 				}
1844 			}
1845 			result = dns_rbtnodechain_next(&chain, NULL, NULL);
1846 		}
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;
1853 		}
1854 	}
1855 
1856 	/*
1857 	 * Exchange the summary databases.
1858 	 */
1859 	RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
1860 
1861 	rpzs->triggers[rpz_num] = load_rpzs->triggers[rpz_num];
1862 	fix_triggers(rpzs, rpz_num);
1863 
1864 	found = rpzs->cidr;
1865 	rpzs->cidr = load_rpzs->cidr;
1866 	load_rpzs->cidr = found;
1867 
1868 	rbt = rpzs->rbt;
1869 	rpzs->rbt = load_rpzs->rbt;
1870 	load_rpzs->rbt = rbt;
1871 
1872 	RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
1873 
1874 	result = ISC_R_SUCCESS;
1875 
1876  unlock_and_detach:
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);
1881 	return (result);
1882 }
1883 
1884 /*
1885  * Add an IP address to the radix tree or a name to the summary database.
1886  */
1887 isc_result_t
dns_rpz_add(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_name_t * src_name)1888 dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_name_t *src_name)
1889 {
1890 	dns_rpz_zone_t *rpz;
1891 	dns_rpz_type_t rpz_type;
1892 	isc_result_t result = ISC_R_FAILURE;
1893 
1894 	REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones);
1895 	rpz = rpzs->zones[rpz_num];
1896 	REQUIRE(rpz != NULL);
1897 
1898 	rpz_type = type_from_name(rpz, src_name);
1899 
1900 	LOCK(&rpzs->maint_lock);
1901 	RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
1902 
1903 	switch (rpz_type) {
1904 	case DNS_RPZ_TYPE_QNAME:
1905 	case DNS_RPZ_TYPE_NSDNAME:
1906 		result = add_name(rpzs, rpz_num, rpz_type, src_name);
1907 		break;
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);
1912 		break;
1913 	case DNS_RPZ_TYPE_BAD:
1914 		break;
1915 	}
1916 
1917 	RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
1918 	UNLOCK(&rpzs->maint_lock);
1919 	return (result);
1920 }
1921 
1922 /*
1923  * Remove an IP address from the radix tree.
1924  */
1925 static void
del_cidr(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_rpz_type_t rpz_type,dns_name_t * src_name)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)
1928 {
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;
1934 
1935 	/*
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.
1939 	 */
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)
1943 		return;
1944 
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);
1949 		/*
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.
1954 		 */
1955 		return;
1956 	}
1957 
1958 	/*
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.
1961 	 */
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;
1968 	set_sum_pair(tgt);
1969 
1970 	adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix, ISC_FALSE);
1971 
1972 	/*
1973 	 * We might need to delete 2 nodes.
1974 	 */
1975 	do {
1976 		/*
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.
1979 		 */
1980 		if ((child = tgt->child[0]) != NULL) {
1981 			if (tgt->child[1] != NULL)
1982 				break;
1983 		} else {
1984 			child = tgt->child[1];
1985 		}
1986 		if (tgt->set.client_ip != 0 ||
1987 		    tgt->set.ip != 0 ||
1988 		    tgt->set.nsip != 0)
1989 			break;
1990 
1991 		/*
1992 		 * Replace the pointer to this node in the parent with
1993 		 * the remaining child or NULL.
1994 		 */
1995 		parent = tgt->parent;
1996 		if (parent == NULL) {
1997 			rpzs->cidr = child;
1998 		} else {
1999 			parent->child[parent->child[1] == tgt] = child;
2000 		}
2001 		/*
2002 		 * If the child exists fix up its parent pointer.
2003 		 */
2004 		if (child != NULL)
2005 			child->parent = parent;
2006 		isc_mem_put(rpzs->mctx, tgt, sizeof(*tgt));
2007 
2008 		tgt = parent;
2009 	} while (tgt != NULL);
2010 }
2011 
2012 static void
del_name(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_rpz_type_t rpz_type,dns_name_t * src_name)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)
2015 {
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;
2022 
2023 	/*
2024 	 * No need for a summary database of names with only 1 policy zone.
2025 	 */
2026 	if (rpzs->p.num_zones <= 1) {
2027 		adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, ISC_FALSE);
2028 		return;
2029 	}
2030 
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);
2034 
2035 	nmnode = NULL;
2036 	result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, NULL, 0,
2037 				  NULL, NULL);
2038 	if (result != ISC_R_SUCCESS) {
2039 		/*
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.
2044 		 */
2045 		if (result == ISC_R_NOTFOUND ||
2046 		    result == DNS_R_PARTIALMATCH)
2047 			return;
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));
2053 		return;
2054 	}
2055 
2056 	nm_data = nmnode->data;
2057 	INSIST(nm_data != NULL);
2058 
2059 	/*
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.
2062 	 */
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;
2067 
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;
2072 
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) {
2077 			/*
2078 			 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2079 			 */
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));
2085 		}
2086 	}
2087 
2088 	adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, ISC_FALSE);
2089 }
2090 
2091 /*
2092  * Remove an IP address from the radix tree or a name from the summary database.
2093  */
2094 void
dns_rpz_delete(dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num,dns_name_t * src_name)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;
2099 
2100 	REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones);
2101 	rpz = rpzs->zones[rpz_num];
2102 	REQUIRE(rpz != NULL);
2103 
2104 	rpz_type = type_from_name(rpz, src_name);
2105 
2106 	LOCK(&rpzs->maint_lock);
2107 	RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2108 
2109 	switch (rpz_type) {
2110 	case DNS_RPZ_TYPE_QNAME:
2111 	case DNS_RPZ_TYPE_NSDNAME:
2112 		del_name(rpzs, rpz_num, rpz_type, src_name);
2113 		break;
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);
2118 		break;
2119 	case DNS_RPZ_TYPE_BAD:
2120 		break;
2121 	}
2122 
2123 	RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2124 	UNLOCK(&rpzs->maint_lock);
2125 }
2126 
2127 /*
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.
2134  */
2135 dns_rpz_num_t
dns_rpz_find_ip(dns_rpz_zones_t * rpzs,dns_rpz_type_t rpz_type,dns_rpz_zbits_t zbits,const isc_netaddr_t * netaddr,dns_name_t * ip_name,dns_rpz_prefix_t * prefixp)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)
2139 {
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;
2146 	int i;
2147 
2148 	LOCK(&rpzs->maint_lock);
2149 	have = rpzs->have;
2150 	UNLOCK(&rpzs->maint_lock);
2151 
2152 	/*
2153 	 * Convert IP address to CIDR tree key.
2154 	 */
2155 	if (netaddr->family == AF_INET) {
2156 		tgt_ip.w[0] = 0;
2157 		tgt_ip.w[1] = 0;
2158 		tgt_ip.w[2] = ADDR_V4MAPPED;
2159 		tgt_ip.w[3] = ntohl(netaddr->type.in.s_addr);
2160 		switch (rpz_type) {
2161 		case DNS_RPZ_TYPE_CLIENT_IP:
2162 			zbits &= have.client_ipv4;
2163 			break;
2164 		case DNS_RPZ_TYPE_IP:
2165 			zbits &= have.ipv4;
2166 			break;
2167 		case DNS_RPZ_TYPE_NSIP:
2168 			zbits &= have.nsipv4;
2169 			break;
2170 		default:
2171 			INSIST(0);
2172 			break;
2173 		}
2174 	} else if (netaddr->family == AF_INET6) {
2175 		dns_rpz_cidr_key_t src_ip6;
2176 
2177 		/*
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.
2181 		 */
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]);
2185 		}
2186 		switch (rpz_type) {
2187 		case DNS_RPZ_TYPE_CLIENT_IP:
2188 			zbits &= have.client_ipv6;
2189 			break;
2190 		case DNS_RPZ_TYPE_IP:
2191 			zbits &= have.ipv6;
2192 			break;
2193 		case DNS_RPZ_TYPE_NSIP:
2194 			zbits &= have.nsipv6;
2195 			break;
2196 		default:
2197 			INSIST(0);
2198 			break;
2199 		}
2200 	} else {
2201 		return (DNS_RPZ_INVALID_NUM);
2202 	}
2203 
2204 	if (zbits == 0)
2205 		return (DNS_RPZ_INVALID_NUM);
2206 	make_addr_set(&tgt_set, zbits, rpz_type);
2207 
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) {
2211 		/*
2212 		 * There are no eligible zones for this IP address.
2213 		 */
2214 		RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2215 		return (DNS_RPZ_INVALID_NUM);
2216 	}
2217 
2218 	/*
2219 	 * Construct the trigger name for the longest matching trigger
2220 	 * in the first eligible zone with a match.
2221 	 */
2222 	*prefixp = found->prefix;
2223 	switch (rpz_type) {
2224 	case DNS_RPZ_TYPE_CLIENT_IP:
2225 		rpz_num = zbit_to_num(found->set.client_ip & tgt_set.client_ip);
2226 		break;
2227 	case DNS_RPZ_TYPE_IP:
2228 		rpz_num = zbit_to_num(found->set.ip & tgt_set.ip);
2229 		break;
2230 	case DNS_RPZ_TYPE_NSIP:
2231 		rpz_num = zbit_to_num(found->set.nsip & tgt_set.nsip);
2232 		break;
2233 	default:
2234 		INSIST(0);
2235 		break;
2236 	}
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) {
2240 		/*
2241 		 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2242 		 */
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);
2248 	}
2249 	return (rpz_num);
2250 }
2251 
2252 /*
2253  * Search the summary radix tree for policy zones with triggers matching
2254  * a name.
2255  */
2256 dns_rpz_zbits_t
dns_rpz_find_name(dns_rpz_zones_t * rpzs,dns_rpz_type_t rpz_type,dns_rpz_zbits_t zbits,dns_name_t * trig_name)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)
2259 {
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;
2265 
2266 	if (zbits == 0)
2267 		return (0);
2268 
2269 	found_zbits = 0;
2270 
2271 	RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2272 
2273 	nmnode = NULL;
2274 	result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, NULL,
2275 				  DNS_RBTFIND_EMPTYDATA, NULL, NULL);
2276 	switch (result) {
2277 	case ISC_R_SUCCESS:
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;
2282 			else
2283 				found_zbits = nm_data->set.ns;
2284 		}
2285 		nmnode = nmnode->parent;
2286 		/* fall thru */
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;
2293 				else
2294 					found_zbits |= nm_data->wild.ns;
2295 			}
2296 			nmnode = nmnode->parent;
2297 		}
2298 		break;
2299 
2300 	case ISC_R_NOTFOUND:
2301 		break;
2302 
2303 	default:
2304 		/*
2305 		 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2306 		 */
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));
2312 		break;
2313 	}
2314 
2315 	RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2316 	return (zbits & found_zbits);
2317 }
2318 
2319 /*
2320  * Translate CNAME rdata to a QNAME response policy action.
2321  */
2322 dns_rpz_policy_t
dns_rpz_decode_cname(dns_rpz_zone_t * rpz,dns_rdataset_t * rdataset,dns_name_t * selfname)2323 dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
2324 		     dns_name_t *selfname)
2325 {
2326 	dns_rdata_t rdata = DNS_RDATA_INIT;
2327 	dns_rdata_cname_t cname;
2328 	isc_result_t result;
2329 
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);
2336 
2337 	/*
2338 	 * CNAME . means NXDOMAIN
2339 	 */
2340 	if (dns_name_equal(&cname.cname, dns_rootname))
2341 		return (DNS_RPZ_POLICY_NXDOMAIN);
2342 
2343 	if (dns_name_iswildcard(&cname.cname)) {
2344 		/*
2345 		 * CNAME *. means NODATA
2346 		 */
2347 		if (dns_name_countlabels(&cname.cname) == 2)
2348 			return (DNS_RPZ_POLICY_NODATA);
2349 
2350 		/*
2351 		 * A qname of www.evil.com and a policy of
2352 		 *	*.evil.com    CNAME   *.garden.net
2353 		 * gives a result of
2354 		 *	evil.com    CNAME   evil.com.garden.net
2355 		 */
2356 		if (dns_name_countlabels(&cname.cname) > 2)
2357 			return (DNS_RPZ_POLICY_WILDCNAME);
2358 	}
2359 
2360 	/*
2361 	 * CNAME rpz-tcp-only. means "send truncated UDP responses."
2362 	 */
2363 	if (dns_name_equal(&cname.cname, &rpz->tcp_only))
2364 		return (DNS_RPZ_POLICY_TCP_ONLY);
2365 
2366 	/*
2367 	 * CNAME rpz-drop. means "do not respond."
2368 	 */
2369 	if (dns_name_equal(&cname.cname, &rpz->drop))
2370 		return (DNS_RPZ_POLICY_DROP);
2371 
2372 	/*
2373 	 * CNAME rpz-passthru. means "do not rewrite."
2374 	 */
2375 	if (dns_name_equal(&cname.cname, &rpz->passthru))
2376 		return (DNS_RPZ_POLICY_PASSTHRU);
2377 
2378 	/*
2379 	 * 128.1.0.127.rpz-ip CNAME  128.1.0.0.127. is obsolete PASSTHRU
2380 	 */
2381 	if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
2382 		return (DNS_RPZ_POLICY_PASSTHRU);
2383 
2384 	/*
2385 	 * Any other rdata gives a response consisting of the rdata.
2386 	 */
2387 	return (DNS_RPZ_POLICY_RECORD);
2388 }
2389