xref: /minix/external/bsd/bind/dist/bin/named/query.c (revision fb9c64b2)
1 /*	$NetBSD: query.c,v 1.19 2015/07/08 17:28:55 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004-2015  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 1999-2003  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*! \file */
21 
22 #include <config.h>
23 
24 #include <string.h>
25 
26 #include <isc/hex.h>
27 #include <isc/mem.h>
28 #include <isc/print.h>
29 #include <isc/rwlock.h>
30 #include <isc/serial.h>
31 #include <isc/stats.h>
32 #include <isc/util.h>
33 
34 #include <dns/adb.h>
35 #include <dns/byaddr.h>
36 #include <dns/cache.h>
37 #include <dns/db.h>
38 #include <dns/dlz.h>
39 #include <dns/dns64.h>
40 #include <dns/dnssec.h>
41 #include <dns/events.h>
42 #include <dns/message.h>
43 #include <dns/ncache.h>
44 #include <dns/nsec3.h>
45 #include <dns/order.h>
46 #include <dns/rdata.h>
47 #include <dns/rdataclass.h>
48 #include <dns/rdatalist.h>
49 #include <dns/rdataset.h>
50 #include <dns/rdatasetiter.h>
51 #include <dns/rdatastruct.h>
52 #include <dns/rdatatype.h>
53 #include <dns/resolver.h>
54 #include <dns/result.h>
55 #include <dns/stats.h>
56 #include <dns/tkey.h>
57 #include <dns/view.h>
58 #include <dns/zone.h>
59 #include <dns/zt.h>
60 
61 #include <named/client.h>
62 #include <named/globals.h>
63 #include <named/log.h>
64 #include <named/server.h>
65 #include <named/sortlist.h>
66 #include <named/xfrout.h>
67 
68 #include "pfilter.h"
69 
70 #if 0
71 /*
72  * It has been recommended that DNS64 be changed to return excluded
73  * AAAA addresses if DNS64 synthesis does not occur.  This minimises
74  * the impact on the lookup results.  While most DNS AAAA lookups are
75  * done to send IP packets to a host, not all of them are and filtering
76  * excluded addresses has a negative impact on those uses.
77  */
78 #define dns64_bis_return_excluded_addresses 1
79 #endif
80 
81 /*% Partial answer? */
82 #define PARTIALANSWER(c)	(((c)->query.attributes & \
83 				  NS_QUERYATTR_PARTIALANSWER) != 0)
84 /*% Use Cache? */
85 #define USECACHE(c)		(((c)->query.attributes & \
86 				  NS_QUERYATTR_CACHEOK) != 0)
87 /*% Recursion OK? */
88 #define RECURSIONOK(c)		(((c)->query.attributes & \
89 				  NS_QUERYATTR_RECURSIONOK) != 0)
90 /*% Recursing? */
91 #define RECURSING(c)		(((c)->query.attributes & \
92 				  NS_QUERYATTR_RECURSING) != 0)
93 /*% Cache glue ok? */
94 #define CACHEGLUEOK(c)		(((c)->query.attributes & \
95 				  NS_QUERYATTR_CACHEGLUEOK) != 0)
96 /*% Want Recursion? */
97 #define WANTRECURSION(c)	(((c)->query.attributes & \
98 				  NS_QUERYATTR_WANTRECURSION) != 0)
99 /*% Want DNSSEC? */
100 #define WANTDNSSEC(c)		(((c)->attributes & \
101 				  NS_CLIENTATTR_WANTDNSSEC) != 0)
102 /*% Want WANTAD? */
103 #define WANTAD(c)		(((c)->attributes & \
104 				  NS_CLIENTATTR_WANTAD) != 0)
105 #ifdef ISC_PLATFORM_USESIT
106 /*% Client presented a valid Source Identity Token. */
107 #define HAVESIT(c)		(((c)->attributes & \
108 				  NS_CLIENTATTR_HAVESIT) != 0)
109 #else
110 #define HAVESIT(c)		(0)
111 #endif
112 
113 /*% No authority? */
114 #define NOAUTHORITY(c)		(((c)->query.attributes & \
115 				  NS_QUERYATTR_NOAUTHORITY) != 0)
116 /*% No additional? */
117 #define NOADDITIONAL(c)		(((c)->query.attributes & \
118 				  NS_QUERYATTR_NOADDITIONAL) != 0)
119 /*% Secure? */
120 #define SECURE(c)		(((c)->query.attributes & \
121 				  NS_QUERYATTR_SECURE) != 0)
122 /*% DNS64 A lookup? */
123 #define DNS64(c)		(((c)->query.attributes & \
124 				  NS_QUERYATTR_DNS64) != 0)
125 
126 #define DNS64EXCLUDE(c)		(((c)->query.attributes & \
127 				  NS_QUERYATTR_DNS64EXCLUDE) != 0)
128 
129 /*% No QNAME Proof? */
130 #define NOQNAME(r)		(((r)->attributes & \
131 				  DNS_RDATASETATTR_NOQNAME) != 0)
132 
133 #if 0
134 #define CTRACE(m)       isc_log_write(ns_g_lctx, \
135 				      NS_LOGCATEGORY_CLIENT, \
136 				      NS_LOGMODULE_QUERY, \
137 				      ISC_LOG_DEBUG(3), \
138 				      "client %p: %s", client, (m))
139 #define QTRACE(m)       isc_log_write(ns_g_lctx, \
140 				      NS_LOGCATEGORY_GENERAL, \
141 				      NS_LOGMODULE_QUERY, \
142 				      ISC_LOG_DEBUG(3), \
143 				      "query %p: %s", query, (m))
144 #else
145 #define CTRACE(m) ((void)m)
146 #define QTRACE(m) ((void)m)
147 #endif
148 
149 #define DNS_GETDB_NOEXACT 0x01U
150 #define DNS_GETDB_NOLOG 0x02U
151 #define DNS_GETDB_PARTIAL 0x04U
152 #define DNS_GETDB_IGNOREACL 0x08U
153 
154 #define PENDINGOK(x)	(((x) & DNS_DBFIND_PENDINGOK) != 0)
155 
156 typedef struct client_additionalctx {
157 	ns_client_t *client;
158 	dns_rdataset_t *rdataset;
159 } client_additionalctx_t;
160 
161 static isc_result_t
162 query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype);
163 
164 static isc_boolean_t
165 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
166 	 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
167 
168 static void
169 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
170 		       dns_dbversion_t *version, ns_client_t *client,
171 		       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
172 		       dns_name_t *fname, isc_boolean_t exact,
173 		       dns_name_t *found);
174 
175 static inline void
176 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level);
177 
178 static void
179 rpz_st_clear(ns_client_t *client);
180 
181 static isc_boolean_t
182 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
183 	      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
184 
185 /*%
186  * Increment query statistics counters.
187  */
188 static inline void
189 inc_stats(ns_client_t *client, isc_statscounter_t counter) {
190 	dns_zone_t *zone = client->query.authzone;
191 	dns_rdatatype_t qtype;
192 	dns_rdataset_t *rdataset;
193 	isc_stats_t *zonestats;
194 	dns_stats_t *querystats = NULL;
195 
196 	isc_stats_increment(ns_g_server->nsstats, counter);
197 
198 	if (zone == NULL)
199 		return;
200 
201 	/* Do regular response type stats */
202 	zonestats = dns_zone_getrequeststats(zone);
203 
204 	if (zonestats != NULL)
205 		isc_stats_increment(zonestats, counter);
206 
207 	/* Do query type statistics
208 	 *
209 	 * We only increment per-type if we're using the authoritative
210 	 * answer counter, preventing double-counting.
211 	 */
212 	if (counter == dns_nsstatscounter_authans) {
213 		querystats = dns_zone_getrcvquerystats(zone);
214 		if (querystats != NULL) {
215 			rdataset = ISC_LIST_HEAD(client->query.qname->list);
216 			if (rdataset != NULL) {
217 				qtype = rdataset->type;
218 				dns_rdatatypestats_increment(querystats, qtype);
219 			}
220 		}
221 	}
222 }
223 
224 static void
225 query_send(ns_client_t *client) {
226 	isc_statscounter_t counter;
227 
228 	if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0)
229 		inc_stats(client, dns_nsstatscounter_nonauthans);
230 	else
231 		inc_stats(client, dns_nsstatscounter_authans);
232 
233 	if (client->message->rcode == dns_rcode_noerror) {
234 		dns_section_t answer = DNS_SECTION_ANSWER;
235 		if (ISC_LIST_EMPTY(client->message->sections[answer])) {
236 			if (client->query.isreferral)
237 				counter = dns_nsstatscounter_referral;
238 			else
239 				counter = dns_nsstatscounter_nxrrset;
240 		} else
241 			counter = dns_nsstatscounter_success;
242 	} else if (client->message->rcode == dns_rcode_nxdomain)
243 		counter = dns_nsstatscounter_nxdomain;
244 	else /* We end up here in case of YXDOMAIN, and maybe others */
245 		counter = dns_nsstatscounter_failure;
246 
247 	inc_stats(client, counter);
248 	ns_client_send(client);
249 }
250 
251 static void
252 query_error(ns_client_t *client, isc_result_t result, int line) {
253 	int loglevel = ISC_LOG_DEBUG(3);
254 
255 	switch (result) {
256 	case DNS_R_SERVFAIL:
257 		loglevel = ISC_LOG_DEBUG(1);
258 		inc_stats(client, dns_nsstatscounter_servfail);
259 		break;
260 	case DNS_R_FORMERR:
261 		inc_stats(client, dns_nsstatscounter_formerr);
262 		break;
263 	default:
264 		inc_stats(client, dns_nsstatscounter_failure);
265 		break;
266 	}
267 
268 	log_queryerror(client, result, line, loglevel);
269 
270 	ns_client_error(client, result);
271 }
272 
273 static void
274 query_next(ns_client_t *client, isc_result_t result) {
275 	if (result == DNS_R_DUPLICATE)
276 		inc_stats(client, dns_nsstatscounter_duplicate);
277 	else if (result == DNS_R_DROP)
278 		inc_stats(client, dns_nsstatscounter_dropped);
279 	else
280 		inc_stats(client, dns_nsstatscounter_failure);
281 	ns_client_next(client, result);
282 }
283 
284 static inline void
285 query_freefreeversions(ns_client_t *client, isc_boolean_t everything) {
286 	ns_dbversion_t *dbversion, *dbversion_next;
287 	unsigned int i;
288 
289 	for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0;
290 	     dbversion != NULL;
291 	     dbversion = dbversion_next, i++)
292 	{
293 		dbversion_next = ISC_LIST_NEXT(dbversion, link);
294 		/*
295 		 * If we're not freeing everything, we keep the first three
296 		 * dbversions structures around.
297 		 */
298 		if (i > 3 || everything) {
299 			ISC_LIST_UNLINK(client->query.freeversions, dbversion,
300 					link);
301 			isc_mem_put(client->mctx, dbversion,
302 				    sizeof(*dbversion));
303 		}
304 	}
305 }
306 
307 void
308 ns_query_cancel(ns_client_t *client) {
309 	LOCK(&client->query.fetchlock);
310 	if (client->query.fetch != NULL) {
311 		dns_resolver_cancelfetch(client->query.fetch);
312 
313 		client->query.fetch = NULL;
314 	}
315 	UNLOCK(&client->query.fetchlock);
316 }
317 
318 static inline void
319 query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
320 	dns_rdataset_t *rdataset = *rdatasetp;
321 
322 	CTRACE("query_putrdataset");
323 	if (rdataset != NULL) {
324 		if (dns_rdataset_isassociated(rdataset))
325 			dns_rdataset_disassociate(rdataset);
326 		dns_message_puttemprdataset(client->message, rdatasetp);
327 	}
328 	CTRACE("query_putrdataset: done");
329 }
330 
331 static inline void
332 query_reset(ns_client_t *client, isc_boolean_t everything) {
333 	isc_buffer_t *dbuf, *dbuf_next;
334 	ns_dbversion_t *dbversion, *dbversion_next;
335 
336 	/*%
337 	 * Reset the query state of a client to its default state.
338 	 */
339 
340 	/*
341 	 * Cancel the fetch if it's running.
342 	 */
343 	ns_query_cancel(client);
344 
345 	/*
346 	 * Cleanup any active versions.
347 	 */
348 	for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
349 	     dbversion != NULL;
350 	     dbversion = dbversion_next) {
351 		dbversion_next = ISC_LIST_NEXT(dbversion, link);
352 		dns_db_closeversion(dbversion->db, &dbversion->version,
353 				    ISC_FALSE);
354 		dns_db_detach(&dbversion->db);
355 		ISC_LIST_INITANDAPPEND(client->query.freeversions,
356 				      dbversion, link);
357 	}
358 	ISC_LIST_INIT(client->query.activeversions);
359 
360 	if (client->query.authdb != NULL)
361 		dns_db_detach(&client->query.authdb);
362 	if (client->query.authzone != NULL)
363 		dns_zone_detach(&client->query.authzone);
364 
365 	if (client->query.dns64_aaaa != NULL)
366 		query_putrdataset(client, &client->query.dns64_aaaa);
367 	if (client->query.dns64_sigaaaa != NULL)
368 		query_putrdataset(client, &client->query.dns64_sigaaaa);
369 	if (client->query.dns64_aaaaok != NULL) {
370 		isc_mem_put(client->mctx, client->query.dns64_aaaaok,
371 			    client->query.dns64_aaaaoklen *
372 			    sizeof(isc_boolean_t));
373 		client->query.dns64_aaaaok =  NULL;
374 		client->query.dns64_aaaaoklen =  0;
375 	}
376 
377 	query_freefreeversions(client, everything);
378 
379 	for (dbuf = ISC_LIST_HEAD(client->query.namebufs);
380 	     dbuf != NULL;
381 	     dbuf = dbuf_next) {
382 		dbuf_next = ISC_LIST_NEXT(dbuf, link);
383 		if (dbuf_next != NULL || everything) {
384 			ISC_LIST_UNLINK(client->query.namebufs, dbuf, link);
385 			isc_buffer_free(&dbuf);
386 		}
387 	}
388 
389 	if (client->query.restarts > 0) {
390 		/*
391 		 * client->query.qname was dynamically allocated.
392 		 */
393 		dns_message_puttempname(client->message,
394 					&client->query.qname);
395 	}
396 	client->query.qname = NULL;
397 	client->query.attributes = (NS_QUERYATTR_RECURSIONOK |
398 				    NS_QUERYATTR_CACHEOK |
399 				    NS_QUERYATTR_SECURE);
400 	client->query.restarts = 0;
401 	client->query.timerset = ISC_FALSE;
402 	if (client->query.rpz_st != NULL) {
403 		rpz_st_clear(client);
404 		if (everything) {
405 			isc_mem_put(client->mctx, client->query.rpz_st,
406 				    sizeof(*client->query.rpz_st));
407 			client->query.rpz_st = NULL;
408 		}
409 	}
410 	client->query.origqname = NULL;
411 	client->query.dboptions = 0;
412 	client->query.fetchoptions = 0;
413 	client->query.gluedb = NULL;
414 	client->query.authdbset = ISC_FALSE;
415 	client->query.isreferral = ISC_FALSE;
416 	client->query.dns64_options = 0;
417 	client->query.dns64_ttl = ISC_UINT32_MAX;
418 }
419 
420 static void
421 query_next_callback(ns_client_t *client) {
422 	query_reset(client, ISC_FALSE);
423 }
424 
425 void
426 ns_query_free(ns_client_t *client) {
427 	query_reset(client, ISC_TRUE);
428 }
429 
430 static inline isc_result_t
431 query_newnamebuf(ns_client_t *client) {
432 	isc_buffer_t *dbuf;
433 	isc_result_t result;
434 
435 	CTRACE("query_newnamebuf");
436 	/*%
437 	 * Allocate a name buffer.
438 	 */
439 
440 	dbuf = NULL;
441 	result = isc_buffer_allocate(client->mctx, &dbuf, 1024);
442 	if (result != ISC_R_SUCCESS) {
443 		CTRACE("query_newnamebuf: isc_buffer_allocate failed: done");
444 		return (result);
445 	}
446 	ISC_LIST_APPEND(client->query.namebufs, dbuf, link);
447 
448 	CTRACE("query_newnamebuf: done");
449 	return (ISC_R_SUCCESS);
450 }
451 
452 static inline isc_buffer_t *
453 query_getnamebuf(ns_client_t *client) {
454 	isc_buffer_t *dbuf;
455 	isc_result_t result;
456 	isc_region_t r;
457 
458 	CTRACE("query_getnamebuf");
459 	/*%
460 	 * Return a name buffer with space for a maximal name, allocating
461 	 * a new one if necessary.
462 	 */
463 
464 	if (ISC_LIST_EMPTY(client->query.namebufs)) {
465 		result = query_newnamebuf(client);
466 		if (result != ISC_R_SUCCESS) {
467 		    CTRACE("query_getnamebuf: query_newnamebuf failed: done");
468 			return (NULL);
469 		}
470 	}
471 
472 	dbuf = ISC_LIST_TAIL(client->query.namebufs);
473 	INSIST(dbuf != NULL);
474 	isc_buffer_availableregion(dbuf, &r);
475 	if (r.length < 255) {
476 		result = query_newnamebuf(client);
477 		if (result != ISC_R_SUCCESS) {
478 		    CTRACE("query_getnamebuf: query_newnamebuf failed: done");
479 			return (NULL);
480 
481 		}
482 		dbuf = ISC_LIST_TAIL(client->query.namebufs);
483 		isc_buffer_availableregion(dbuf, &r);
484 		INSIST(r.length >= 255);
485 	}
486 	CTRACE("query_getnamebuf: done");
487 	return (dbuf);
488 }
489 
490 static inline void
491 query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
492 	isc_region_t r;
493 
494 	CTRACE("query_keepname");
495 	/*%
496 	 * 'name' is using space in 'dbuf', but 'dbuf' has not yet been
497 	 * adjusted to take account of that.  We do the adjustment.
498 	 */
499 
500 	REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);
501 
502 	dns_name_toregion(name, &r);
503 	isc_buffer_add(dbuf, r.length);
504 	dns_name_setbuffer(name, NULL);
505 	client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
506 }
507 
508 static inline void
509 query_releasename(ns_client_t *client, dns_name_t **namep) {
510 	dns_name_t *name = *namep;
511 
512 	/*%
513 	 * 'name' is no longer needed.  Return it to our pool of temporary
514 	 * names.  If it is using a name buffer, relinquish its exclusive
515 	 * rights on the buffer.
516 	 */
517 
518 	CTRACE("query_releasename");
519 	if (dns_name_hasbuffer(name)) {
520 		INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED)
521 		       != 0);
522 		client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
523 	}
524 	dns_message_puttempname(client->message, namep);
525 	CTRACE("query_releasename: done");
526 }
527 
528 static inline dns_name_t *
529 query_newname(ns_client_t *client, isc_buffer_t *dbuf,
530 	      isc_buffer_t *nbuf)
531 {
532 	dns_name_t *name;
533 	isc_region_t r;
534 	isc_result_t result;
535 
536 	REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
537 
538 	CTRACE("query_newname");
539 	name = NULL;
540 	result = dns_message_gettempname(client->message, &name);
541 	if (result != ISC_R_SUCCESS) {
542 		CTRACE("query_newname: dns_message_gettempname failed: done");
543 		return (NULL);
544 	}
545 	isc_buffer_availableregion(dbuf, &r);
546 	isc_buffer_init(nbuf, r.base, r.length);
547 	dns_name_init(name, NULL);
548 	dns_name_setbuffer(name, nbuf);
549 	client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
550 
551 	CTRACE("query_newname: done");
552 	return (name);
553 }
554 
555 static inline dns_rdataset_t *
556 query_newrdataset(ns_client_t *client) {
557 	dns_rdataset_t *rdataset;
558 	isc_result_t result;
559 
560 	CTRACE("query_newrdataset");
561 	rdataset = NULL;
562 	result = dns_message_gettemprdataset(client->message, &rdataset);
563 	if (result != ISC_R_SUCCESS) {
564 	  CTRACE("query_newrdataset: "
565 		 "dns_message_gettemprdataset failed: done");
566 		return (NULL);
567 	}
568 
569 	CTRACE("query_newrdataset: done");
570 	return (rdataset);
571 }
572 
573 static inline isc_result_t
574 query_newdbversion(ns_client_t *client, unsigned int n) {
575 	unsigned int i;
576 	ns_dbversion_t *dbversion;
577 
578 	for (i = 0; i < n; i++) {
579 		dbversion = isc_mem_get(client->mctx, sizeof(*dbversion));
580 		if (dbversion != NULL) {
581 			dbversion->db = NULL;
582 			dbversion->version = NULL;
583 			ISC_LIST_INITANDAPPEND(client->query.freeversions,
584 					      dbversion, link);
585 		} else {
586 			/*
587 			 * We only return ISC_R_NOMEMORY if we couldn't
588 			 * allocate anything.
589 			 */
590 			if (i == 0)
591 				return (ISC_R_NOMEMORY);
592 			else
593 				return (ISC_R_SUCCESS);
594 		}
595 	}
596 
597 	return (ISC_R_SUCCESS);
598 }
599 
600 static inline ns_dbversion_t *
601 query_getdbversion(ns_client_t *client) {
602 	isc_result_t result;
603 	ns_dbversion_t *dbversion;
604 
605 	if (ISC_LIST_EMPTY(client->query.freeversions)) {
606 		result = query_newdbversion(client, 1);
607 		if (result != ISC_R_SUCCESS)
608 			return (NULL);
609 	}
610 	dbversion = ISC_LIST_HEAD(client->query.freeversions);
611 	INSIST(dbversion != NULL);
612 	ISC_LIST_UNLINK(client->query.freeversions, dbversion, link);
613 
614 	return (dbversion);
615 }
616 
617 isc_result_t
618 ns_query_init(ns_client_t *client) {
619 	isc_result_t result;
620 
621 	ISC_LIST_INIT(client->query.namebufs);
622 	ISC_LIST_INIT(client->query.activeversions);
623 	ISC_LIST_INIT(client->query.freeversions);
624 	client->query.restarts = 0;
625 	client->query.timerset = ISC_FALSE;
626 	client->query.rpz_st = NULL;
627 	client->query.qname = NULL;
628 	/*
629 	 * This mutex is destroyed when the client is destroyed in
630 	 * exit_check().
631 	 */
632 	result = isc_mutex_init(&client->query.fetchlock);
633 	if (result != ISC_R_SUCCESS)
634 		return (result);
635 	client->query.fetch = NULL;
636 	client->query.prefetch = NULL;
637 	client->query.authdb = NULL;
638 	client->query.authzone = NULL;
639 	client->query.authdbset = ISC_FALSE;
640 	client->query.isreferral = ISC_FALSE;
641 	client->query.dns64_aaaa = NULL;
642 	client->query.dns64_sigaaaa = NULL;
643 	client->query.dns64_aaaaok = NULL;
644 	client->query.dns64_aaaaoklen = 0;
645 	query_reset(client, ISC_FALSE);
646 	result = query_newdbversion(client, 3);
647 	if (result != ISC_R_SUCCESS) {
648 		DESTROYLOCK(&client->query.fetchlock);
649 		return (result);
650 	}
651 	result = query_newnamebuf(client);
652 	if (result != ISC_R_SUCCESS) {
653 		query_freefreeversions(client, ISC_TRUE);
654 		DESTROYLOCK(&client->query.fetchlock);
655 	}
656 
657 	return (result);
658 }
659 
660 static inline ns_dbversion_t *
661 query_findversion(ns_client_t *client, dns_db_t *db) {
662 	ns_dbversion_t *dbversion;
663 
664 	/*%
665 	 * We may already have done a query related to this
666 	 * database.  If so, we must be sure to make subsequent
667 	 * queries from the same version.
668 	 */
669 	for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
670 	     dbversion != NULL;
671 	     dbversion = ISC_LIST_NEXT(dbversion, link)) {
672 		if (dbversion->db == db)
673 			break;
674 	}
675 
676 	if (dbversion == NULL) {
677 		/*
678 		 * This is a new zone for this query.  Add it to
679 		 * the active list.
680 		 */
681 		dbversion = query_getdbversion(client);
682 		if (dbversion == NULL)
683 			return (NULL);
684 		dns_db_attach(db, &dbversion->db);
685 		dns_db_currentversion(db, &dbversion->version);
686 		dbversion->acl_checked = ISC_FALSE;
687 		dbversion->queryok = ISC_FALSE;
688 		ISC_LIST_APPEND(client->query.activeversions,
689 				dbversion, link);
690 	}
691 
692 	return (dbversion);
693 }
694 
695 static inline isc_result_t
696 query_validatezonedb(ns_client_t *client, dns_name_t *name,
697 		     dns_rdatatype_t qtype, unsigned int options,
698 		     dns_zone_t *zone, dns_db_t *db,
699 		     dns_dbversion_t **versionp)
700 {
701 	isc_result_t result;
702 	dns_acl_t *queryacl, *queryonacl;
703 	ns_dbversion_t *dbversion;
704 
705 	REQUIRE(zone != NULL);
706 	REQUIRE(db != NULL);
707 
708 	/*
709 	 * This limits our searching to the zone where the first name
710 	 * (the query target) was looked for.  This prevents following
711 	 * CNAMES or DNAMES into other zones and prevents returning
712 	 * additional data from other zones.
713 	 */
714 	if (!client->view->additionalfromauth &&
715 	    client->query.authdbset &&
716 	    db != client->query.authdb)
717 		return (DNS_R_REFUSED);
718 
719 	/*
720 	 * Non recursive query to a static-stub zone is prohibited; its
721 	 * zone content is not public data, but a part of local configuration
722 	 * and should not be disclosed.
723 	 */
724 	if (dns_zone_gettype(zone) == dns_zone_staticstub &&
725 	    !RECURSIONOK(client)) {
726 		return (DNS_R_REFUSED);
727 	}
728 
729 	/*
730 	 * If the zone has an ACL, we'll check it, otherwise
731 	 * we use the view's "allow-query" ACL.  Each ACL is only checked
732 	 * once per query.
733 	 *
734 	 * Also, get the database version to use.
735 	 */
736 
737 	/*
738 	 * Get the current version of this database.
739 	 */
740 	dbversion = query_findversion(client, db);
741 	if (dbversion == NULL)
742 		return (DNS_R_SERVFAIL);
743 
744 	if ((options & DNS_GETDB_IGNOREACL) != 0)
745 		goto approved;
746 	if (dbversion->acl_checked) {
747 		if (!dbversion->queryok)
748 			return (DNS_R_REFUSED);
749 		goto approved;
750 	}
751 
752 	queryacl = dns_zone_getqueryacl(zone);
753 	if (queryacl == NULL) {
754 		queryacl = client->view->queryacl;
755 		if ((client->query.attributes &
756 		     NS_QUERYATTR_QUERYOKVALID) != 0) {
757 			/*
758 			 * We've evaluated the view's queryacl already.  If
759 			 * NS_QUERYATTR_QUERYOK is set, then the client is
760 			 * allowed to make queries, otherwise the query should
761 			 * be refused.
762 			 */
763 			dbversion->acl_checked = ISC_TRUE;
764 			if ((client->query.attributes &
765 			     NS_QUERYATTR_QUERYOK) == 0) {
766 				dbversion->queryok = ISC_FALSE;
767 				return (DNS_R_REFUSED);
768 			}
769 			dbversion->queryok = ISC_TRUE;
770 			goto approved;
771 		}
772 	}
773 
774 	result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
775 	if (result != ISC_R_SUCCESS)
776 		pfilter_notify(result, client, "validatezonedb");
777 	if ((options & DNS_GETDB_NOLOG) == 0) {
778 		char msg[NS_CLIENT_ACLMSGSIZE("query")];
779 		if (result == ISC_R_SUCCESS) {
780 			if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(3))) {
781 				ns_client_aclmsg("query", name, qtype,
782 						 client->view->rdclass,
783 						 msg, sizeof(msg));
784 				ns_client_log(client,
785 					      DNS_LOGCATEGORY_SECURITY,
786 					      NS_LOGMODULE_QUERY,
787 					      ISC_LOG_DEBUG(3),
788 					      "%s approved", msg);
789 			}
790 		} else {
791 			ns_client_aclmsg("query", name, qtype,
792 					 client->view->rdclass,
793 					 msg, sizeof(msg));
794 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
795 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
796 				      "%s denied", msg);
797 		}
798 	}
799 
800 	if (queryacl == client->view->queryacl) {
801 		if (result == ISC_R_SUCCESS) {
802 			/*
803 			 * We were allowed by the default
804 			 * "allow-query" ACL.  Remember this so we
805 			 * don't have to check again.
806 			 */
807 			client->query.attributes |= NS_QUERYATTR_QUERYOK;
808 		}
809 		/*
810 		 * We've now evaluated the view's query ACL, and
811 		 * the NS_QUERYATTR_QUERYOK attribute is now valid.
812 		 */
813 		client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
814 	}
815 
816 	/* If and only if we've gotten this far, check allow-query-on too */
817 	if (result == ISC_R_SUCCESS) {
818 		queryonacl = dns_zone_getqueryonacl(zone);
819 		if (queryonacl == NULL)
820 			queryonacl = client->view->queryonacl;
821 
822 		result = ns_client_checkaclsilent(client, &client->destaddr,
823 						  queryonacl, ISC_TRUE);
824 		if ((options & DNS_GETDB_NOLOG) == 0 &&
825 		    result != ISC_R_SUCCESS)
826 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
827 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
828 				      "query-on denied");
829 	}
830 
831 	dbversion->acl_checked = ISC_TRUE;
832 	if (result != ISC_R_SUCCESS) {
833 		dbversion->queryok = ISC_FALSE;
834 		return (DNS_R_REFUSED);
835 	}
836 	dbversion->queryok = ISC_TRUE;
837 
838  approved:
839 	/* Transfer ownership, if necessary. */
840 	if (versionp != NULL)
841 		*versionp = dbversion->version;
842 	return (ISC_R_SUCCESS);
843 }
844 
845 static inline isc_result_t
846 query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
847 		unsigned int options, dns_zone_t **zonep, dns_db_t **dbp,
848 		dns_dbversion_t **versionp)
849 {
850 	isc_result_t result;
851 	unsigned int ztoptions;
852 	dns_zone_t *zone = NULL;
853 	dns_db_t *db = NULL;
854 	isc_boolean_t partial = ISC_FALSE;
855 
856 	REQUIRE(zonep != NULL && *zonep == NULL);
857 	REQUIRE(dbp != NULL && *dbp == NULL);
858 
859 	/*%
860 	 * Find a zone database to answer the query.
861 	 */
862 	ztoptions = ((options & DNS_GETDB_NOEXACT) != 0) ?
863 		DNS_ZTFIND_NOEXACT : 0;
864 
865 	result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL,
866 			     &zone);
867 
868 	if (result == DNS_R_PARTIALMATCH)
869 		partial = ISC_TRUE;
870 	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
871 		result = dns_zone_getdb(zone, &db);
872 
873 	if (result != ISC_R_SUCCESS)
874 		goto fail;
875 
876 	result = query_validatezonedb(client, name, qtype, options, zone, db,
877 				      versionp);
878 
879 	if (result != ISC_R_SUCCESS)
880 		goto fail;
881 
882 	/* Transfer ownership. */
883 	*zonep = zone;
884 	*dbp = db;
885 
886 	if (partial && (options & DNS_GETDB_PARTIAL) != 0)
887 		return (DNS_R_PARTIALMATCH);
888 	return (ISC_R_SUCCESS);
889 
890  fail:
891 	if (zone != NULL)
892 		dns_zone_detach(&zone);
893 	if (db != NULL)
894 		dns_db_detach(&db);
895 
896 	return (result);
897 }
898 
899 static void
900 rpz_log_rewrite(ns_client_t *client, isc_boolean_t disabled,
901 		dns_rpz_policy_t policy, dns_rpz_type_t type,
902 		dns_zone_t *p_zone, dns_name_t *p_name)
903 {
904 	isc_stats_t *zonestats;
905 	char qname_buf[DNS_NAME_FORMATSIZE];
906 	char p_name_buf[DNS_NAME_FORMATSIZE];
907 
908 	/*
909 	 * Count enabled rewrites in the global counter.
910 	 * Count both enabled and disabled rewrites for each zone.
911 	 */
912 	if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) {
913 		isc_stats_increment(ns_g_server->nsstats,
914 				    dns_nsstatscounter_rpz_rewrites);
915 	}
916 	if (p_zone != NULL) {
917 		zonestats = dns_zone_getrequeststats(p_zone);
918 		if (zonestats != NULL)
919 			isc_stats_increment(zonestats,
920 					    dns_nsstatscounter_rpz_rewrites);
921 	}
922 
923 	if (!isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL))
924 		return;
925 
926 	dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf));
927 	dns_name_format(p_name, p_name_buf, sizeof(p_name_buf));
928 
929 	ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY,
930 		      DNS_RPZ_INFO_LEVEL, "%srpz %s %s rewrite %s via %s",
931 		      disabled ? "disabled " : "",
932 		      dns_rpz_type2str(type), dns_rpz_policy2str(policy),
933 		      qname_buf, p_name_buf);
934 }
935 
936 static void
937 rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name,
938 	     dns_rpz_type_t rpz_type, const char *str, isc_result_t result)
939 {
940 	char qnamebuf[DNS_NAME_FORMATSIZE];
941 	char p_namebuf[DNS_NAME_FORMATSIZE];
942 	const char *failed;
943 
944 	if (!isc_log_wouldlog(ns_g_lctx, level))
945 		return;
946 
947 	/*
948 	 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed" for problems.
949 	 */
950 	if (level <= DNS_RPZ_DEBUG_LEVEL1)
951 		failed = "failed: ";
952 	else
953 		failed = ": ";
954 	dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf));
955 	dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
956 	ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS,
957 		      NS_LOGMODULE_QUERY, level,
958 		      "rpz %s rewrite %s via %s%s%s%s",
959 		      dns_rpz_type2str(rpz_type),
960 		      qnamebuf, p_namebuf,
961 		      str, failed, isc_result_totext(result));
962 }
963 
964 /*
965  * Get a policy rewrite zone database.
966  */
967 static isc_result_t
968 rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type,
969 	  dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp)
970 {
971 	char qnamebuf[DNS_NAME_FORMATSIZE];
972 	char p_namebuf[DNS_NAME_FORMATSIZE];
973 	dns_dbversion_t *rpz_version = NULL;
974 	isc_result_t result;
975 
976 	CTRACE("rpz_getdb");
977 
978 	result = query_getzonedb(client, p_name, dns_rdatatype_any,
979 				 DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version);
980 	if (result == ISC_R_SUCCESS) {
981 		if (isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) {
982 			dns_name_format(client->query.qname, qnamebuf,
983 					sizeof(qnamebuf));
984 			dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
985 			ns_client_log(client, DNS_LOGCATEGORY_RPZ,
986 				      NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2,
987 				      "try rpz %s rewrite %s via %s",
988 				      dns_rpz_type2str(rpz_type),
989 				      qnamebuf, p_namebuf);
990 		}
991 		*versionp = rpz_version;
992 		return (ISC_R_SUCCESS);
993 	}
994 	rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
995 		     " query_getzonedb()", result);
996 	return (result);
997 }
998 
999 static inline isc_result_t
1000 query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
1001 		 dns_db_t **dbp, unsigned int options)
1002 {
1003 	isc_result_t result;
1004 	isc_boolean_t check_acl;
1005 	dns_db_t *db = NULL;
1006 
1007 	REQUIRE(dbp != NULL && *dbp == NULL);
1008 
1009 	/*%
1010 	 * Find a cache database to answer the query.
1011 	 * This may fail with DNS_R_REFUSED if the client
1012 	 * is not allowed to use the cache.
1013 	 */
1014 
1015 	if (!USECACHE(client))
1016 		return (DNS_R_REFUSED);
1017 	dns_db_attach(client->view->cachedb, &db);
1018 
1019 	if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) != 0) {
1020 		/*
1021 		 * We've evaluated the view's cacheacl already.  If
1022 		 * NS_QUERYATTR_CACHEACLOK is set, then the client is
1023 		 * allowed to make queries, otherwise the query should
1024 		 * be refused.
1025 		 */
1026 		check_acl = ISC_FALSE;
1027 		if ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) == 0)
1028 			goto refuse;
1029 	} else {
1030 		/*
1031 		 * We haven't evaluated the view's queryacl yet.
1032 		 */
1033 		check_acl = ISC_TRUE;
1034 	}
1035 
1036 	if (check_acl) {
1037 		isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0);
1038 		char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")];
1039 
1040 		result = ns_client_checkaclsilent(client, NULL,
1041 						  client->view->cacheacl,
1042 						  ISC_TRUE);
1043 		if (result == ISC_R_SUCCESS)
1044 			pfilter_notify(result, client, "cachedb");
1045 		if (result == ISC_R_SUCCESS) {
1046 			/*
1047 			 * We were allowed by the "allow-query-cache" ACL.
1048 			 * Remember this so we don't have to check again.
1049 			 */
1050 			client->query.attributes |=
1051 				NS_QUERYATTR_CACHEACLOK;
1052 			if (log && isc_log_wouldlog(ns_g_lctx,
1053 						     ISC_LOG_DEBUG(3)))
1054 			{
1055 				ns_client_aclmsg("query (cache)", name, qtype,
1056 						 client->view->rdclass,
1057 						 msg, sizeof(msg));
1058 				ns_client_log(client,
1059 					      DNS_LOGCATEGORY_SECURITY,
1060 					      NS_LOGMODULE_QUERY,
1061 					      ISC_LOG_DEBUG(3),
1062 					      "%s approved", msg);
1063 			}
1064 		} else if (log) {
1065 			ns_client_aclmsg("query (cache)", name, qtype,
1066 					 client->view->rdclass, msg,
1067 					 sizeof(msg));
1068 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1069 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
1070 				      "%s denied", msg);
1071 		}
1072 		/*
1073 		 * We've now evaluated the view's query ACL, and
1074 		 * the NS_QUERYATTR_CACHEACLOKVALID attribute is now valid.
1075 		 */
1076 		client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID;
1077 
1078 		if (result != ISC_R_SUCCESS)
1079 			goto refuse;
1080 	}
1081 
1082 	/* Approved. */
1083 
1084 	/* Transfer ownership. */
1085 	*dbp = db;
1086 
1087 	return (ISC_R_SUCCESS);
1088 
1089  refuse:
1090 	result = DNS_R_REFUSED;
1091 
1092 	if (db != NULL)
1093 		dns_db_detach(&db);
1094 
1095 	return (result);
1096 }
1097 
1098 
1099 static inline isc_result_t
1100 query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
1101 	    unsigned int options, dns_zone_t **zonep, dns_db_t **dbp,
1102 	    dns_dbversion_t **versionp, isc_boolean_t *is_zonep)
1103 {
1104 	isc_result_t result;
1105 
1106 	isc_result_t tresult;
1107 	unsigned int namelabels;
1108 	unsigned int zonelabels;
1109 	dns_zone_t *zone = NULL;
1110 	dns_db_t *tdbp;
1111 
1112 	REQUIRE(zonep != NULL && *zonep == NULL);
1113 
1114 	tdbp = NULL;
1115 
1116 	/* Calculate how many labels are in name. */
1117 	namelabels = dns_name_countlabels(name);
1118 	zonelabels = 0;
1119 
1120 	/* Try to find name in bind's standard database. */
1121 	result = query_getzonedb(client, name, qtype, options, &zone,
1122 				 dbp, versionp);
1123 
1124 	/* See how many labels are in the zone's name.	  */
1125 	if (result == ISC_R_SUCCESS && zone != NULL)
1126 		zonelabels = dns_name_countlabels(dns_zone_getorigin(zone));
1127 
1128 	/*
1129 	 * If # zone labels < # name labels, try to find an even better match
1130 	 * Only try if DLZ drivers are loaded for this view
1131 	 */
1132 	if (zonelabels < namelabels &&
1133 	    !ISC_LIST_EMPTY(client->view->dlz_searched))
1134 	{
1135 		dns_clientinfomethods_t cm;
1136 		dns_clientinfo_t ci;
1137 
1138 		dns_clientinfomethods_init(&cm, ns_client_sourceip);
1139 		dns_clientinfo_init(&ci, client);
1140 
1141 		tresult = dns_view_searchdlz(client->view, name,
1142 					     zonelabels, &cm, &ci, &tdbp);
1143 		 /* If we successful, we found a better match. */
1144 		if (tresult == ISC_R_SUCCESS) {
1145 			/*
1146 			 * If the previous search returned a zone, detach it.
1147 			 */
1148 			if (zone != NULL)
1149 				dns_zone_detach(&zone);
1150 
1151 			/*
1152 			 * If the previous search returned a database,
1153 			 * detach it.
1154 			 */
1155 			if (*dbp != NULL)
1156 				dns_db_detach(dbp);
1157 
1158 			/*
1159 			 * If the previous search returned a version, clear it.
1160 			 */
1161 			*versionp = NULL;
1162 
1163 			/*
1164 			 * Get our database version.
1165 			 */
1166 			dns_db_currentversion(tdbp, versionp);
1167 
1168 			/*
1169 			 * Be sure to return our database.
1170 			 */
1171 			*dbp = tdbp;
1172 
1173 			/*
1174 			 * We return a null zone, No stats for DLZ zones.
1175 			 */
1176 			zone = NULL;
1177 			result = tresult;
1178 		}
1179 	}
1180 
1181 	/* If successful, Transfer ownership of zone. */
1182 	if (result == ISC_R_SUCCESS) {
1183 		*zonep = zone;
1184 		/*
1185 		 * If neither attempt above succeeded, return the cache instead
1186 		 */
1187 		*is_zonep = ISC_TRUE;
1188 	} else if (result == ISC_R_NOTFOUND) {
1189 		result = query_getcachedb(client, name, qtype, dbp, options);
1190 		*is_zonep = ISC_FALSE;
1191 	}
1192 	return (result);
1193 }
1194 
1195 static inline isc_boolean_t
1196 query_isduplicate(ns_client_t *client, dns_name_t *name,
1197 		  dns_rdatatype_t type, dns_name_t **mnamep)
1198 {
1199 	dns_section_t section;
1200 	dns_name_t *mname = NULL;
1201 	isc_result_t result;
1202 
1203 	CTRACE("query_isduplicate");
1204 
1205 	for (section = DNS_SECTION_ANSWER;
1206 	     section <= DNS_SECTION_ADDITIONAL;
1207 	     section++) {
1208 		result = dns_message_findname(client->message, section,
1209 					      name, type, 0, &mname, NULL);
1210 		if (result == ISC_R_SUCCESS) {
1211 			/*
1212 			 * We've already got this RRset in the response.
1213 			 */
1214 			CTRACE("query_isduplicate: true: done");
1215 			return (ISC_TRUE);
1216 		} else if (result == DNS_R_NXRRSET) {
1217 			/*
1218 			 * The name exists, but the rdataset does not.
1219 			 */
1220 			if (section == DNS_SECTION_ADDITIONAL)
1221 				break;
1222 		} else
1223 			RUNTIME_CHECK(result == DNS_R_NXDOMAIN);
1224 		mname = NULL;
1225 	}
1226 
1227 	if (mnamep != NULL)
1228 		*mnamep = mname;
1229 
1230 	CTRACE("query_isduplicate: false: done");
1231 	return (ISC_FALSE);
1232 }
1233 
1234 static isc_result_t
1235 query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
1236 	ns_client_t *client = arg;
1237 	isc_result_t result, eresult;
1238 	dns_dbnode_t *node;
1239 	dns_db_t *db;
1240 	dns_name_t *fname, *mname;
1241 	dns_rdataset_t *rdataset, *sigrdataset, *trdataset;
1242 	isc_buffer_t *dbuf;
1243 	isc_buffer_t b;
1244 	dns_dbversion_t *version;
1245 	isc_boolean_t added_something, need_addname;
1246 	dns_zone_t *zone;
1247 	dns_rdatatype_t type;
1248 	dns_clientinfomethods_t cm;
1249 	dns_clientinfo_t ci;
1250 
1251 	REQUIRE(NS_CLIENT_VALID(client));
1252 	REQUIRE(qtype != dns_rdatatype_any);
1253 
1254 	if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype))
1255 		return (ISC_R_SUCCESS);
1256 
1257 	CTRACE("query_addadditional");
1258 
1259 	/*
1260 	 * Initialization.
1261 	 */
1262 	eresult = ISC_R_SUCCESS;
1263 	fname = NULL;
1264 	rdataset = NULL;
1265 	sigrdataset = NULL;
1266 	trdataset = NULL;
1267 	db = NULL;
1268 	version = NULL;
1269 	node = NULL;
1270 	added_something = ISC_FALSE;
1271 	need_addname = ISC_FALSE;
1272 	zone = NULL;
1273 
1274 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
1275 	dns_clientinfo_init(&ci, client);
1276 
1277 	/*
1278 	 * We treat type A additional section processing as if it
1279 	 * were "any address type" additional section processing.
1280 	 * To avoid multiple lookups, we do an 'any' database
1281 	 * lookup and iterate over the node.
1282 	 */
1283 	if (qtype == dns_rdatatype_a)
1284 		type = dns_rdatatype_any;
1285 	else
1286 		type = qtype;
1287 
1288 	/*
1289 	 * Get some resources.
1290 	 */
1291 	dbuf = query_getnamebuf(client);
1292 	if (dbuf == NULL)
1293 		goto cleanup;
1294 	fname = query_newname(client, dbuf, &b);
1295 	rdataset = query_newrdataset(client);
1296 	if (fname == NULL || rdataset == NULL)
1297 		goto cleanup;
1298 	if (WANTDNSSEC(client)) {
1299 		sigrdataset = query_newrdataset(client);
1300 		if (sigrdataset == NULL)
1301 			goto cleanup;
1302 	}
1303 
1304 	/*
1305 	 * Look for a zone database that might contain authoritative
1306 	 * additional data.
1307 	 */
1308 	result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG,
1309 				 &zone, &db, &version);
1310 	if (result != ISC_R_SUCCESS)
1311 		goto try_cache;
1312 
1313 	CTRACE("query_addadditional: db_find");
1314 
1315 	/*
1316 	 * Since we are looking for authoritative data, we do not set
1317 	 * the GLUEOK flag.  Glue will be looked for later, but not
1318 	 * necessarily in the same database.
1319 	 */
1320 	node = NULL;
1321 	result = dns_db_findext(db, name, version, type,
1322 				client->query.dboptions,
1323 				client->now, &node, fname, &cm, &ci,
1324 				rdataset, sigrdataset);
1325 	if (result == ISC_R_SUCCESS) {
1326 		if (sigrdataset != NULL && !dns_db_issecure(db) &&
1327 		    dns_rdataset_isassociated(sigrdataset))
1328 			dns_rdataset_disassociate(sigrdataset);
1329 		goto found;
1330 	}
1331 
1332 	if (dns_rdataset_isassociated(rdataset))
1333 		dns_rdataset_disassociate(rdataset);
1334 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
1335 		dns_rdataset_disassociate(sigrdataset);
1336 	if (node != NULL)
1337 		dns_db_detachnode(db, &node);
1338 	version = NULL;
1339 	dns_db_detach(&db);
1340 
1341 	/*
1342 	 * No authoritative data was found.  The cache is our next best bet.
1343 	 */
1344 
1345  try_cache:
1346 	result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG);
1347 	if (result != ISC_R_SUCCESS)
1348 		/*
1349 		 * Most likely the client isn't allowed to query the cache.
1350 		 */
1351 		goto try_glue;
1352 	/*
1353 	 * Attempt to validate glue.
1354 	 */
1355 	if (sigrdataset == NULL) {
1356 		sigrdataset = query_newrdataset(client);
1357 		if (sigrdataset == NULL)
1358 			goto cleanup;
1359 	}
1360 	result = dns_db_findext(db, name, version, type,
1361 				client->query.dboptions |
1362 				 DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
1363 				client->now, &node, fname, &cm, &ci,
1364 				rdataset, sigrdataset);
1365 
1366 	dns_cache_updatestats(client->view->cache, result);
1367 	if (result == DNS_R_GLUE &&
1368 	    validate(client, db, fname, rdataset, sigrdataset))
1369 		result = ISC_R_SUCCESS;
1370 	if (!WANTDNSSEC(client))
1371 		query_putrdataset(client, &sigrdataset);
1372 	if (result == ISC_R_SUCCESS)
1373 		goto found;
1374 
1375 
1376 	if (dns_rdataset_isassociated(rdataset))
1377 		dns_rdataset_disassociate(rdataset);
1378 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
1379 		dns_rdataset_disassociate(sigrdataset);
1380 	if (node != NULL)
1381 		dns_db_detachnode(db, &node);
1382 	dns_db_detach(&db);
1383 
1384  try_glue:
1385 	/*
1386 	 * No cached data was found.  Glue is our last chance.
1387 	 * RFC1035 sayeth:
1388 	 *
1389 	 *	NS records cause both the usual additional section
1390 	 *	processing to locate a type A record, and, when used
1391 	 *	in a referral, a special search of the zone in which
1392 	 *	they reside for glue information.
1393 	 *
1394 	 * This is the "special search".  Note that we must search
1395 	 * the zone where the NS record resides, not the zone it
1396 	 * points to, and that we only do the search in the delegation
1397 	 * case (identified by client->query.gluedb being set).
1398 	 */
1399 
1400 	if (client->query.gluedb == NULL)
1401 		goto cleanup;
1402 
1403 	/*
1404 	 * Don't poison caches using the bailiwick protection model.
1405 	 */
1406 	if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb)))
1407 		goto cleanup;
1408 
1409 	dns_db_attach(client->query.gluedb, &db);
1410 	result = dns_db_findext(db, name, version, type,
1411 				client->query.dboptions | DNS_DBFIND_GLUEOK,
1412 				client->now, &node, fname, &cm, &ci,
1413 				rdataset, sigrdataset);
1414 	if (!(result == ISC_R_SUCCESS ||
1415 	      result == DNS_R_ZONECUT ||
1416 	      result == DNS_R_GLUE))
1417 		goto cleanup;
1418 
1419  found:
1420 	/*
1421 	 * We have found a potential additional data rdataset, or
1422 	 * at least a node to iterate over.
1423 	 */
1424 	query_keepname(client, fname, dbuf);
1425 
1426 	/*
1427 	 * If we have an rdataset, add it to the additional data
1428 	 * section.
1429 	 */
1430 	mname = NULL;
1431 	if (dns_rdataset_isassociated(rdataset) &&
1432 	    !query_isduplicate(client, fname, type, &mname)) {
1433 		if (mname != NULL) {
1434 			INSIST(mname != fname);
1435 			query_releasename(client, &fname);
1436 			fname = mname;
1437 		} else
1438 			need_addname = ISC_TRUE;
1439 		ISC_LIST_APPEND(fname->list, rdataset, link);
1440 		trdataset = rdataset;
1441 		rdataset = NULL;
1442 		added_something = ISC_TRUE;
1443 		/*
1444 		 * Note: we only add SIGs if we've added the type they cover,
1445 		 * so we do not need to check if the SIG rdataset is already
1446 		 * in the response.
1447 		 */
1448 		if (sigrdataset != NULL &&
1449 		    dns_rdataset_isassociated(sigrdataset))
1450 		{
1451 			ISC_LIST_APPEND(fname->list, sigrdataset, link);
1452 			sigrdataset = NULL;
1453 		}
1454 	}
1455 
1456 	if (qtype == dns_rdatatype_a) {
1457 #ifdef ALLOW_FILTER_AAAA
1458 		isc_boolean_t have_a = ISC_FALSE;
1459 #endif
1460 
1461 		/*
1462 		 * We now go looking for A and AAAA records, along with
1463 		 * their signatures.
1464 		 *
1465 		 * XXXRTH  This code could be more efficient.
1466 		 */
1467 		if (rdataset != NULL) {
1468 			if (dns_rdataset_isassociated(rdataset))
1469 				dns_rdataset_disassociate(rdataset);
1470 		} else {
1471 			rdataset = query_newrdataset(client);
1472 			if (rdataset == NULL)
1473 				goto addname;
1474 		}
1475 		if (sigrdataset != NULL) {
1476 			if (dns_rdataset_isassociated(sigrdataset))
1477 				dns_rdataset_disassociate(sigrdataset);
1478 		} else if (WANTDNSSEC(client)) {
1479 			sigrdataset = query_newrdataset(client);
1480 			if (sigrdataset == NULL)
1481 				goto addname;
1482 		}
1483 		if (query_isduplicate(client, fname, dns_rdatatype_a, NULL))
1484 			goto aaaa_lookup;
1485 		result = dns_db_findrdataset(db, node, version,
1486 					     dns_rdatatype_a, 0,
1487 					     client->now,
1488 					     rdataset, sigrdataset);
1489 		if (result == DNS_R_NCACHENXDOMAIN)
1490 			goto addname;
1491 		if (result == DNS_R_NCACHENXRRSET) {
1492 			dns_rdataset_disassociate(rdataset);
1493 			if (sigrdataset != NULL &&
1494 			    dns_rdataset_isassociated(sigrdataset))
1495 				dns_rdataset_disassociate(sigrdataset);
1496 		}
1497 		if (result == ISC_R_SUCCESS) {
1498 			mname = NULL;
1499 #ifdef ALLOW_FILTER_AAAA
1500 			have_a = ISC_TRUE;
1501 #endif
1502 			if (!query_isduplicate(client, fname,
1503 					       dns_rdatatype_a, &mname)) {
1504 				if (mname != fname) {
1505 					if (mname != NULL) {
1506 						query_releasename(client, &fname);
1507 						fname = mname;
1508 					} else
1509 						need_addname = ISC_TRUE;
1510 				}
1511 				ISC_LIST_APPEND(fname->list, rdataset, link);
1512 				added_something = ISC_TRUE;
1513 				if (sigrdataset != NULL &&
1514 				    dns_rdataset_isassociated(sigrdataset))
1515 				{
1516 					ISC_LIST_APPEND(fname->list,
1517 							sigrdataset, link);
1518 					sigrdataset =
1519 						query_newrdataset(client);
1520 				}
1521 				rdataset = query_newrdataset(client);
1522 				if (rdataset == NULL)
1523 					goto addname;
1524 				if (WANTDNSSEC(client) && sigrdataset == NULL)
1525 					goto addname;
1526 			} else {
1527 				dns_rdataset_disassociate(rdataset);
1528 				if (sigrdataset != NULL &&
1529 				    dns_rdataset_isassociated(sigrdataset))
1530 					dns_rdataset_disassociate(sigrdataset);
1531 			}
1532 		}
1533   aaaa_lookup:
1534 		if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL))
1535 			goto addname;
1536 		result = dns_db_findrdataset(db, node, version,
1537 					     dns_rdatatype_aaaa, 0,
1538 					     client->now,
1539 					     rdataset, sigrdataset);
1540 		if (result == DNS_R_NCACHENXDOMAIN)
1541 			goto addname;
1542 		if (result == DNS_R_NCACHENXRRSET) {
1543 			dns_rdataset_disassociate(rdataset);
1544 			if (sigrdataset != NULL &&
1545 			    dns_rdataset_isassociated(sigrdataset))
1546 				dns_rdataset_disassociate(sigrdataset);
1547 		}
1548 		if (result == ISC_R_SUCCESS) {
1549 			mname = NULL;
1550 			/*
1551 			 * There's an A; check whether we're filtering AAAA
1552 			 */
1553 #ifdef ALLOW_FILTER_AAAA
1554 			if (have_a &&
1555 			    (client->filter_aaaa == dns_aaaa_break_dnssec ||
1556 			    (client->filter_aaaa == dns_aaaa_filter &&
1557 			     (!WANTDNSSEC(client) || sigrdataset == NULL ||
1558 			      !dns_rdataset_isassociated(sigrdataset)))))
1559 				goto addname;
1560 #endif
1561 			if (!query_isduplicate(client, fname,
1562 					       dns_rdatatype_aaaa, &mname)) {
1563 				if (mname != fname) {
1564 					if (mname != NULL) {
1565 						query_releasename(client, &fname);
1566 						fname = mname;
1567 					} else
1568 						need_addname = ISC_TRUE;
1569 				}
1570 				ISC_LIST_APPEND(fname->list, rdataset, link);
1571 				added_something = ISC_TRUE;
1572 				if (sigrdataset != NULL &&
1573 				    dns_rdataset_isassociated(sigrdataset))
1574 				{
1575 					ISC_LIST_APPEND(fname->list,
1576 							sigrdataset, link);
1577 					sigrdataset = NULL;
1578 				}
1579 				rdataset = NULL;
1580 			}
1581 		}
1582 	}
1583 
1584  addname:
1585 	CTRACE("query_addadditional: addname");
1586 	/*
1587 	 * If we haven't added anything, then we're done.
1588 	 */
1589 	if (!added_something)
1590 		goto cleanup;
1591 
1592 	/*
1593 	 * We may have added our rdatasets to an existing name, if so, then
1594 	 * need_addname will be ISC_FALSE.  Whether we used an existing name
1595 	 * or a new one, we must set fname to NULL to prevent cleanup.
1596 	 */
1597 	if (need_addname)
1598 		dns_message_addname(client->message, fname,
1599 				    DNS_SECTION_ADDITIONAL);
1600 	fname = NULL;
1601 
1602 	/*
1603 	 * In a few cases, we want to add additional data for additional
1604 	 * data.  It's simpler to just deal with special cases here than
1605 	 * to try to create a general purpose mechanism and allow the
1606 	 * rdata implementations to do it themselves.
1607 	 *
1608 	 * This involves recursion, but the depth is limited.  The
1609 	 * most complex case is adding a SRV rdataset, which involves
1610 	 * recursing to add address records, which in turn can cause
1611 	 * recursion to add KEYs.
1612 	 */
1613 	if (type == dns_rdatatype_srv && trdataset != NULL) {
1614 		/*
1615 		 * If we're adding SRV records to the additional data
1616 		 * section, it's helpful if we add the SRV additional data
1617 		 * as well.
1618 		 */
1619 		eresult = dns_rdataset_additionaldata(trdataset,
1620 						      query_addadditional,
1621 						      client);
1622 	}
1623 
1624  cleanup:
1625 	CTRACE("query_addadditional: cleanup");
1626 	query_putrdataset(client, &rdataset);
1627 	if (sigrdataset != NULL)
1628 		query_putrdataset(client, &sigrdataset);
1629 	if (fname != NULL)
1630 		query_releasename(client, &fname);
1631 	if (node != NULL)
1632 		dns_db_detachnode(db, &node);
1633 	if (db != NULL)
1634 		dns_db_detach(&db);
1635 	if (zone != NULL)
1636 		dns_zone_detach(&zone);
1637 
1638 	CTRACE("query_addadditional: done");
1639 	return (eresult);
1640 }
1641 
1642 static inline void
1643 query_discardcache(ns_client_t *client, dns_rdataset_t *rdataset_base,
1644 		   dns_rdatasetadditional_t additionaltype,
1645 		   dns_rdatatype_t type, dns_zone_t **zonep, dns_db_t **dbp,
1646 		   dns_dbversion_t **versionp, dns_dbnode_t **nodep,
1647 		   dns_name_t *fname)
1648 {
1649 	dns_rdataset_t *rdataset;
1650 
1651 	while  ((rdataset = ISC_LIST_HEAD(fname->list)) != NULL) {
1652 		ISC_LIST_UNLINK(fname->list, rdataset, link);
1653 		query_putrdataset(client, &rdataset);
1654 	}
1655 	if (*versionp != NULL)
1656 		dns_db_closeversion(*dbp, versionp, ISC_FALSE);
1657 	if (*nodep != NULL)
1658 		dns_db_detachnode(*dbp, nodep);
1659 	if (*dbp != NULL)
1660 		dns_db_detach(dbp);
1661 	if (*zonep != NULL)
1662 		dns_zone_detach(zonep);
1663 	(void)dns_rdataset_putadditional(client->view->acache, rdataset_base,
1664 					 additionaltype, type);
1665 }
1666 
1667 static inline isc_result_t
1668 query_iscachevalid(dns_zone_t *zone, dns_db_t *db, dns_db_t *db0,
1669 		   dns_dbversion_t *version)
1670 {
1671 	isc_result_t result = ISC_R_SUCCESS;
1672 	dns_dbversion_t *version_current = NULL;
1673 	dns_db_t *db_current = db0;
1674 
1675 	if (db_current == NULL) {
1676 		result = dns_zone_getdb(zone, &db_current);
1677 		if (result != ISC_R_SUCCESS)
1678 			return (result);
1679 	}
1680 	dns_db_currentversion(db_current, &version_current);
1681 	if (db_current != db || version_current != version) {
1682 		result = ISC_R_FAILURE;
1683 		goto cleanup;
1684 	}
1685 
1686  cleanup:
1687 	dns_db_closeversion(db_current, &version_current, ISC_FALSE);
1688 	if (db0 == NULL && db_current != NULL)
1689 		dns_db_detach(&db_current);
1690 
1691 	return (result);
1692 }
1693 
1694 static isc_result_t
1695 query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
1696 	client_additionalctx_t *additionalctx = arg;
1697 	dns_rdataset_t *rdataset_base;
1698 	ns_client_t *client;
1699 	isc_result_t result, eresult;
1700 	dns_dbnode_t *node, *cnode;
1701 	dns_db_t *db, *cdb;
1702 	dns_name_t *fname, *mname0, cfname;
1703 	dns_rdataset_t *rdataset, *sigrdataset;
1704 	dns_rdataset_t *crdataset, *crdataset_next;
1705 	isc_buffer_t *dbuf;
1706 	isc_buffer_t b;
1707 	dns_dbversion_t *version, *cversion;
1708 	isc_boolean_t added_something, need_addname, needadditionalcache;
1709 	isc_boolean_t need_sigrrset;
1710 	dns_zone_t *zone;
1711 	dns_rdatatype_t type;
1712 	dns_rdatasetadditional_t additionaltype;
1713 	dns_clientinfomethods_t cm;
1714 	dns_clientinfo_t ci;
1715 
1716 	/*
1717 	 * If we don't have an additional cache call query_addadditional.
1718 	 */
1719 	client = additionalctx->client;
1720 	REQUIRE(NS_CLIENT_VALID(client));
1721 
1722 	if (qtype != dns_rdatatype_a || client->view->acache == NULL) {
1723 		/*
1724 		 * This function is optimized for "address" types.  For other
1725 		 * types, use a generic routine.
1726 		 * XXX: ideally, this function should be generic enough.
1727 		 */
1728 		return (query_addadditional(additionalctx->client,
1729 					    name, qtype));
1730 	}
1731 
1732 	/*
1733 	 * Initialization.
1734 	 */
1735 	rdataset_base = additionalctx->rdataset;
1736 	eresult = ISC_R_SUCCESS;
1737 	fname = NULL;
1738 	rdataset = NULL;
1739 	sigrdataset = NULL;
1740 	db = NULL;
1741 	cdb = NULL;
1742 	version = NULL;
1743 	cversion = NULL;
1744 	node = NULL;
1745 	cnode = NULL;
1746 	added_something = ISC_FALSE;
1747 	need_addname = ISC_FALSE;
1748 	zone = NULL;
1749 	needadditionalcache = ISC_FALSE;
1750 	POST(needadditionalcache);
1751 	additionaltype = dns_rdatasetadditional_fromauth;
1752 	dns_name_init(&cfname, NULL);
1753 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
1754 	dns_clientinfo_init(&ci, client);
1755 
1756 	CTRACE("query_addadditional2");
1757 
1758 	/*
1759 	 * We treat type A additional section processing as if it
1760 	 * were "any address type" additional section processing.
1761 	 * To avoid multiple lookups, we do an 'any' database
1762 	 * lookup and iterate over the node.
1763 	 * XXXJT: this approach can cause a suboptimal result when the cache
1764 	 * DB only has partial address types and the glue DB has remaining
1765 	 * ones.
1766 	 */
1767 	type = dns_rdatatype_any;
1768 
1769 	/*
1770 	 * Get some resources.
1771 	 */
1772 	dbuf = query_getnamebuf(client);
1773 	if (dbuf == NULL)
1774 		goto cleanup;
1775 	fname = query_newname(client, dbuf, &b);
1776 	if (fname == NULL)
1777 		goto cleanup;
1778 	dns_name_setbuffer(&cfname, &b); /* share the buffer */
1779 
1780 	/* Check additional cache */
1781 	result = dns_rdataset_getadditional(rdataset_base, additionaltype,
1782 					    type, client->view->acache, &zone,
1783 					    &cdb, &cversion, &cnode, &cfname,
1784 					    client->message, client->now);
1785 	if (result != ISC_R_SUCCESS)
1786 		goto findauthdb;
1787 	if (zone == NULL) {
1788 		CTRACE("query_addadditional2: auth zone not found");
1789 		goto try_cache;
1790 	}
1791 
1792 	/* Is the cached DB up-to-date? */
1793 	result = query_iscachevalid(zone, cdb, NULL, cversion);
1794 	if (result != ISC_R_SUCCESS) {
1795 		CTRACE("query_addadditional2: old auth additional cache");
1796 		query_discardcache(client, rdataset_base, additionaltype,
1797 				   type, &zone, &cdb, &cversion, &cnode,
1798 				   &cfname);
1799 		goto findauthdb;
1800 	}
1801 
1802 	if (cnode == NULL) {
1803 		/*
1804 		 * We have a negative cache.  We don't have to check the zone
1805 		 * ACL, since the result (not using this zone) would be same
1806 		 * regardless of the result.
1807 		 */
1808 		CTRACE("query_addadditional2: negative auth additional cache");
1809 		dns_db_closeversion(cdb, &cversion, ISC_FALSE);
1810 		dns_db_detach(&cdb);
1811 		dns_zone_detach(&zone);
1812 		goto try_cache;
1813 	}
1814 
1815 	result = query_validatezonedb(client, name, qtype, DNS_GETDB_NOLOG,
1816 				      zone, cdb, NULL);
1817 	if (result != ISC_R_SUCCESS) {
1818 		query_discardcache(client, rdataset_base, additionaltype,
1819 				   type, &zone, &cdb, &cversion, &cnode,
1820 				   &cfname);
1821 		goto try_cache;
1822 	}
1823 
1824 	/* We've got an active cache. */
1825 	CTRACE("query_addadditional2: auth additional cache");
1826 	dns_db_closeversion(cdb, &cversion, ISC_FALSE);
1827 	db = cdb;
1828 	node = cnode;
1829 	dns_name_clone(&cfname, fname);
1830 	query_keepname(client, fname, dbuf);
1831 	goto foundcache;
1832 
1833 	/*
1834 	 * Look for a zone database that might contain authoritative
1835 	 * additional data.
1836 	 */
1837  findauthdb:
1838 	result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG,
1839 				 &zone, &db, &version);
1840 	if (result != ISC_R_SUCCESS) {
1841 		/* Cache the negative result */
1842 		(void)dns_rdataset_setadditional(rdataset_base, additionaltype,
1843 						 type, client->view->acache,
1844 						 NULL, NULL, NULL, NULL,
1845 						 NULL);
1846 		goto try_cache;
1847 	}
1848 
1849 	CTRACE("query_addadditional2: db_find");
1850 
1851 	/*
1852 	 * Since we are looking for authoritative data, we do not set
1853 	 * the GLUEOK flag.  Glue will be looked for later, but not
1854 	 * necessarily in the same database.
1855 	 */
1856 	node = NULL;
1857 	result = dns_db_findext(db, name, version, type,
1858 				client->query.dboptions,
1859 				client->now, &node, fname, &cm, &ci,
1860 				NULL, NULL);
1861 	if (result == ISC_R_SUCCESS)
1862 		goto found;
1863 
1864 	/* Cache the negative result */
1865 	(void)dns_rdataset_setadditional(rdataset_base, additionaltype,
1866 					 type, client->view->acache, zone, db,
1867 					 version, NULL, fname);
1868 
1869 	if (node != NULL)
1870 		dns_db_detachnode(db, &node);
1871 	version = NULL;
1872 	dns_db_detach(&db);
1873 
1874 	/*
1875 	 * No authoritative data was found.  The cache is our next best bet.
1876 	 */
1877 
1878  try_cache:
1879 	additionaltype = dns_rdatasetadditional_fromcache;
1880 	result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG);
1881 	if (result != ISC_R_SUCCESS)
1882 		/*
1883 		 * Most likely the client isn't allowed to query the cache.
1884 		 */
1885 		goto try_glue;
1886 
1887 	result = dns_db_findext(db, name, version, type,
1888 				client->query.dboptions |
1889 				 DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
1890 				client->now, &node, fname, &cm, &ci,
1891 				NULL, NULL);
1892 	if (result == ISC_R_SUCCESS)
1893 		goto found;
1894 
1895 	if (node != NULL)
1896 		dns_db_detachnode(db, &node);
1897 	dns_db_detach(&db);
1898 
1899  try_glue:
1900 	/*
1901 	 * No cached data was found.  Glue is our last chance.
1902 	 * RFC1035 sayeth:
1903 	 *
1904 	 *	NS records cause both the usual additional section
1905 	 *	processing to locate a type A record, and, when used
1906 	 *	in a referral, a special search of the zone in which
1907 	 *	they reside for glue information.
1908 	 *
1909 	 * This is the "special search".  Note that we must search
1910 	 * the zone where the NS record resides, not the zone it
1911 	 * points to, and that we only do the search in the delegation
1912 	 * case (identified by client->query.gluedb being set).
1913 	 */
1914 	if (client->query.gluedb == NULL)
1915 		goto cleanup;
1916 
1917 	/*
1918 	 * Don't poison caches using the bailiwick protection model.
1919 	 */
1920 	if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb)))
1921 		goto cleanup;
1922 
1923 	/* Check additional cache */
1924 	additionaltype = dns_rdatasetadditional_fromglue;
1925 	result = dns_rdataset_getadditional(rdataset_base, additionaltype,
1926 					    type, client->view->acache, NULL,
1927 					    &cdb, &cversion, &cnode, &cfname,
1928 					    client->message, client->now);
1929 	if (result != ISC_R_SUCCESS)
1930 		goto findglue;
1931 
1932 	result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion);
1933 	if (result != ISC_R_SUCCESS) {
1934 		CTRACE("query_addadditional2: old glue additional cache");
1935 		query_discardcache(client, rdataset_base, additionaltype,
1936 				   type, &zone, &cdb, &cversion, &cnode,
1937 				   &cfname);
1938 		goto findglue;
1939 	}
1940 
1941 	if (cnode == NULL) {
1942 		/* We have a negative cache. */
1943 		CTRACE("query_addadditional2: negative glue additional cache");
1944 		dns_db_closeversion(cdb, &cversion, ISC_FALSE);
1945 		dns_db_detach(&cdb);
1946 		goto cleanup;
1947 	}
1948 
1949 	/* Cache hit. */
1950 	CTRACE("query_addadditional2: glue additional cache");
1951 	dns_db_closeversion(cdb, &cversion, ISC_FALSE);
1952 	db = cdb;
1953 	node = cnode;
1954 	dns_name_clone(&cfname, fname);
1955 	query_keepname(client, fname, dbuf);
1956 	goto foundcache;
1957 
1958  findglue:
1959 	dns_db_attach(client->query.gluedb, &db);
1960 	result = dns_db_findext(db, name, version, type,
1961 				client->query.dboptions | DNS_DBFIND_GLUEOK,
1962 				client->now, &node, fname, &cm, &ci,
1963 				NULL, NULL);
1964 	if (!(result == ISC_R_SUCCESS ||
1965 	      result == DNS_R_ZONECUT ||
1966 	      result == DNS_R_GLUE)) {
1967 		/* cache the negative result */
1968 		(void)dns_rdataset_setadditional(rdataset_base, additionaltype,
1969 						 type, client->view->acache,
1970 						 NULL, db, version, NULL,
1971 						 fname);
1972 		goto cleanup;
1973 	}
1974 
1975  found:
1976 	/*
1977 	 * We have found a DB node to iterate over from a DB.
1978 	 * We are going to look for address RRsets (i.e., A and AAAA) in the DB
1979 	 * node we've just found.  We'll then store the complete information
1980 	 * in the additional data cache.
1981 	 */
1982 	dns_name_clone(fname, &cfname);
1983 	query_keepname(client, fname, dbuf);
1984 	needadditionalcache = ISC_TRUE;
1985 
1986 	rdataset = query_newrdataset(client);
1987 	if (rdataset == NULL)
1988 		goto cleanup;
1989 
1990 	sigrdataset = query_newrdataset(client);
1991 	if (sigrdataset == NULL)
1992 		goto cleanup;
1993 
1994 	if (additionaltype == dns_rdatasetadditional_fromcache &&
1995 	    query_isduplicate(client, fname, dns_rdatatype_a, NULL))
1996 		goto aaaa_lookup;
1997 	/*
1998 	 * Find A RRset with sig RRset.  Even if we don't find a sig RRset
1999 	 * for a client using DNSSEC, we'll continue the process to make a
2000 	 * complete list to be cached.  However, we need to cancel the
2001 	 * caching when something unexpected happens, in order to avoid
2002 	 * caching incomplete information.
2003 	 */
2004 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0,
2005 				     client->now, rdataset, sigrdataset);
2006 	/*
2007 	 * If we can't promote glue/pending from the cache to secure
2008 	 * then drop it.
2009 	 */
2010 	if (result == ISC_R_SUCCESS &&
2011 	    additionaltype == dns_rdatasetadditional_fromcache &&
2012 	    (DNS_TRUST_PENDING(rdataset->trust) ||
2013 	     DNS_TRUST_GLUE(rdataset->trust)) &&
2014 	    !validate(client, db, fname, rdataset, sigrdataset)) {
2015 		dns_rdataset_disassociate(rdataset);
2016 		if (dns_rdataset_isassociated(sigrdataset))
2017 			dns_rdataset_disassociate(sigrdataset);
2018 		result = ISC_R_NOTFOUND;
2019 	}
2020 	if (result == DNS_R_NCACHENXDOMAIN)
2021 		goto setcache;
2022 	if (result == DNS_R_NCACHENXRRSET) {
2023 		dns_rdataset_disassociate(rdataset);
2024 		if (dns_rdataset_isassociated(sigrdataset))
2025 			dns_rdataset_disassociate(sigrdataset);
2026 	}
2027 	if (result == ISC_R_SUCCESS) {
2028 		/* Remember the result as a cache */
2029 		ISC_LIST_APPEND(cfname.list, rdataset, link);
2030 		if (dns_rdataset_isassociated(sigrdataset)) {
2031 			ISC_LIST_APPEND(cfname.list, sigrdataset, link);
2032 			sigrdataset = query_newrdataset(client);
2033 		}
2034 		rdataset = query_newrdataset(client);
2035 		if (sigrdataset == NULL || rdataset == NULL) {
2036 			/* do not cache incomplete information */
2037 			goto foundcache;
2038 		}
2039 	}
2040 
2041  aaaa_lookup:
2042 	if (additionaltype == dns_rdatasetadditional_fromcache &&
2043 	    query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL))
2044 		goto foundcache;
2045 	/* Find AAAA RRset with sig RRset */
2046 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa,
2047 				     0, client->now, rdataset, sigrdataset);
2048 	/*
2049 	 * If we can't promote glue/pending from the cache to secure
2050 	 * then drop it.
2051 	 */
2052 	if (result == ISC_R_SUCCESS &&
2053 	    additionaltype == dns_rdatasetadditional_fromcache &&
2054 	    (DNS_TRUST_PENDING(rdataset->trust) ||
2055 	     DNS_TRUST_GLUE(rdataset->trust)) &&
2056 	    !validate(client, db, fname, rdataset, sigrdataset)) {
2057 		dns_rdataset_disassociate(rdataset);
2058 		if (dns_rdataset_isassociated(sigrdataset))
2059 			dns_rdataset_disassociate(sigrdataset);
2060 		result = ISC_R_NOTFOUND;
2061 	}
2062 	if (result == ISC_R_SUCCESS) {
2063 		ISC_LIST_APPEND(cfname.list, rdataset, link);
2064 		rdataset = NULL;
2065 		if (dns_rdataset_isassociated(sigrdataset)) {
2066 			ISC_LIST_APPEND(cfname.list, sigrdataset, link);
2067 			sigrdataset = NULL;
2068 		}
2069 	}
2070 
2071  setcache:
2072 	/*
2073 	 * Set the new result in the cache if required.  We do not support
2074 	 * caching additional data from a cache DB.
2075 	 */
2076 	if (needadditionalcache == ISC_TRUE &&
2077 	    (additionaltype == dns_rdatasetadditional_fromauth ||
2078 	     additionaltype == dns_rdatasetadditional_fromglue)) {
2079 		(void)dns_rdataset_setadditional(rdataset_base, additionaltype,
2080 						 type, client->view->acache,
2081 						 zone, db, version, node,
2082 						 &cfname);
2083 	}
2084 
2085  foundcache:
2086 	need_sigrrset = ISC_FALSE;
2087 	mname0 = NULL;
2088 	for (crdataset = ISC_LIST_HEAD(cfname.list);
2089 	     crdataset != NULL;
2090 	     crdataset = crdataset_next) {
2091 		dns_name_t *mname;
2092 
2093 		crdataset_next = ISC_LIST_NEXT(crdataset, link);
2094 
2095 		mname = NULL;
2096 		if (crdataset->type == dns_rdatatype_a ||
2097 		    crdataset->type == dns_rdatatype_aaaa) {
2098 			if (!query_isduplicate(client, fname, crdataset->type,
2099 					       &mname)) {
2100 				if (mname != fname) {
2101 					if (mname != NULL) {
2102 						/*
2103 						 * A different type of this name is
2104 						 * already stored in the additional
2105 						 * section.  We'll reuse the name.
2106 						 * Note that this should happen at most
2107 						 * once.  Otherwise, fname->link could
2108 						 * leak below.
2109 						 */
2110 						INSIST(mname0 == NULL);
2111 
2112 						query_releasename(client, &fname);
2113 						fname = mname;
2114 						mname0 = mname;
2115 					} else
2116 						need_addname = ISC_TRUE;
2117 				}
2118 				ISC_LIST_UNLINK(cfname.list, crdataset, link);
2119 				ISC_LIST_APPEND(fname->list, crdataset, link);
2120 				added_something = ISC_TRUE;
2121 				need_sigrrset = ISC_TRUE;
2122 			} else
2123 				need_sigrrset = ISC_FALSE;
2124 		} else if (crdataset->type == dns_rdatatype_rrsig &&
2125 			   need_sigrrset && WANTDNSSEC(client)) {
2126 			ISC_LIST_UNLINK(cfname.list, crdataset, link);
2127 			ISC_LIST_APPEND(fname->list, crdataset, link);
2128 			added_something = ISC_TRUE; /* just in case */
2129 			need_sigrrset = ISC_FALSE;
2130 		}
2131 	}
2132 
2133 	CTRACE("query_addadditional2: addname");
2134 
2135 	/*
2136 	 * If we haven't added anything, then we're done.
2137 	 */
2138 	if (!added_something)
2139 		goto cleanup;
2140 
2141 	/*
2142 	 * We may have added our rdatasets to an existing name, if so, then
2143 	 * need_addname will be ISC_FALSE.  Whether we used an existing name
2144 	 * or a new one, we must set fname to NULL to prevent cleanup.
2145 	 */
2146 	if (need_addname)
2147 		dns_message_addname(client->message, fname,
2148 				    DNS_SECTION_ADDITIONAL);
2149 	fname = NULL;
2150 
2151  cleanup:
2152 	CTRACE("query_addadditional2: cleanup");
2153 
2154 	if (rdataset != NULL)
2155 		query_putrdataset(client, &rdataset);
2156 	if (sigrdataset != NULL)
2157 		query_putrdataset(client, &sigrdataset);
2158 	while  ((crdataset = ISC_LIST_HEAD(cfname.list)) != NULL) {
2159 		ISC_LIST_UNLINK(cfname.list, crdataset, link);
2160 		query_putrdataset(client, &crdataset);
2161 	}
2162 	if (fname != NULL)
2163 		query_releasename(client, &fname);
2164 	if (node != NULL)
2165 		dns_db_detachnode(db, &node);
2166 	if (db != NULL)
2167 		dns_db_detach(&db);
2168 	if (zone != NULL)
2169 		dns_zone_detach(&zone);
2170 
2171 	CTRACE("query_addadditional2: done");
2172 	return (eresult);
2173 }
2174 
2175 static inline void
2176 query_addrdataset(ns_client_t *client, dns_name_t *fname,
2177 		  dns_rdataset_t *rdataset)
2178 {
2179 	client_additionalctx_t additionalctx;
2180 
2181 	/*
2182 	 * Add 'rdataset' and any pertinent additional data to
2183 	 * 'fname', a name in the response message for 'client'.
2184 	 */
2185 
2186 	CTRACE("query_addrdataset");
2187 
2188 	ISC_LIST_APPEND(fname->list, rdataset, link);
2189 
2190 	if (client->view->order != NULL)
2191 		rdataset->attributes |= dns_order_find(client->view->order,
2192 						       fname, rdataset->type,
2193 						       rdataset->rdclass);
2194 	rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
2195 
2196 	if (NOADDITIONAL(client))
2197 		return;
2198 
2199 	/*
2200 	 * Add additional data.
2201 	 *
2202 	 * We don't care if dns_rdataset_additionaldata() fails.
2203 	 */
2204 	additionalctx.client = client;
2205 	additionalctx.rdataset = rdataset;
2206 	(void)dns_rdataset_additionaldata(rdataset, query_addadditional2,
2207 					  &additionalctx);
2208 	CTRACE("query_addrdataset: done");
2209 }
2210 
2211 static isc_result_t
2212 query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset,
2213 	    dns_rdataset_t *sigrdataset, isc_buffer_t *dbuf,
2214 	    dns_section_t section)
2215 {
2216 	dns_name_t *name, *mname;
2217 	dns_rdata_t *dns64_rdata;
2218 	dns_rdata_t rdata = DNS_RDATA_INIT;
2219 	dns_rdatalist_t *dns64_rdatalist;
2220 	dns_rdataset_t *dns64_rdataset;
2221 	dns_rdataset_t *mrdataset;
2222 	isc_buffer_t *buffer;
2223 	isc_region_t r;
2224 	isc_result_t result;
2225 	dns_view_t *view = client->view;
2226 	isc_netaddr_t netaddr;
2227 	dns_dns64_t *dns64;
2228 	unsigned int flags = 0;
2229 
2230 	/*%
2231 	 * To the current response for 'client', add the answer RRset
2232 	 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with
2233 	 * owner name '*namep', to section 'section', unless they are
2234 	 * already there.  Also add any pertinent additional data.
2235 	 *
2236 	 * If 'dbuf' is not NULL, then '*namep' is the name whose data is
2237 	 * stored in 'dbuf'.  In this case, query_addrrset() guarantees that
2238 	 * when it returns the name will either have been kept or released.
2239 	 */
2240 	CTRACE("query_dns64");
2241 	name = *namep;
2242 	mname = NULL;
2243 	mrdataset = NULL;
2244 	buffer = NULL;
2245 	dns64_rdata = NULL;
2246 	dns64_rdataset = NULL;
2247 	dns64_rdatalist = NULL;
2248 	result = dns_message_findname(client->message, section,
2249 				      name, dns_rdatatype_aaaa,
2250 				      rdataset->covers,
2251 				      &mname, &mrdataset);
2252 	if (result == ISC_R_SUCCESS) {
2253 		/*
2254 		 * We've already got an RRset of the given name and type.
2255 		 * There's nothing else to do;
2256 		 */
2257 		CTRACE("query_dns64: dns_message_findname succeeded: done");
2258 		if (dbuf != NULL)
2259 			query_releasename(client, namep);
2260 		return (ISC_R_SUCCESS);
2261 	} else if (result == DNS_R_NXDOMAIN) {
2262 		/*
2263 		 * The name doesn't exist.
2264 		 */
2265 		if (dbuf != NULL)
2266 			query_keepname(client, name, dbuf);
2267 		dns_message_addname(client->message, name, section);
2268 		*namep = NULL;
2269 		mname = name;
2270 	} else {
2271 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
2272 		if (dbuf != NULL)
2273 			query_releasename(client, namep);
2274 	}
2275 
2276 	if (rdataset->trust != dns_trust_secure &&
2277 	    (section == DNS_SECTION_ANSWER ||
2278 	     section == DNS_SECTION_AUTHORITY))
2279 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
2280 
2281 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
2282 
2283 	result = isc_buffer_allocate(client->mctx, &buffer, view->dns64cnt *
2284 				     16 * dns_rdataset_count(rdataset));
2285 	if (result != ISC_R_SUCCESS)
2286 		goto cleanup;
2287 	result = dns_message_gettemprdataset(client->message, &dns64_rdataset);
2288 	if (result != ISC_R_SUCCESS)
2289 		goto cleanup;
2290 	result = dns_message_gettemprdatalist(client->message,
2291 					      &dns64_rdatalist);
2292 	if (result != ISC_R_SUCCESS)
2293 		goto cleanup;
2294 
2295 	dns_rdatalist_init(dns64_rdatalist);
2296 	dns64_rdatalist->rdclass = dns_rdataclass_in;
2297 	dns64_rdatalist->type = dns_rdatatype_aaaa;
2298 	if (client->query.dns64_ttl != ISC_UINT32_MAX)
2299 		dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl,
2300 					       client->query.dns64_ttl);
2301 	else
2302 		dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 600);
2303 
2304 	if (RECURSIONOK(client))
2305 		flags |= DNS_DNS64_RECURSIVE;
2306 
2307 	/*
2308 	 * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC
2309 	 * as this provides a easy way to see if the answer was signed.
2310 	 */
2311 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
2312 		flags |= DNS_DNS64_DNSSEC;
2313 
2314 	for (result = dns_rdataset_first(rdataset);
2315 	     result == ISC_R_SUCCESS;
2316 	     result = dns_rdataset_next(rdataset)) {
2317 		for (dns64 = ISC_LIST_HEAD(client->view->dns64);
2318 		     dns64 != NULL; dns64 = dns_dns64_next(dns64)) {
2319 
2320 			dns_rdataset_current(rdataset, &rdata);
2321 			isc_buffer_availableregion(buffer, &r);
2322 			INSIST(r.length >= 16);
2323 			result = dns_dns64_aaaafroma(dns64, &netaddr,
2324 						     client->signer,
2325 						     &ns_g_server->aclenv,
2326 						     flags, rdata.data, r.base);
2327 			if (result != ISC_R_SUCCESS) {
2328 				dns_rdata_reset(&rdata);
2329 				continue;
2330 			}
2331 			isc_buffer_add(buffer, 16);
2332 			isc_buffer_remainingregion(buffer, &r);
2333 			isc_buffer_forward(buffer, 16);
2334 			result = dns_message_gettemprdata(client->message,
2335 							  &dns64_rdata);
2336 			if (result != ISC_R_SUCCESS)
2337 				goto cleanup;
2338 			dns_rdata_init(dns64_rdata);
2339 			dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
2340 					     dns_rdatatype_aaaa, &r);
2341 			ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata,
2342 					link);
2343 			dns64_rdata = NULL;
2344 			dns_rdata_reset(&rdata);
2345 		}
2346 	}
2347 	if (result != ISC_R_NOMORE)
2348 		goto cleanup;
2349 
2350 	if (ISC_LIST_EMPTY(dns64_rdatalist->rdata))
2351 		goto cleanup;
2352 
2353 	result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
2354 	if (result != ISC_R_SUCCESS)
2355 		goto cleanup;
2356 	client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
2357 	dns64_rdataset->trust = rdataset->trust;
2358 	query_addrdataset(client, mname, dns64_rdataset);
2359 	dns64_rdataset = NULL;
2360 	dns64_rdatalist = NULL;
2361 	dns_message_takebuffer(client->message, &buffer);
2362 	inc_stats(client, dns_nsstatscounter_dns64);
2363 	result = ISC_R_SUCCESS;
2364 
2365  cleanup:
2366 	if (buffer != NULL)
2367 		isc_buffer_free(&buffer);
2368 
2369 	if (dns64_rdata != NULL)
2370 		dns_message_puttemprdata(client->message, &dns64_rdata);
2371 
2372 	if (dns64_rdataset != NULL)
2373 		dns_message_puttemprdataset(client->message, &dns64_rdataset);
2374 
2375 	if (dns64_rdatalist != NULL) {
2376 		for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata);
2377 		     dns64_rdata != NULL;
2378 		     dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata))
2379 		{
2380 			ISC_LIST_UNLINK(dns64_rdatalist->rdata,
2381 					dns64_rdata, link);
2382 			dns_message_puttemprdata(client->message, &dns64_rdata);
2383 		}
2384 		dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
2385 	}
2386 
2387 	CTRACE("query_dns64: done");
2388 	return (result);
2389 }
2390 
2391 static void
2392 query_filter64(ns_client_t *client, dns_name_t **namep,
2393 	       dns_rdataset_t *rdataset, isc_buffer_t *dbuf,
2394 	       dns_section_t section)
2395 {
2396 	dns_name_t *name, *mname;
2397 	dns_rdata_t *myrdata;
2398 	dns_rdata_t rdata = DNS_RDATA_INIT;
2399 	dns_rdatalist_t *myrdatalist;
2400 	dns_rdataset_t *myrdataset;
2401 	isc_buffer_t *buffer;
2402 	isc_region_t r;
2403 	isc_result_t result;
2404 	unsigned int i;
2405 
2406 	CTRACE("query_filter64");
2407 
2408 	INSIST(client->query.dns64_aaaaok != NULL);
2409 	INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset));
2410 
2411 	name = *namep;
2412 	mname = NULL;
2413 	buffer = NULL;
2414 	myrdata = NULL;
2415 	myrdataset = NULL;
2416 	myrdatalist = NULL;
2417 	result = dns_message_findname(client->message, section,
2418 				      name, dns_rdatatype_aaaa,
2419 				      rdataset->covers,
2420 				      &mname, &myrdataset);
2421 	if (result == ISC_R_SUCCESS) {
2422 		/*
2423 		 * We've already got an RRset of the given name and type.
2424 		 * There's nothing else to do;
2425 		 */
2426 		CTRACE("query_filter64: dns_message_findname succeeded: done");
2427 		if (dbuf != NULL)
2428 			query_releasename(client, namep);
2429 		return;
2430 	} else if (result == DNS_R_NXDOMAIN) {
2431 		mname = name;
2432 		*namep = NULL;
2433 	} else {
2434 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
2435 		if (dbuf != NULL)
2436 			query_releasename(client, namep);
2437 		dbuf = NULL;
2438 	}
2439 
2440 	if (rdataset->trust != dns_trust_secure &&
2441 	    (section == DNS_SECTION_ANSWER ||
2442 	     section == DNS_SECTION_AUTHORITY))
2443 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
2444 
2445 	result = isc_buffer_allocate(client->mctx, &buffer,
2446 				     16 * dns_rdataset_count(rdataset));
2447 	if (result != ISC_R_SUCCESS)
2448 		goto cleanup;
2449 	result = dns_message_gettemprdataset(client->message, &myrdataset);
2450 	if (result != ISC_R_SUCCESS)
2451 		goto cleanup;
2452 	result = dns_message_gettemprdatalist(client->message, &myrdatalist);
2453 	if (result != ISC_R_SUCCESS)
2454 		goto cleanup;
2455 
2456 	dns_rdatalist_init(myrdatalist);
2457 	myrdatalist->rdclass = dns_rdataclass_in;
2458 	myrdatalist->type = dns_rdatatype_aaaa;
2459 	myrdatalist->ttl = rdataset->ttl;
2460 
2461 	i = 0;
2462 	for (result = dns_rdataset_first(rdataset);
2463 	     result == ISC_R_SUCCESS;
2464 	     result = dns_rdataset_next(rdataset)) {
2465 		if (!client->query.dns64_aaaaok[i++])
2466 			continue;
2467 		dns_rdataset_current(rdataset, &rdata);
2468 		INSIST(rdata.length == 16);
2469 		isc_buffer_putmem(buffer, rdata.data, rdata.length);
2470 		isc_buffer_remainingregion(buffer, &r);
2471 		isc_buffer_forward(buffer, rdata.length);
2472 		result = dns_message_gettemprdata(client->message, &myrdata);
2473 		if (result != ISC_R_SUCCESS)
2474 			goto cleanup;
2475 		dns_rdata_init(myrdata);
2476 		dns_rdata_fromregion(myrdata, dns_rdataclass_in,
2477 				     dns_rdatatype_aaaa, &r);
2478 		ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link);
2479 		myrdata = NULL;
2480 		dns_rdata_reset(&rdata);
2481 	}
2482 	if (result != ISC_R_NOMORE)
2483 		goto cleanup;
2484 
2485 	result = dns_rdatalist_tordataset(myrdatalist, myrdataset);
2486 	if (result != ISC_R_SUCCESS)
2487 		goto cleanup;
2488 	client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
2489 	if (mname == name) {
2490 		if (dbuf != NULL)
2491 			query_keepname(client, name, dbuf);
2492 		dns_message_addname(client->message, name, section);
2493 		dbuf = NULL;
2494 	}
2495 	myrdataset->trust = rdataset->trust;
2496 	query_addrdataset(client, mname, myrdataset);
2497 	myrdataset = NULL;
2498 	myrdatalist = NULL;
2499 	dns_message_takebuffer(client->message, &buffer);
2500 
2501  cleanup:
2502 	if (buffer != NULL)
2503 		isc_buffer_free(&buffer);
2504 
2505 	if (myrdata != NULL)
2506 		dns_message_puttemprdata(client->message, &myrdata);
2507 
2508 	if (myrdataset != NULL)
2509 		dns_message_puttemprdataset(client->message, &myrdataset);
2510 
2511 	if (myrdatalist != NULL) {
2512 		for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata);
2513 		     myrdata != NULL;
2514 		     myrdata = ISC_LIST_HEAD(myrdatalist->rdata))
2515 		{
2516 			ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link);
2517 			dns_message_puttemprdata(client->message, &myrdata);
2518 		}
2519 		dns_message_puttemprdatalist(client->message, &myrdatalist);
2520 	}
2521 	if (dbuf != NULL)
2522 		query_releasename(client, &name);
2523 
2524 	CTRACE("query_filter64: done");
2525 }
2526 
2527 static void
2528 query_addrrset(ns_client_t *client, dns_name_t **namep,
2529 	       dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
2530 	       isc_buffer_t *dbuf, dns_section_t section)
2531 {
2532 	dns_name_t *name, *mname;
2533 	dns_rdataset_t *rdataset, *mrdataset, *sigrdataset;
2534 	isc_result_t result;
2535 
2536 	/*%
2537 	 * To the current response for 'client', add the answer RRset
2538 	 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with
2539 	 * owner name '*namep', to section 'section', unless they are
2540 	 * already there.  Also add any pertinent additional data.
2541 	 *
2542 	 * If 'dbuf' is not NULL, then '*namep' is the name whose data is
2543 	 * stored in 'dbuf'.  In this case, query_addrrset() guarantees that
2544 	 * when it returns the name will either have been kept or released.
2545 	 */
2546 	CTRACE("query_addrrset");
2547 	name = *namep;
2548 	rdataset = *rdatasetp;
2549 	if (sigrdatasetp != NULL)
2550 		sigrdataset = *sigrdatasetp;
2551 	else
2552 		sigrdataset = NULL;
2553 	mname = NULL;
2554 	mrdataset = NULL;
2555 	result = dns_message_findname(client->message, section,
2556 				      name, rdataset->type, rdataset->covers,
2557 				      &mname, &mrdataset);
2558 	if (result == ISC_R_SUCCESS) {
2559 		/*
2560 		 * We've already got an RRset of the given name and type.
2561 		 */
2562 		CTRACE("query_addrrset: dns_message_findname succeeded: done");
2563 		if (dbuf != NULL)
2564 			query_releasename(client, namep);
2565 		if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0)
2566 			mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
2567 		return;
2568 	} else if (result == DNS_R_NXDOMAIN) {
2569 		/*
2570 		 * The name doesn't exist.
2571 		 */
2572 		if (dbuf != NULL)
2573 			query_keepname(client, name, dbuf);
2574 		dns_message_addname(client->message, name, section);
2575 		*namep = NULL;
2576 		mname = name;
2577 	} else {
2578 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
2579 		if (dbuf != NULL)
2580 			query_releasename(client, namep);
2581 	}
2582 
2583 	if (rdataset->trust != dns_trust_secure &&
2584 	    (section == DNS_SECTION_ANSWER ||
2585 	     section == DNS_SECTION_AUTHORITY))
2586 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
2587 	/*
2588 	 * Note: we only add SIGs if we've added the type they cover, so
2589 	 * we do not need to check if the SIG rdataset is already in the
2590 	 * response.
2591 	 */
2592 	query_addrdataset(client, mname, rdataset);
2593 	*rdatasetp = NULL;
2594 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {
2595 		/*
2596 		 * We have a signature.  Add it to the response.
2597 		 */
2598 		ISC_LIST_APPEND(mname->list, sigrdataset, link);
2599 		*sigrdatasetp = NULL;
2600 	}
2601 	CTRACE("query_addrrset: done");
2602 }
2603 
2604 static inline isc_result_t
2605 query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
2606 	     unsigned int override_ttl, isc_boolean_t isassociated,
2607 	     dns_section_t section)
2608 {
2609 	dns_name_t *name;
2610 	dns_dbnode_t *node;
2611 	isc_result_t result, eresult;
2612 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
2613 	dns_rdataset_t **sigrdatasetp = NULL;
2614 	dns_clientinfomethods_t cm;
2615 	dns_clientinfo_t ci;
2616 
2617 	CTRACE("query_addsoa");
2618 	/*
2619 	 * Initialization.
2620 	 */
2621 	eresult = ISC_R_SUCCESS;
2622 	name = NULL;
2623 	rdataset = NULL;
2624 	node = NULL;
2625 
2626 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
2627 	dns_clientinfo_init(&ci, client);
2628 
2629 	/*
2630 	 * Don't add the SOA record for test which set "-T nosoa".
2631 	 */
2632 	if (ns_g_nosoa && (!WANTDNSSEC(client) || !isassociated))
2633 		return (ISC_R_SUCCESS);
2634 
2635 	/*
2636 	 * Get resources and make 'name' be the database origin.
2637 	 */
2638 	result = dns_message_gettempname(client->message, &name);
2639 	if (result != ISC_R_SUCCESS)
2640 		return (result);
2641 	dns_name_init(name, NULL);
2642 	dns_name_clone(dns_db_origin(db), name);
2643 	rdataset = query_newrdataset(client);
2644 	if (rdataset == NULL) {
2645 		eresult = DNS_R_SERVFAIL;
2646 		goto cleanup;
2647 	}
2648 	if (WANTDNSSEC(client) && dns_db_issecure(db)) {
2649 		sigrdataset = query_newrdataset(client);
2650 		if (sigrdataset == NULL) {
2651 			eresult = DNS_R_SERVFAIL;
2652 			goto cleanup;
2653 		}
2654 	}
2655 
2656 	/*
2657 	 * Find the SOA.
2658 	 */
2659 	result = dns_db_getoriginnode(db, &node);
2660 	if (result == ISC_R_SUCCESS) {
2661 		result = dns_db_findrdataset(db, node, version,
2662 					     dns_rdatatype_soa, 0, client->now,
2663 					     rdataset, sigrdataset);
2664 	} else {
2665 		dns_fixedname_t foundname;
2666 		dns_name_t *fname;
2667 
2668 		dns_fixedname_init(&foundname);
2669 		fname = dns_fixedname_name(&foundname);
2670 
2671 		result = dns_db_findext(db, name, version, dns_rdatatype_soa,
2672 					client->query.dboptions, 0, &node,
2673 					fname, &cm, &ci, rdataset, sigrdataset);
2674 	}
2675 	if (result != ISC_R_SUCCESS) {
2676 		/*
2677 		 * This is bad.  We tried to get the SOA RR at the zone top
2678 		 * and it didn't work!
2679 		 */
2680 		eresult = DNS_R_SERVFAIL;
2681 	} else {
2682 		/*
2683 		 * Extract the SOA MINIMUM.
2684 		 */
2685 		dns_rdata_soa_t soa;
2686 		dns_rdata_t rdata = DNS_RDATA_INIT;
2687 		result = dns_rdataset_first(rdataset);
2688 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
2689 		dns_rdataset_current(rdataset, &rdata);
2690 		result = dns_rdata_tostruct(&rdata, &soa, NULL);
2691 		if (result != ISC_R_SUCCESS)
2692 			goto cleanup;
2693 
2694 		if (override_ttl != ISC_UINT32_MAX &&
2695 		    override_ttl < rdataset->ttl) {
2696 			rdataset->ttl = override_ttl;
2697 			if (sigrdataset != NULL)
2698 				sigrdataset->ttl = override_ttl;
2699 		}
2700 
2701 		/*
2702 		 * Add the SOA and its SIG to the response, with the
2703 		 * TTLs adjusted per RFC2308 section 3.
2704 		 */
2705 		if (rdataset->ttl > soa.minimum)
2706 			rdataset->ttl = soa.minimum;
2707 		if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum)
2708 			sigrdataset->ttl = soa.minimum;
2709 
2710 		if (sigrdataset != NULL)
2711 			sigrdatasetp = &sigrdataset;
2712 		else
2713 			sigrdatasetp = NULL;
2714 
2715 		if (section == DNS_SECTION_ADDITIONAL)
2716 			rdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
2717 		query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL,
2718 			       section);
2719 	}
2720 
2721  cleanup:
2722 	query_putrdataset(client, &rdataset);
2723 	if (sigrdataset != NULL)
2724 		query_putrdataset(client, &sigrdataset);
2725 	if (name != NULL)
2726 		query_releasename(client, &name);
2727 	if (node != NULL)
2728 		dns_db_detachnode(db, &node);
2729 
2730 	return (eresult);
2731 }
2732 
2733 static inline isc_result_t
2734 query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
2735 	dns_name_t *name, *fname;
2736 	dns_dbnode_t *node;
2737 	isc_result_t result, eresult;
2738 	dns_fixedname_t foundname;
2739 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
2740 	dns_rdataset_t **sigrdatasetp = NULL;
2741 	dns_clientinfomethods_t cm;
2742 	dns_clientinfo_t ci;
2743 
2744 	CTRACE("query_addns");
2745 	/*
2746 	 * Initialization.
2747 	 */
2748 	eresult = ISC_R_SUCCESS;
2749 	name = NULL;
2750 	rdataset = NULL;
2751 	node = NULL;
2752 	dns_fixedname_init(&foundname);
2753 	fname = dns_fixedname_name(&foundname);
2754 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
2755 	dns_clientinfo_init(&ci, client);
2756 
2757 	/*
2758 	 * Get resources and make 'name' be the database origin.
2759 	 */
2760 	result = dns_message_gettempname(client->message, &name);
2761 	if (result != ISC_R_SUCCESS) {
2762 		CTRACE("query_addns: dns_message_gettempname failed: done");
2763 		return (result);
2764 	}
2765 	dns_name_init(name, NULL);
2766 	dns_name_clone(dns_db_origin(db), name);
2767 	rdataset = query_newrdataset(client);
2768 	if (rdataset == NULL) {
2769 		CTRACE("query_addns: query_newrdataset failed");
2770 		eresult = DNS_R_SERVFAIL;
2771 		goto cleanup;
2772 	}
2773 	if (WANTDNSSEC(client) && dns_db_issecure(db)) {
2774 		sigrdataset = query_newrdataset(client);
2775 		if (sigrdataset == NULL) {
2776 			CTRACE("query_addns: query_newrdataset failed");
2777 			eresult = DNS_R_SERVFAIL;
2778 			goto cleanup;
2779 		}
2780 	}
2781 
2782 	/*
2783 	 * Find the NS rdataset.
2784 	 */
2785 	result = dns_db_getoriginnode(db, &node);
2786 	if (result == ISC_R_SUCCESS) {
2787 		result = dns_db_findrdataset(db, node, version,
2788 					     dns_rdatatype_ns, 0, client->now,
2789 					     rdataset, sigrdataset);
2790 	} else {
2791 		CTRACE("query_addns: calling dns_db_find");
2792 		result = dns_db_findext(db, name, NULL, dns_rdatatype_ns,
2793 					client->query.dboptions, 0, &node,
2794 					fname, &cm, &ci, rdataset, sigrdataset);
2795 		CTRACE("query_addns: dns_db_find complete");
2796 	}
2797 	if (result != ISC_R_SUCCESS) {
2798 		CTRACE("query_addns: "
2799 		       "dns_db_findrdataset or dns_db_find failed");
2800 		/*
2801 		 * This is bad.  We tried to get the NS rdataset at the zone
2802 		 * top and it didn't work!
2803 		 */
2804 		eresult = DNS_R_SERVFAIL;
2805 	} else {
2806 		if (sigrdataset != NULL)
2807 			sigrdatasetp = &sigrdataset;
2808 		else
2809 			sigrdatasetp = NULL;
2810 		query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL,
2811 			       DNS_SECTION_AUTHORITY);
2812 	}
2813 
2814  cleanup:
2815 	CTRACE("query_addns: cleanup");
2816 	query_putrdataset(client, &rdataset);
2817 	if (sigrdataset != NULL)
2818 		query_putrdataset(client, &sigrdataset);
2819 	if (name != NULL)
2820 		query_releasename(client, &name);
2821 	if (node != NULL)
2822 		dns_db_detachnode(db, &node);
2823 
2824 	CTRACE("query_addns: done");
2825 	return (eresult);
2826 }
2827 
2828 static isc_result_t
2829 query_add_cname(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
2830 		dns_trust_t trust, dns_ttl_t ttl)
2831 {
2832 	dns_rdataset_t *rdataset;
2833 	dns_rdatalist_t *rdatalist;
2834 	dns_rdata_t *rdata;
2835 	isc_region_t r;
2836 	dns_name_t *aname;
2837 	isc_result_t result;
2838 
2839 	/*
2840 	 * We assume the name data referred to by tname won't go away.
2841 	 */
2842 
2843 	aname = NULL;
2844 	result = dns_message_gettempname(client->message, &aname);
2845 	if (result != ISC_R_SUCCESS)
2846 		return (result);
2847 	result = dns_name_dup(qname, client->mctx, aname);
2848 	if (result != ISC_R_SUCCESS) {
2849 		dns_message_puttempname(client->message, &aname);
2850 		return (result);
2851 	}
2852 
2853 	rdatalist = NULL;
2854 	result = dns_message_gettemprdatalist(client->message, &rdatalist);
2855 	if (result != ISC_R_SUCCESS) {
2856 		dns_message_puttempname(client->message, &aname);
2857 		return (result);
2858 	}
2859 	rdata = NULL;
2860 	result = dns_message_gettemprdata(client->message, &rdata);
2861 	if (result != ISC_R_SUCCESS) {
2862 		dns_message_puttempname(client->message, &aname);
2863 		dns_message_puttemprdatalist(client->message, &rdatalist);
2864 		return (result);
2865 	}
2866 	rdataset = NULL;
2867 	result = dns_message_gettemprdataset(client->message, &rdataset);
2868 	if (result != ISC_R_SUCCESS) {
2869 		dns_message_puttempname(client->message, &aname);
2870 		dns_message_puttemprdatalist(client->message, &rdatalist);
2871 		dns_message_puttemprdata(client->message, &rdata);
2872 		return (result);
2873 	}
2874 	rdatalist->type = dns_rdatatype_cname;
2875 	rdatalist->covers = 0;
2876 	rdatalist->rdclass = client->message->rdclass;
2877 	rdatalist->ttl = ttl;
2878 
2879 	dns_name_toregion(tname, &r);
2880 	rdata->data = r.base;
2881 	rdata->length = r.length;
2882 	rdata->rdclass = client->message->rdclass;
2883 	rdata->type = dns_rdatatype_cname;
2884 
2885 	ISC_LIST_INIT(rdatalist->rdata);
2886 	ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
2887 	RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
2888 		      == ISC_R_SUCCESS);
2889 	rdataset->trust = trust;
2890 
2891 	query_addrrset(client, &aname, &rdataset, NULL, NULL,
2892 		       DNS_SECTION_ANSWER);
2893 	if (rdataset != NULL) {
2894 		if (dns_rdataset_isassociated(rdataset))
2895 			dns_rdataset_disassociate(rdataset);
2896 		dns_message_puttemprdataset(client->message, &rdataset);
2897 	}
2898 	if (aname != NULL)
2899 		dns_message_puttempname(client->message, &aname);
2900 
2901 	return (ISC_R_SUCCESS);
2902 }
2903 
2904 /*
2905  * Mark the RRsets as secure.  Update the cache (db) to reflect the
2906  * change in trust level.
2907  */
2908 static void
2909 mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name,
2910 	    dns_rdata_rrsig_t *rrsig, dns_rdataset_t *rdataset,
2911 	    dns_rdataset_t *sigrdataset)
2912 {
2913 	isc_result_t result;
2914 	dns_dbnode_t *node = NULL;
2915 	dns_clientinfomethods_t cm;
2916 	dns_clientinfo_t ci;
2917 	isc_stdtime_t now;
2918 
2919 	rdataset->trust = dns_trust_secure;
2920 	sigrdataset->trust = dns_trust_secure;
2921 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
2922 	dns_clientinfo_init(&ci, client);
2923 
2924 	/*
2925 	 * Save the updated secure state.  Ignore failures.
2926 	 */
2927 	result = dns_db_findnodeext(db, name, ISC_TRUE, &cm, &ci, &node);
2928 	if (result != ISC_R_SUCCESS)
2929 		return;
2930 
2931 	isc_stdtime_get(&now);
2932 	dns_rdataset_trimttl(rdataset, sigrdataset, rrsig, now,
2933 			     client->view->acceptexpired);
2934 
2935 	(void)dns_db_addrdataset(db, node, NULL, client->now, rdataset,
2936 				 0, NULL);
2937 	(void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset,
2938 				 0, NULL);
2939 	dns_db_detachnode(db, &node);
2940 }
2941 
2942 /*
2943  * Find the secure key that corresponds to rrsig.
2944  * Note: 'keyrdataset' maintains state between successive calls,
2945  * there may be multiple keys with the same keyid.
2946  * Return ISC_FALSE if we have exhausted all the possible keys.
2947  */
2948 static isc_boolean_t
2949 get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig,
2950 	dns_rdataset_t *keyrdataset, dst_key_t **keyp)
2951 {
2952 	isc_result_t result;
2953 	dns_dbnode_t *node = NULL;
2954 	isc_boolean_t secure = ISC_FALSE;
2955 	dns_clientinfomethods_t cm;
2956 	dns_clientinfo_t ci;
2957 
2958 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
2959 	dns_clientinfo_init(&ci, client);
2960 
2961 	if (!dns_rdataset_isassociated(keyrdataset)) {
2962 		result = dns_db_findnodeext(db, &rrsig->signer, ISC_FALSE,
2963 					    &cm, &ci, &node);
2964 		if (result != ISC_R_SUCCESS)
2965 			return (ISC_FALSE);
2966 
2967 		result = dns_db_findrdataset(db, node, NULL,
2968 					     dns_rdatatype_dnskey, 0,
2969 					     client->now, keyrdataset, NULL);
2970 		dns_db_detachnode(db, &node);
2971 		if (result != ISC_R_SUCCESS)
2972 			return (ISC_FALSE);
2973 
2974 		if (keyrdataset->trust != dns_trust_secure)
2975 			return (ISC_FALSE);
2976 
2977 		result = dns_rdataset_first(keyrdataset);
2978 	} else
2979 		result = dns_rdataset_next(keyrdataset);
2980 
2981 	for ( ; result == ISC_R_SUCCESS;
2982 	     result = dns_rdataset_next(keyrdataset)) {
2983 		dns_rdata_t rdata = DNS_RDATA_INIT;
2984 		isc_buffer_t b;
2985 
2986 		dns_rdataset_current(keyrdataset, &rdata);
2987 		isc_buffer_init(&b, rdata.data, rdata.length);
2988 		isc_buffer_add(&b, rdata.length);
2989 		result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b,
2990 					 client->mctx, keyp);
2991 		if (result != ISC_R_SUCCESS)
2992 			continue;
2993 		if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) &&
2994 		    rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) &&
2995 		    dst_key_iszonekey(*keyp)) {
2996 			secure = ISC_TRUE;
2997 			break;
2998 		}
2999 		dst_key_free(keyp);
3000 	}
3001 	return (secure);
3002 }
3003 
3004 static isc_boolean_t
3005 verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset,
3006        dns_rdata_t *rdata, ns_client_t *client)
3007 {
3008 	isc_result_t result;
3009 	dns_fixedname_t fixed;
3010 	isc_boolean_t ignore = ISC_FALSE;
3011 
3012 	dns_fixedname_init(&fixed);
3013 
3014 again:
3015 	result = dns_dnssec_verify3(name, rdataset, key, ignore,
3016 				    client->view->maxbits, client->mctx,
3017 				    rdata, NULL);
3018 	if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) {
3019 		ignore = ISC_TRUE;
3020 		goto again;
3021 	}
3022 	if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD)
3023 		return (ISC_TRUE);
3024 	return (ISC_FALSE);
3025 }
3026 
3027 /*
3028  * Validate the rdataset if possible with available records.
3029  */
3030 static isc_boolean_t
3031 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
3032 	 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
3033 {
3034 	isc_result_t result;
3035 	dns_rdata_t rdata = DNS_RDATA_INIT;
3036 	dns_rdata_rrsig_t rrsig;
3037 	dst_key_t *key = NULL;
3038 	dns_rdataset_t keyrdataset;
3039 
3040 	if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset))
3041 		return (ISC_FALSE);
3042 
3043 	for (result = dns_rdataset_first(sigrdataset);
3044 	     result == ISC_R_SUCCESS;
3045 	     result = dns_rdataset_next(sigrdataset)) {
3046 
3047 		dns_rdata_reset(&rdata);
3048 		dns_rdataset_current(sigrdataset, &rdata);
3049 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
3050 		if (result != ISC_R_SUCCESS)
3051 			return (ISC_FALSE);
3052 		if (!dns_resolver_algorithm_supported(client->view->resolver,
3053 						      name, rrsig.algorithm))
3054 			continue;
3055 		if (!dns_name_issubdomain(name, &rrsig.signer))
3056 			continue;
3057 		dns_rdataset_init(&keyrdataset);
3058 		do {
3059 			if (!get_key(client, db, &rrsig, &keyrdataset, &key))
3060 				break;
3061 			if (verify(key, name, rdataset, &rdata, client)) {
3062 				dst_key_free(&key);
3063 				dns_rdataset_disassociate(&keyrdataset);
3064 				mark_secure(client, db, name, &rrsig,
3065 					    rdataset, sigrdataset);
3066 				return (ISC_TRUE);
3067 			}
3068 			dst_key_free(&key);
3069 		} while (1);
3070 		if (dns_rdataset_isassociated(&keyrdataset))
3071 			dns_rdataset_disassociate(&keyrdataset);
3072 	}
3073 	return (ISC_FALSE);
3074 }
3075 
3076 static void
3077 query_addbestns(ns_client_t *client) {
3078 	dns_db_t *db, *zdb;
3079 	dns_dbnode_t *node;
3080 	dns_name_t *fname, *zfname;
3081 	dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset;
3082 	isc_boolean_t is_zone, use_zone;
3083 	isc_buffer_t *dbuf;
3084 	isc_result_t result;
3085 	dns_dbversion_t *version;
3086 	dns_zone_t *zone;
3087 	isc_buffer_t b;
3088 	dns_clientinfomethods_t cm;
3089 	dns_clientinfo_t ci;
3090 
3091 	CTRACE("query_addbestns");
3092 	fname = NULL;
3093 	zfname = NULL;
3094 	rdataset = NULL;
3095 	zrdataset = NULL;
3096 	sigrdataset = NULL;
3097 	zsigrdataset = NULL;
3098 	node = NULL;
3099 	db = NULL;
3100 	zdb = NULL;
3101 	version = NULL;
3102 	zone = NULL;
3103 	is_zone = ISC_FALSE;
3104 	use_zone = ISC_FALSE;
3105 
3106 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
3107 	dns_clientinfo_init(&ci, client);
3108 
3109 	/*
3110 	 * Find the right database.
3111 	 */
3112 	result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0,
3113 			     &zone, &db, &version, &is_zone);
3114 	if (result != ISC_R_SUCCESS)
3115 		goto cleanup;
3116 
3117  db_find:
3118 	/*
3119 	 * We'll need some resources...
3120 	 */
3121 	dbuf = query_getnamebuf(client);
3122 	if (dbuf == NULL)
3123 		goto cleanup;
3124 	fname = query_newname(client, dbuf, &b);
3125 	rdataset = query_newrdataset(client);
3126 	if (fname == NULL || rdataset == NULL)
3127 		goto cleanup;
3128 	/*
3129 	 * Get the RRSIGs if the client requested them or if we may
3130 	 * need to validate answers from the cache.
3131 	 */
3132 	if (WANTDNSSEC(client) || !is_zone) {
3133 		sigrdataset = query_newrdataset(client);
3134 		if (sigrdataset == NULL)
3135 			goto cleanup;
3136 	}
3137 
3138 	/*
3139 	 * Now look for the zonecut.
3140 	 */
3141 	if (is_zone) {
3142 		result = dns_db_findext(db, client->query.qname, version,
3143 					dns_rdatatype_ns,
3144 					client->query.dboptions,
3145 					client->now, &node, fname,
3146 					&cm, &ci, rdataset, sigrdataset);
3147 		if (result != DNS_R_DELEGATION)
3148 			goto cleanup;
3149 		if (USECACHE(client)) {
3150 			query_keepname(client, fname, dbuf);
3151 			zdb = db;
3152 			zfname = fname;
3153 			fname = NULL;
3154 			zrdataset = rdataset;
3155 			rdataset = NULL;
3156 			zsigrdataset = sigrdataset;
3157 			sigrdataset = NULL;
3158 			dns_db_detachnode(db, &node);
3159 			version = NULL;
3160 			db = NULL;
3161 			dns_db_attach(client->view->cachedb, &db);
3162 			is_zone = ISC_FALSE;
3163 			goto db_find;
3164 		}
3165 	} else {
3166 		result = dns_db_findzonecut(db, client->query.qname,
3167 					    client->query.dboptions,
3168 					    client->now, &node, fname,
3169 					    rdataset, sigrdataset);
3170 		if (result == ISC_R_SUCCESS) {
3171 			if (zfname != NULL &&
3172 			    !dns_name_issubdomain(fname, zfname)) {
3173 				/*
3174 				 * We found a zonecut in the cache, but our
3175 				 * zone delegation is better.
3176 				 */
3177 				use_zone = ISC_TRUE;
3178 			}
3179 		} else if (result == ISC_R_NOTFOUND && zfname != NULL) {
3180 			/*
3181 			 * We didn't find anything in the cache, but we
3182 			 * have a zone delegation, so use it.
3183 			 */
3184 			use_zone = ISC_TRUE;
3185 		} else
3186 			goto cleanup;
3187 	}
3188 
3189 	if (use_zone) {
3190 		query_releasename(client, &fname);
3191 		fname = zfname;
3192 		zfname = NULL;
3193 		/*
3194 		 * We've already done query_keepname() on
3195 		 * zfname, so we must set dbuf to NULL to
3196 		 * prevent query_addrrset() from trying to
3197 		 * call query_keepname() again.
3198 		 */
3199 		dbuf = NULL;
3200 		query_putrdataset(client, &rdataset);
3201 		if (sigrdataset != NULL)
3202 			query_putrdataset(client, &sigrdataset);
3203 		rdataset = zrdataset;
3204 		zrdataset = NULL;
3205 		sigrdataset = zsigrdataset;
3206 		zsigrdataset = NULL;
3207 	}
3208 
3209 	/*
3210 	 * Attempt to validate RRsets that are pending or that are glue.
3211 	 */
3212 	if ((DNS_TRUST_PENDING(rdataset->trust) ||
3213 	     (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust)))
3214 	    && !validate(client, db, fname, rdataset, sigrdataset) &&
3215 	    !PENDINGOK(client->query.dboptions))
3216 		goto cleanup;
3217 
3218 	if ((DNS_TRUST_GLUE(rdataset->trust) ||
3219 	     (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) &&
3220 	    !validate(client, db, fname, rdataset, sigrdataset) &&
3221 	    SECURE(client) && WANTDNSSEC(client))
3222 		goto cleanup;
3223 
3224 	/*
3225 	 * If the answer is secure only add NS records if they are secure		 * when the client may be looking for AD in the response.
3226 	 */
3227 	if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) &&
3228 	    ((rdataset->trust != dns_trust_secure) ||
3229 	    (sigrdataset != NULL && sigrdataset->trust != dns_trust_secure)))
3230 		goto cleanup;
3231 
3232 	/*
3233 	 * If the client doesn't want DNSSEC we can discard the sigrdataset
3234 	 * now.
3235 	 */
3236 	if (!WANTDNSSEC(client))
3237 		query_putrdataset(client, &sigrdataset);
3238 	query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
3239 		       DNS_SECTION_AUTHORITY);
3240 
3241  cleanup:
3242 	if (rdataset != NULL)
3243 		query_putrdataset(client, &rdataset);
3244 	if (sigrdataset != NULL)
3245 		query_putrdataset(client, &sigrdataset);
3246 	if (fname != NULL)
3247 		query_releasename(client, &fname);
3248 	if (node != NULL)
3249 		dns_db_detachnode(db, &node);
3250 	if (db != NULL)
3251 		dns_db_detach(&db);
3252 	if (zone != NULL)
3253 		dns_zone_detach(&zone);
3254 	if (zdb != NULL) {
3255 		query_putrdataset(client, &zrdataset);
3256 		if (zsigrdataset != NULL)
3257 			query_putrdataset(client, &zsigrdataset);
3258 		if (zfname != NULL)
3259 			query_releasename(client, &zfname);
3260 		dns_db_detach(&zdb);
3261 	}
3262 }
3263 
3264 static void
3265 fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) {
3266 	if (*rdataset == NULL)
3267 		*rdataset = query_newrdataset(client);
3268 	else  if (dns_rdataset_isassociated(*rdataset))
3269 		dns_rdataset_disassociate(*rdataset);
3270 }
3271 
3272 static void
3273 fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf,
3274 	 isc_buffer_t *nbuf)
3275 {
3276 	if (*fname == NULL) {
3277 		*dbuf = query_getnamebuf(client);
3278 		if (*dbuf == NULL)
3279 			return;
3280 		*fname = query_newname(client, *dbuf, nbuf);
3281 	}
3282 }
3283 
3284 static void
3285 query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node,
3286 	    dns_dbversion_t *version, dns_name_t *name)
3287 {
3288 	dns_fixedname_t fixed;
3289 	dns_name_t *fname = NULL;
3290 	dns_name_t *rname;
3291 	dns_rdataset_t *rdataset, *sigrdataset;
3292 	isc_buffer_t *dbuf, b;
3293 	isc_result_t result;
3294 	unsigned int count;
3295 
3296 	CTRACE("query_addds");
3297 	rname = NULL;
3298 	rdataset = NULL;
3299 	sigrdataset = NULL;
3300 
3301 	/*
3302 	 * We'll need some resources...
3303 	 */
3304 	rdataset = query_newrdataset(client);
3305 	sigrdataset = query_newrdataset(client);
3306 	if (rdataset == NULL || sigrdataset == NULL)
3307 		goto cleanup;
3308 
3309 	/*
3310 	 * Look for the DS record, which may or may not be present.
3311 	 */
3312 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_ds, 0,
3313 				     client->now, rdataset, sigrdataset);
3314 	/*
3315 	 * If we didn't find it, look for an NSEC.
3316 	 */
3317 	if (result == ISC_R_NOTFOUND)
3318 		result = dns_db_findrdataset(db, node, version,
3319 					     dns_rdatatype_nsec, 0, client->now,
3320 					     rdataset, sigrdataset);
3321 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
3322 		goto addnsec3;
3323 	if (!dns_rdataset_isassociated(rdataset) ||
3324 	    !dns_rdataset_isassociated(sigrdataset))
3325 		goto addnsec3;
3326 
3327 	/*
3328 	 * We've already added the NS record, so if the name's not there,
3329 	 * we have other problems.  Use this name rather than calling
3330 	 * query_addrrset().
3331 	 */
3332 	result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY);
3333 	if (result != ISC_R_SUCCESS)
3334 		goto cleanup;
3335 
3336 	rname = NULL;
3337 	dns_message_currentname(client->message, DNS_SECTION_AUTHORITY,
3338 				&rname);
3339 	result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL);
3340 	if (result != ISC_R_SUCCESS)
3341 		goto cleanup;
3342 
3343 	ISC_LIST_APPEND(rname->list, rdataset, link);
3344 	ISC_LIST_APPEND(rname->list, sigrdataset, link);
3345 	rdataset = NULL;
3346 	sigrdataset = NULL;
3347 	return;
3348 
3349    addnsec3:
3350 	if (!dns_db_iszone(db))
3351 		goto cleanup;
3352 	/*
3353 	 * Add the NSEC3 which proves the DS does not exist.
3354 	 */
3355 	dbuf = query_getnamebuf(client);
3356 	if (dbuf == NULL)
3357 		goto cleanup;
3358 	fname = query_newname(client, dbuf, &b);
3359 	dns_fixedname_init(&fixed);
3360 	if (dns_rdataset_isassociated(rdataset))
3361 		dns_rdataset_disassociate(rdataset);
3362 	if (dns_rdataset_isassociated(sigrdataset))
3363 		dns_rdataset_disassociate(sigrdataset);
3364 	query_findclosestnsec3(name, db, version, client, rdataset,
3365 			       sigrdataset, fname, ISC_TRUE,
3366 			       dns_fixedname_name(&fixed));
3367 	if (!dns_rdataset_isassociated(rdataset))
3368 		goto cleanup;
3369 	query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
3370 		       DNS_SECTION_AUTHORITY);
3371 	/*
3372 	 * Did we find the closest provable encloser instead?
3373 	 * If so add the nearest to the closest provable encloser.
3374 	 */
3375 	if (!dns_name_equal(name, dns_fixedname_name(&fixed))) {
3376 		count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1;
3377 		dns_name_getlabelsequence(name,
3378 					  dns_name_countlabels(name) - count,
3379 					  count, dns_fixedname_name(&fixed));
3380 		fixfname(client, &fname, &dbuf, &b);
3381 		fixrdataset(client, &rdataset);
3382 		fixrdataset(client, &sigrdataset);
3383 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
3384 				goto cleanup;
3385 		query_findclosestnsec3(dns_fixedname_name(&fixed), db, version,
3386 				       client, rdataset, sigrdataset, fname,
3387 				       ISC_FALSE, NULL);
3388 		if (!dns_rdataset_isassociated(rdataset))
3389 			goto cleanup;
3390 		query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
3391 			       DNS_SECTION_AUTHORITY);
3392 	}
3393 
3394  cleanup:
3395 	if (rdataset != NULL)
3396 		query_putrdataset(client, &rdataset);
3397 	if (sigrdataset != NULL)
3398 		query_putrdataset(client, &sigrdataset);
3399 	if (fname != NULL)
3400 		query_releasename(client, &fname);
3401 }
3402 
3403 static void
3404 query_addwildcardproof(ns_client_t *client, dns_db_t *db,
3405 		       dns_dbversion_t *version, dns_name_t *name,
3406 		       isc_boolean_t ispositive, isc_boolean_t nodata)
3407 {
3408 	isc_buffer_t *dbuf, b;
3409 	dns_name_t *fname;
3410 	dns_rdataset_t *rdataset, *sigrdataset;
3411 	dns_fixedname_t wfixed;
3412 	dns_name_t *wname;
3413 	dns_dbnode_t *node;
3414 	unsigned int options;
3415 	unsigned int olabels, nlabels, labels;
3416 	isc_result_t result;
3417 	dns_rdata_t rdata = DNS_RDATA_INIT;
3418 	dns_rdata_nsec_t nsec;
3419 	isc_boolean_t have_wname;
3420 	int order;
3421 	dns_fixedname_t cfixed;
3422 	dns_name_t *cname;
3423 	dns_clientinfomethods_t cm;
3424 	dns_clientinfo_t ci;
3425 
3426 	CTRACE("query_addwildcardproof");
3427 	fname = NULL;
3428 	rdataset = NULL;
3429 	sigrdataset = NULL;
3430 	node = NULL;
3431 
3432 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
3433 	dns_clientinfo_init(&ci, client);
3434 
3435 	/*
3436 	 * Get the NOQNAME proof then if !ispositive
3437 	 * get the NOWILDCARD proof.
3438 	 *
3439 	 * DNS_DBFIND_NOWILD finds the NSEC records that covers the
3440 	 * name ignoring any wildcard.  From the owner and next names
3441 	 * of this record you can compute which wildcard (if it exists)
3442 	 * will match by finding the longest common suffix of the
3443 	 * owner name and next names with the qname and prefixing that
3444 	 * with the wildcard label.
3445 	 *
3446 	 * e.g.
3447 	 *   Given:
3448 	 *	example SOA
3449 	 *	example NSEC b.example
3450 	 *	b.example A
3451 	 *	b.example NSEC a.d.example
3452 	 *	a.d.example A
3453 	 *	a.d.example NSEC g.f.example
3454 	 *	g.f.example A
3455 	 *	g.f.example NSEC z.i.example
3456 	 *	z.i.example A
3457 	 *	z.i.example NSEC example
3458 	 *
3459 	 *   QNAME:
3460 	 *   a.example -> example NSEC b.example
3461 	 *	owner common example
3462 	 *	next common example
3463 	 *	wild *.example
3464 	 *   d.b.example -> b.example NSEC a.d.example
3465 	 *	owner common b.example
3466 	 *	next common example
3467 	 *	wild *.b.example
3468 	 *   a.f.example -> a.d.example NSEC g.f.example
3469 	 *	owner common example
3470 	 *	next common f.example
3471 	 *	wild *.f.example
3472 	 *  j.example -> z.i.example NSEC example
3473 	 *	owner common example
3474 	 *	next common example
3475 	 *	wild *.example
3476 	 */
3477 	options = client->query.dboptions | DNS_DBFIND_NOWILD;
3478 	dns_fixedname_init(&wfixed);
3479 	wname = dns_fixedname_name(&wfixed);
3480  again:
3481 	have_wname = ISC_FALSE;
3482 	/*
3483 	 * We'll need some resources...
3484 	 */
3485 	dbuf = query_getnamebuf(client);
3486 	if (dbuf == NULL)
3487 		goto cleanup;
3488 	fname = query_newname(client, dbuf, &b);
3489 	rdataset = query_newrdataset(client);
3490 	sigrdataset = query_newrdataset(client);
3491 	if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
3492 		goto cleanup;
3493 
3494 	result = dns_db_findext(db, name, version, dns_rdatatype_nsec,
3495 				options, 0, &node, fname, &cm, &ci,
3496 				rdataset, sigrdataset);
3497 	if (node != NULL)
3498 		dns_db_detachnode(db, &node);
3499 
3500 	if (!dns_rdataset_isassociated(rdataset)) {
3501 		/*
3502 		 * No NSEC proof available, return NSEC3 proofs instead.
3503 		 */
3504 		dns_fixedname_init(&cfixed);
3505 		cname = dns_fixedname_name(&cfixed);
3506 		/*
3507 		 * Find the closest encloser.
3508 		 */
3509 		dns_name_copy(name, cname, NULL);
3510 		while (result == DNS_R_NXDOMAIN) {
3511 			labels = dns_name_countlabels(cname) - 1;
3512 			/*
3513 			 * Sanity check.
3514 			 */
3515 			if (labels == 0U)
3516 				goto cleanup;
3517 			dns_name_split(cname, labels, NULL, cname);
3518 			result = dns_db_findext(db, cname, version,
3519 						dns_rdatatype_nsec,
3520 						options, 0, NULL, fname,
3521 						&cm, &ci, NULL, NULL);
3522 		}
3523 		/*
3524 		 * Add closest (provable) encloser NSEC3.
3525 		 */
3526 		query_findclosestnsec3(cname, db, NULL, client, rdataset,
3527 				       sigrdataset, fname, ISC_TRUE, cname);
3528 		if (!dns_rdataset_isassociated(rdataset))
3529 			goto cleanup;
3530 		if (!ispositive)
3531 			query_addrrset(client, &fname, &rdataset, &sigrdataset,
3532 				       dbuf, DNS_SECTION_AUTHORITY);
3533 
3534 		/*
3535 		 * Replace resources which were consumed by query_addrrset.
3536 		 */
3537 		if (fname == NULL) {
3538 			dbuf = query_getnamebuf(client);
3539 			if (dbuf == NULL)
3540 				goto cleanup;
3541 			fname = query_newname(client, dbuf, &b);
3542 		}
3543 
3544 		if (rdataset == NULL)
3545 			rdataset = query_newrdataset(client);
3546 		else if (dns_rdataset_isassociated(rdataset))
3547 			dns_rdataset_disassociate(rdataset);
3548 
3549 		if (sigrdataset == NULL)
3550 			sigrdataset = query_newrdataset(client);
3551 		else if (dns_rdataset_isassociated(sigrdataset))
3552 			dns_rdataset_disassociate(sigrdataset);
3553 
3554 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
3555 			goto cleanup;
3556 		/*
3557 		 * Add no qname proof.
3558 		 */
3559 		labels = dns_name_countlabels(cname) + 1;
3560 		if (dns_name_countlabels(name) == labels)
3561 			dns_name_copy(name, wname, NULL);
3562 		else
3563 			dns_name_split(name, labels, NULL, wname);
3564 
3565 		query_findclosestnsec3(wname, db, NULL, client, rdataset,
3566 				       sigrdataset, fname, ISC_FALSE, NULL);
3567 		if (!dns_rdataset_isassociated(rdataset))
3568 			goto cleanup;
3569 		query_addrrset(client, &fname, &rdataset, &sigrdataset,
3570 			       dbuf, DNS_SECTION_AUTHORITY);
3571 
3572 		if (ispositive)
3573 			goto cleanup;
3574 
3575 		/*
3576 		 * Replace resources which were consumed by query_addrrset.
3577 		 */
3578 		if (fname == NULL) {
3579 			dbuf = query_getnamebuf(client);
3580 			if (dbuf == NULL)
3581 				goto cleanup;
3582 			fname = query_newname(client, dbuf, &b);
3583 		}
3584 
3585 		if (rdataset == NULL)
3586 			rdataset = query_newrdataset(client);
3587 		else if (dns_rdataset_isassociated(rdataset))
3588 			dns_rdataset_disassociate(rdataset);
3589 
3590 		if (sigrdataset == NULL)
3591 			sigrdataset = query_newrdataset(client);
3592 		else if (dns_rdataset_isassociated(sigrdataset))
3593 			dns_rdataset_disassociate(sigrdataset);
3594 
3595 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
3596 			goto cleanup;
3597 		/*
3598 		 * Add the no wildcard proof.
3599 		 */
3600 		result = dns_name_concatenate(dns_wildcardname,
3601 					      cname, wname, NULL);
3602 		if (result != ISC_R_SUCCESS)
3603 			goto cleanup;
3604 
3605 		query_findclosestnsec3(wname, db, NULL, client, rdataset,
3606 				       sigrdataset, fname, nodata, NULL);
3607 		if (!dns_rdataset_isassociated(rdataset))
3608 			goto cleanup;
3609 		query_addrrset(client, &fname, &rdataset, &sigrdataset,
3610 			       dbuf, DNS_SECTION_AUTHORITY);
3611 
3612 		goto cleanup;
3613 	} else if (result == DNS_R_NXDOMAIN) {
3614 		if (!ispositive)
3615 			result = dns_rdataset_first(rdataset);
3616 		if (result == ISC_R_SUCCESS) {
3617 			dns_rdataset_current(rdataset, &rdata);
3618 			result = dns_rdata_tostruct(&rdata, &nsec, NULL);
3619 		}
3620 		if (result == ISC_R_SUCCESS) {
3621 			(void)dns_name_fullcompare(name, fname, &order,
3622 						   &olabels);
3623 			(void)dns_name_fullcompare(name, &nsec.next, &order,
3624 						   &nlabels);
3625 			/*
3626 			 * Check for a pathological condition created when
3627 			 * serving some malformed signed zones and bail out.
3628 			 */
3629 			if (dns_name_countlabels(name) == nlabels)
3630 				goto cleanup;
3631 
3632 			if (olabels > nlabels)
3633 				dns_name_split(name, olabels, NULL, wname);
3634 			else
3635 				dns_name_split(name, nlabels, NULL, wname);
3636 			result = dns_name_concatenate(dns_wildcardname,
3637 						      wname, wname, NULL);
3638 			if (result == ISC_R_SUCCESS)
3639 				have_wname = ISC_TRUE;
3640 			dns_rdata_freestruct(&nsec);
3641 		}
3642 		query_addrrset(client, &fname, &rdataset, &sigrdataset,
3643 			       dbuf, DNS_SECTION_AUTHORITY);
3644 	}
3645 	if (rdataset != NULL)
3646 		query_putrdataset(client, &rdataset);
3647 	if (sigrdataset != NULL)
3648 		query_putrdataset(client, &sigrdataset);
3649 	if (fname != NULL)
3650 		query_releasename(client, &fname);
3651 	if (have_wname) {
3652 		ispositive = ISC_TRUE;	/* prevent loop */
3653 		if (!dns_name_equal(name, wname)) {
3654 			name = wname;
3655 			goto again;
3656 		}
3657 	}
3658  cleanup:
3659 	if (rdataset != NULL)
3660 		query_putrdataset(client, &rdataset);
3661 	if (sigrdataset != NULL)
3662 		query_putrdataset(client, &sigrdataset);
3663 	if (fname != NULL)
3664 		query_releasename(client, &fname);
3665 }
3666 
3667 static void
3668 query_addnxrrsetnsec(ns_client_t *client, dns_db_t *db,
3669 		     dns_dbversion_t *version, dns_name_t **namep,
3670 		     dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp)
3671 {
3672 	dns_name_t *name;
3673 	dns_rdataset_t *sigrdataset;
3674 	dns_rdata_t sigrdata;
3675 	dns_rdata_rrsig_t sig;
3676 	unsigned int labels;
3677 	isc_buffer_t *dbuf, b;
3678 	dns_name_t *fname;
3679 	isc_result_t result;
3680 
3681 	name = *namep;
3682 	if ((name->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
3683 		query_addrrset(client, namep, rdatasetp, sigrdatasetp,
3684 			       NULL, DNS_SECTION_AUTHORITY);
3685 		return;
3686 	}
3687 
3688 	if (sigrdatasetp == NULL)
3689 		return;
3690 
3691 	sigrdataset = *sigrdatasetp;
3692 	if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset))
3693 		return;
3694 	result = dns_rdataset_first(sigrdataset);
3695 	if (result != ISC_R_SUCCESS)
3696 		return;
3697 	dns_rdata_init(&sigrdata);
3698 	dns_rdataset_current(sigrdataset, &sigrdata);
3699 	result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
3700 	if (result != ISC_R_SUCCESS)
3701 		return;
3702 
3703 	labels = dns_name_countlabels(name);
3704 	if ((unsigned int)sig.labels + 1 >= labels)
3705 		return;
3706 
3707 	/* XXX */
3708 	query_addwildcardproof(client, db, version, client->query.qname,
3709 			       ISC_TRUE, ISC_FALSE);
3710 
3711 	/*
3712 	 * We'll need some resources...
3713 	 */
3714 	dbuf = query_getnamebuf(client);
3715 	if (dbuf == NULL)
3716 		return;
3717 	fname = query_newname(client, dbuf, &b);
3718 	if (fname == NULL)
3719 		return;
3720 	dns_name_split(name, sig.labels + 1, NULL, fname);
3721 	/* This will succeed, since we've stripped labels. */
3722 	RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname,
3723 					   NULL) == ISC_R_SUCCESS);
3724 	query_addrrset(client, &fname, rdatasetp, sigrdatasetp,
3725 		       dbuf, DNS_SECTION_AUTHORITY);
3726 }
3727 
3728 static void
3729 query_resume(isc_task_t *task, isc_event_t *event) {
3730 	dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
3731 	dns_fetch_t *fetch;
3732 	ns_client_t *client;
3733 	isc_boolean_t fetch_canceled, client_shuttingdown;
3734 	isc_result_t result;
3735 	isc_logcategory_t *logcategory = NS_LOGCATEGORY_QUERY_EERRORS;
3736 	int errorloglevel;
3737 
3738 	/*
3739 	 * Resume a query after recursion.
3740 	 */
3741 
3742 	UNUSED(task);
3743 
3744 	REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
3745 	client = devent->ev_arg;
3746 	REQUIRE(NS_CLIENT_VALID(client));
3747 	REQUIRE(task == client->task);
3748 	REQUIRE(RECURSING(client));
3749 
3750 	LOCK(&client->query.fetchlock);
3751 	if (client->query.fetch != NULL) {
3752 		/*
3753 		 * This is the fetch we've been waiting for.
3754 		 */
3755 		INSIST(devent->fetch == client->query.fetch);
3756 		client->query.fetch = NULL;
3757 		fetch_canceled = ISC_FALSE;
3758 		/*
3759 		 * Update client->now.
3760 		 */
3761 		isc_stdtime_get(&client->now);
3762 	} else {
3763 		/*
3764 		 * This is a fetch completion event for a canceled fetch.
3765 		 * Clean up and don't resume the find.
3766 		 */
3767 		fetch_canceled = ISC_TRUE;
3768 	}
3769 	UNLOCK(&client->query.fetchlock);
3770 	INSIST(client->query.fetch == NULL);
3771 
3772 	client->query.attributes &= ~NS_QUERYATTR_RECURSING;
3773 	fetch = devent->fetch;
3774 	devent->fetch = NULL;
3775 
3776 	/*
3777 	 * If this client is shutting down, or this transaction
3778 	 * has timed out, do not resume the find.
3779 	 */
3780 	client_shuttingdown = ns_client_shuttingdown(client);
3781 	if (fetch_canceled || client_shuttingdown) {
3782 		if (devent->node != NULL)
3783 			dns_db_detachnode(devent->db, &devent->node);
3784 		if (devent->db != NULL)
3785 			dns_db_detach(&devent->db);
3786 		query_putrdataset(client, &devent->rdataset);
3787 		if (devent->sigrdataset != NULL)
3788 			query_putrdataset(client, &devent->sigrdataset);
3789 		isc_event_free(&event);
3790 		if (fetch_canceled)
3791 			query_error(client, DNS_R_SERVFAIL, __LINE__);
3792 		else
3793 			query_next(client, ISC_R_CANCELED);
3794 		/*
3795 		 * This may destroy the client.
3796 		 */
3797 		ns_client_detach(&client);
3798 	} else {
3799 		result = query_find(client, devent, 0);
3800 		if (result != ISC_R_SUCCESS) {
3801 			if (result == DNS_R_SERVFAIL)
3802 				errorloglevel = ISC_LOG_DEBUG(2);
3803 			else
3804 				errorloglevel = ISC_LOG_DEBUG(4);
3805 			if (isc_log_wouldlog(ns_g_lctx, errorloglevel)) {
3806 				dns_resolver_logfetch(fetch, ns_g_lctx,
3807 						      logcategory,
3808 						      NS_LOGMODULE_QUERY,
3809 						      errorloglevel, ISC_FALSE);
3810 			}
3811 		}
3812 	}
3813 
3814 	dns_resolver_destroyfetch(&fetch);
3815 }
3816 
3817 static void
3818 prefetch_done(isc_task_t *task, isc_event_t *event) {
3819 	dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
3820 	ns_client_t *client;
3821 
3822 	UNUSED(task);
3823 
3824 	REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
3825 	client = devent->ev_arg;
3826 	REQUIRE(NS_CLIENT_VALID(client));
3827 	REQUIRE(task == client->task);
3828 
3829 	LOCK(&client->query.fetchlock);
3830 	if (client->query.prefetch != NULL) {
3831 		INSIST(devent->fetch == client->query.prefetch);
3832 		client->query.prefetch = NULL;
3833 	}
3834 	UNLOCK(&client->query.fetchlock);
3835 	if (devent->fetch != NULL)
3836 		dns_resolver_destroyfetch(&devent->fetch);
3837 	if (devent->node != NULL)
3838 		dns_db_detachnode(devent->db, &devent->node);
3839 	if (devent->db != NULL)
3840 		dns_db_detach(&devent->db);
3841 	query_putrdataset(client, &devent->rdataset);
3842 	isc_event_free(&event);
3843 	ns_client_detach(&client);
3844 }
3845 
3846 static void
3847 query_prefetch(ns_client_t *client, dns_name_t *qname,
3848 	       dns_rdataset_t *rdataset)
3849 {
3850 	isc_result_t result;
3851 	isc_sockaddr_t *peeraddr;
3852 	dns_rdataset_t *tmprdataset;
3853 	ns_client_t *dummy = NULL;
3854 	unsigned int options;
3855 
3856 	if (client->query.prefetch != NULL ||
3857 	    client->view->prefetch_trigger == 0U ||
3858 	    rdataset->ttl > client->view->prefetch_trigger ||
3859 	    (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0)
3860 		return;
3861 
3862 	if (client->recursionquota == NULL) {
3863 		result = isc_quota_attach(&ns_g_server->recursionquota,
3864 					  &client->recursionquota);
3865 		if (result != ISC_R_SUCCESS)
3866 			return;
3867 		isc_stats_increment(ns_g_server->nsstats,
3868 				    dns_nsstatscounter_recursclients);
3869 	}
3870 
3871 	tmprdataset = query_newrdataset(client);
3872 	if (tmprdataset == NULL)
3873 		return;
3874 	if ((client->attributes & NS_CLIENTATTR_TCP) == 0)
3875 		peeraddr = &client->peeraddr;
3876 	else
3877 		peeraddr = NULL;
3878 	ns_client_attach(client, &dummy);
3879 	options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH;
3880 	result = dns_resolver_createfetch3(client->view->resolver,
3881 					   qname, rdataset->type, NULL, NULL,
3882 					   NULL, peeraddr, client->message->id,
3883 					   options, 0, NULL, client->task,
3884 					   prefetch_done, client,
3885 					   tmprdataset, NULL,
3886 					   &client->query.prefetch);
3887 	if (result != ISC_R_SUCCESS) {
3888 		query_putrdataset(client, &tmprdataset);
3889 		ns_client_detach(&dummy);
3890 	}
3891 	dns_rdataset_clearprefetch(rdataset);
3892 }
3893 
3894 static isc_result_t
3895 query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
3896 	      dns_name_t *qdomain, dns_rdataset_t *nameservers,
3897 	      isc_boolean_t resuming)
3898 {
3899 	isc_result_t result;
3900 	dns_rdataset_t *rdataset, *sigrdataset;
3901 	isc_sockaddr_t *peeraddr;
3902 
3903 	if (!resuming)
3904 		inc_stats(client, dns_nsstatscounter_recursion);
3905 
3906 	/*
3907 	 * We are about to recurse, which means that this client will
3908 	 * be unavailable for serving new requests for an indeterminate
3909 	 * amount of time.  If this client is currently responsible
3910 	 * for handling incoming queries, set up a new client
3911 	 * object to handle them while we are waiting for a
3912 	 * response.  There is no need to replace TCP clients
3913 	 * because those have already been replaced when the
3914 	 * connection was accepted (if allowed by the TCP quota).
3915 	 */
3916 	if (client->recursionquota == NULL) {
3917 		result = isc_quota_attach(&ns_g_server->recursionquota,
3918 					  &client->recursionquota);
3919 
3920 		isc_stats_increment(ns_g_server->nsstats,
3921 				    dns_nsstatscounter_recursclients);
3922 
3923 		if  (result == ISC_R_SOFTQUOTA) {
3924 			static isc_stdtime_t last = 0;
3925 			isc_stdtime_t now;
3926 			isc_stdtime_get(&now);
3927 			if (now != last) {
3928 				last = now;
3929 				ns_client_log(client, NS_LOGCATEGORY_CLIENT,
3930 					      NS_LOGMODULE_QUERY,
3931 					      ISC_LOG_WARNING,
3932 					      "recursive-clients soft limit "
3933 					      "exceeded (%d/%d/%d), "
3934 					      "aborting oldest query",
3935 					      client->recursionquota->used,
3936 					      client->recursionquota->soft,
3937 					      client->recursionquota->max);
3938 			}
3939 			ns_client_killoldestquery(client);
3940 			result = ISC_R_SUCCESS;
3941 		} else if (result == ISC_R_QUOTA) {
3942 			static isc_stdtime_t last = 0;
3943 			isc_stdtime_t now;
3944 			isc_stdtime_get(&now);
3945 			if (now != last) {
3946 				last = now;
3947 				ns_client_log(client, NS_LOGCATEGORY_CLIENT,
3948 					      NS_LOGMODULE_QUERY,
3949 					      ISC_LOG_WARNING,
3950 					      "no more recursive clients "
3951 					      "(%d/%d/%d): %s",
3952 					      ns_g_server->recursionquota.used,
3953 					      ns_g_server->recursionquota.soft,
3954 					      ns_g_server->recursionquota.max,
3955 					      isc_result_totext(result));
3956 			}
3957 			ns_client_killoldestquery(client);
3958 		}
3959 		if (result == ISC_R_SUCCESS && !client->mortal &&
3960 		    (client->attributes & NS_CLIENTATTR_TCP) == 0) {
3961 			result = ns_client_replace(client);
3962 			if (result != ISC_R_SUCCESS) {
3963 				ns_client_log(client, NS_LOGCATEGORY_CLIENT,
3964 					      NS_LOGMODULE_QUERY,
3965 					      ISC_LOG_WARNING,
3966 					      "ns_client_replace() failed: %s",
3967 					      isc_result_totext(result));
3968 				isc_quota_detach(&client->recursionquota);
3969 				isc_stats_decrement(ns_g_server->nsstats,
3970 				    dns_nsstatscounter_recursclients);
3971 			}
3972 		}
3973 		if (result != ISC_R_SUCCESS)
3974 			return (result);
3975 		ns_client_recursing(client);
3976 	}
3977 
3978 	/*
3979 	 * Invoke the resolver.
3980 	 */
3981 	REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns);
3982 	REQUIRE(client->query.fetch == NULL);
3983 
3984 	rdataset = query_newrdataset(client);
3985 	if (rdataset == NULL)
3986 		return (ISC_R_NOMEMORY);
3987 	if (WANTDNSSEC(client)) {
3988 		sigrdataset = query_newrdataset(client);
3989 		if (sigrdataset == NULL) {
3990 			query_putrdataset(client, &rdataset);
3991 			return (ISC_R_NOMEMORY);
3992 		}
3993 	} else
3994 		sigrdataset = NULL;
3995 
3996 	if (client->query.timerset == ISC_FALSE)
3997 		ns_client_settimeout(client, 60);
3998 	if ((client->attributes & NS_CLIENTATTR_TCP) == 0)
3999 		peeraddr = &client->peeraddr;
4000 	else
4001 		peeraddr = NULL;
4002 	result = dns_resolver_createfetch3(client->view->resolver,
4003 					   qname, qtype, qdomain, nameservers,
4004 					   NULL, peeraddr, client->message->id,
4005 					   client->query.fetchoptions, 0, NULL,
4006 					   client->task, query_resume, client,
4007 					   rdataset, sigrdataset,
4008 					   &client->query.fetch);
4009 
4010 	if (result == ISC_R_SUCCESS) {
4011 		/*
4012 		 * Record that we're waiting for an event.  A client which
4013 		 * is shutting down will not be destroyed until all the
4014 		 * events have been received.
4015 		 */
4016 	} else {
4017 		query_putrdataset(client, &rdataset);
4018 		if (sigrdataset != NULL)
4019 			query_putrdataset(client, &sigrdataset);
4020 	}
4021 
4022 	return (result);
4023 }
4024 
4025 static inline void
4026 rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep,
4027 	  dns_rdataset_t **rdatasetp)
4028 {
4029 	if (nodep != NULL && *nodep != NULL) {
4030 		REQUIRE(dbp != NULL && *dbp != NULL);
4031 		dns_db_detachnode(*dbp, nodep);
4032 	}
4033 	if (dbp != NULL && *dbp != NULL)
4034 		dns_db_detach(dbp);
4035 	if (zonep != NULL && *zonep != NULL)
4036 		dns_zone_detach(zonep);
4037 	if (rdatasetp != NULL && *rdatasetp != NULL &&
4038 	    dns_rdataset_isassociated(*rdatasetp))
4039 		dns_rdataset_disassociate(*rdatasetp);
4040 }
4041 
4042 static inline void
4043 rpz_match_clear(dns_rpz_st_t *st) {
4044 	rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
4045 	st->m.version = NULL;
4046 }
4047 
4048 static inline isc_result_t
4049 rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp) {
4050 	REQUIRE(rdatasetp != NULL);
4051 
4052 	CTRACE("rpz_ready");
4053 
4054 	if (*rdatasetp == NULL) {
4055 		*rdatasetp = query_newrdataset(client);
4056 		if (*rdatasetp == NULL)
4057 			return (DNS_R_SERVFAIL);
4058 	} else if (dns_rdataset_isassociated(*rdatasetp)) {
4059 		dns_rdataset_disassociate(*rdatasetp);
4060 	}
4061 	return (ISC_R_SUCCESS);
4062 }
4063 
4064 static void
4065 rpz_st_clear(ns_client_t *client) {
4066 	dns_rpz_st_t *st = client->query.rpz_st;
4067 
4068 	CTRACE("rpz_st_clear");
4069 
4070 	if (st->m.rdataset != NULL)
4071 		query_putrdataset(client, &st->m.rdataset);
4072 	rpz_match_clear(st);
4073 
4074 	rpz_clean(NULL, &st->r.db, NULL, NULL);
4075 	if (st->r.ns_rdataset != NULL)
4076 		query_putrdataset(client, &st->r.ns_rdataset);
4077 	if (st->r.r_rdataset != NULL)
4078 		query_putrdataset(client, &st->r.r_rdataset);
4079 
4080 	rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL);
4081 	if (st->q.rdataset != NULL)
4082 		query_putrdataset(client, &st->q.rdataset);
4083 	if (st->q.sigrdataset != NULL)
4084 		query_putrdataset(client, &st->q.sigrdataset);
4085 	st->state = 0;
4086 	st->m.type = DNS_RPZ_TYPE_BAD;
4087 	st->m.policy = DNS_RPZ_POLICY_MISS;
4088 }
4089 
4090 static dns_rpz_zbits_t
4091 rpz_get_zbits(ns_client_t *client,
4092 	      dns_rdatatype_t ip_type, dns_rpz_type_t rpz_type)
4093 {
4094 	dns_rpz_st_t *st;
4095 	dns_rpz_zbits_t zbits;
4096 
4097 	REQUIRE(client != NULL);
4098 	REQUIRE(client->query.rpz_st != NULL);
4099 
4100 	st = client->query.rpz_st;
4101 
4102 	switch (rpz_type) {
4103 	case DNS_RPZ_TYPE_CLIENT_IP:
4104 		zbits = st->have.client_ip;
4105 		break;
4106 	case DNS_RPZ_TYPE_QNAME:
4107 		zbits = st->have.qname;
4108 		break;
4109 	case DNS_RPZ_TYPE_IP:
4110 		if (ip_type == dns_rdatatype_a) {
4111 			zbits = st->have.ipv4;
4112 		} else if (ip_type == dns_rdatatype_aaaa) {
4113 			zbits = st->have.ipv6;
4114 		} else {
4115 			zbits = st->have.ip;
4116 		}
4117 		break;
4118 	case DNS_RPZ_TYPE_NSDNAME:
4119 		zbits = st->have.nsdname;
4120 		break;
4121 	case DNS_RPZ_TYPE_NSIP:
4122 		if (ip_type == dns_rdatatype_a) {
4123 			zbits = st->have.nsipv4;
4124 		} else if (ip_type == dns_rdatatype_aaaa) {
4125 			zbits = st->have.nsipv6;
4126 		} else {
4127 			zbits = st->have.nsip;
4128 		}
4129 		break;
4130 	default:
4131 		INSIST(0);
4132 		break;
4133 	}
4134 
4135 	/*
4136 	 * Choose
4137 	 *	the earliest configured policy zone (rpz->num)
4138 	 *	QNAME over IP over NSDNAME over NSIP (rpz_type)
4139 	 *	the smallest name,
4140 	 *	the longest IP address prefix,
4141 	 *	the lexically smallest address.
4142 	 */
4143 	if (st->m.policy != DNS_RPZ_POLICY_MISS) {
4144 		if (st->m.type >= rpz_type) {
4145 			zbits &= DNS_RPZ_ZMASK(st->m.rpz->num);
4146 		} else{
4147 			zbits &= DNS_RPZ_ZMASK(st->m.rpz->num) >> 1;
4148 		}
4149 	}
4150 
4151 	/*
4152 	 * If the client wants recursion, allow only compatible policies.
4153 	 */
4154 	if (!RECURSIONOK(client))
4155 		zbits &= st->popt.no_rd_ok;
4156 
4157 	return (zbits);
4158 }
4159 
4160 /*
4161  * Get an NS, A, or AAAA rrset related to the response for the client
4162  * to check the contents of that rrset for hits by eligible policy zones.
4163  */
4164 static isc_result_t
4165 rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
4166 	       dns_rpz_type_t rpz_type, dns_db_t **dbp, dns_dbversion_t *version,
4167 	       dns_rdataset_t **rdatasetp, isc_boolean_t resuming)
4168 {
4169 	dns_rpz_st_t *st;
4170 	isc_boolean_t is_zone;
4171 	dns_dbnode_t *node;
4172 	dns_fixedname_t fixed;
4173 	dns_name_t *found;
4174 	isc_result_t result;
4175 	dns_clientinfomethods_t cm;
4176 	dns_clientinfo_t ci;
4177 
4178 	CTRACE("rpz_rrset_find");
4179 
4180 	st = client->query.rpz_st;
4181 	if ((st->state & DNS_RPZ_RECURSING) != 0) {
4182 		INSIST(st->r.r_type == type);
4183 		INSIST(dns_name_equal(name, st->r_name));
4184 		INSIST(*rdatasetp == NULL ||
4185 		       !dns_rdataset_isassociated(*rdatasetp));
4186 		INSIST(*dbp == NULL);
4187 		st->state &= ~DNS_RPZ_RECURSING;
4188 		*dbp = st->r.db;
4189 		st->r.db = NULL;
4190 		if (*rdatasetp != NULL)
4191 			query_putrdataset(client, rdatasetp);
4192 		*rdatasetp = st->r.r_rdataset;
4193 		st->r.r_rdataset = NULL;
4194 		result = st->r.r_result;
4195 		if (result == DNS_R_DELEGATION) {
4196 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
4197 				     rpz_type, " rpz_rrset_find(1)", result);
4198 			st->m.policy = DNS_RPZ_POLICY_ERROR;
4199 			result = DNS_R_SERVFAIL;
4200 		}
4201 		return (result);
4202 	}
4203 
4204 	result = rpz_ready(client, rdatasetp);
4205 	if (result != ISC_R_SUCCESS) {
4206 		st->m.policy = DNS_RPZ_POLICY_ERROR;
4207 		return (result);
4208 	}
4209 	if (*dbp != NULL) {
4210 		is_zone = ISC_FALSE;
4211 	} else {
4212 		dns_zone_t *zone;
4213 
4214 		version = NULL;
4215 		zone = NULL;
4216 		result = query_getdb(client, name, type, 0, &zone, dbp,
4217 				     &version, &is_zone);
4218 		if (result != ISC_R_SUCCESS) {
4219 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
4220 				     rpz_type, " rpz_rrset_find(2)", result);
4221 			st->m.policy = DNS_RPZ_POLICY_ERROR;
4222 			if (zone != NULL)
4223 				dns_zone_detach(&zone);
4224 			return (result);
4225 		}
4226 		if (zone != NULL)
4227 			dns_zone_detach(&zone);
4228 	}
4229 
4230 	node = NULL;
4231 	dns_fixedname_init(&fixed);
4232 	found = dns_fixedname_name(&fixed);
4233 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
4234 	dns_clientinfo_init(&ci, client);
4235 	result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK,
4236 				client->now, &node, found,
4237 				&cm, &ci, *rdatasetp, NULL);
4238 	if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) {
4239 		/*
4240 		 * Try the cache if we're authoritative for an
4241 		 * ancestor but not the domain itself.
4242 		 */
4243 		rpz_clean(NULL, dbp, &node, rdatasetp);
4244 		version = NULL;
4245 		dns_db_attach(client->view->cachedb, dbp);
4246 		result = dns_db_findext(*dbp, name, version, dns_rdatatype_ns,
4247 					0, client->now, &node, found,
4248 					&cm, &ci, *rdatasetp, NULL);
4249 	}
4250 	rpz_clean(NULL, dbp, &node, NULL);
4251 	if (result == DNS_R_DELEGATION) {
4252 		rpz_clean(NULL, NULL, NULL, rdatasetp);
4253 		/*
4254 		 * Recurse for NS rrset or A or AAAA rrset for an NS.
4255 		 * Do not recurse for addresses for the query name.
4256 		 */
4257 		if (rpz_type == DNS_RPZ_TYPE_IP) {
4258 			result = DNS_R_NXRRSET;
4259 		} else {
4260 			dns_name_copy(name, st->r_name, NULL);
4261 			result = query_recurse(client, type, st->r_name,
4262 					       NULL, NULL, resuming);
4263 			if (result == ISC_R_SUCCESS) {
4264 				st->state |= DNS_RPZ_RECURSING;
4265 				result = DNS_R_DELEGATION;
4266 			}
4267 		}
4268 	}
4269 	return (result);
4270 }
4271 
4272 /*
4273  * Compute a policy owner name, p_name, in a policy zone given the needed
4274  * policy type and the trigger name.
4275  */
4276 static isc_result_t
4277 rpz_get_p_name(ns_client_t *client, dns_name_t *p_name,
4278 	       dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
4279 	       dns_name_t *trig_name)
4280 {
4281 	dns_offsets_t prefix_offsets;
4282 	dns_name_t prefix, *suffix;
4283 	unsigned int first, labels;
4284 	isc_result_t result;
4285 
4286 	CTRACE("rpz_get_p_name");
4287 
4288 	/*
4289 	 * The policy owner name consists of a suffix depending on the type
4290 	 * and policy zone and a prefix that is the longest possible string
4291 	 * from the trigger name that keesp the resulting policy owner name
4292 	 * from being too long.
4293 	 */
4294 	switch (rpz_type) {
4295 	case DNS_RPZ_TYPE_CLIENT_IP:
4296 		suffix = &rpz->client_ip;
4297 		break;
4298 	case DNS_RPZ_TYPE_QNAME:
4299 		suffix = &rpz->origin;
4300 		break;
4301 	case DNS_RPZ_TYPE_IP:
4302 		suffix = &rpz->ip;
4303 		break;
4304 	case DNS_RPZ_TYPE_NSDNAME:
4305 		suffix = &rpz->nsdname;
4306 		break;
4307 	case DNS_RPZ_TYPE_NSIP:
4308 		suffix = &rpz->nsip;
4309 		break;
4310 	default:
4311 		INSIST(0);
4312 	}
4313 
4314 	/*
4315 	 * Start with relative version of the full trigger name,
4316 	 * and trim enough allow the addition of the suffix.
4317 	 */
4318 	dns_name_init(&prefix, prefix_offsets);
4319 	labels = dns_name_countlabels(trig_name);
4320 	first = 0;
4321 	for (;;) {
4322 		dns_name_getlabelsequence(trig_name, first, labels-first-1,
4323 					  &prefix);
4324 		result = dns_name_concatenate(&prefix, suffix, p_name, NULL);
4325 		if (result == ISC_R_SUCCESS)
4326 			break;
4327 		INSIST(result == DNS_R_NAMETOOLONG);
4328 		/*
4329 		 * Trim the trigger name until the combination is not too long.
4330 		 */
4331 		if (labels-first < 2) {
4332 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix,
4333 				     rpz_type, " concatentate()", result);
4334 			return (ISC_R_FAILURE);
4335 		}
4336 		/*
4337 		 * Complain once about trimming the trigger name.
4338 		 */
4339 		if (first == 0) {
4340 			rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix,
4341 				     rpz_type, " concatentate()", result);
4342 		}
4343 		++first;
4344 	}
4345 	return (ISC_R_SUCCESS);
4346 }
4347 
4348 /*
4349  * Look in policy zone rpz for a policy of rpz_type by p_name.
4350  * The self-name (usually the client qname or an NS name) is compared with
4351  * the target of a CNAME policy for the old style passthru encoding.
4352  * If found, the policy is recorded in *zonep, *dbp, *versionp, *nodep,
4353  * *rdatasetp, and *policyp.
4354  * The target DNS type, qtype, chooses the best rdataset for *rdatasetp.
4355  * The caller must decide if the found policy is most suitable, including
4356  * better than a previously found policy.
4357  * If it is best, the caller records it in client->query.rpz_st->m.
4358  */
4359 static isc_result_t
4360 rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype,
4361 	   dns_name_t *p_name, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
4362 	   dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp,
4363 	   dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
4364 	   dns_rpz_policy_t *policyp)
4365 {
4366 	dns_fixedname_t foundf;
4367 	dns_name_t *found;
4368 	isc_result_t result;
4369 	dns_clientinfomethods_t cm;
4370 	dns_clientinfo_t ci;
4371 
4372 	REQUIRE(nodep != NULL);
4373 
4374 	CTRACE("rpz_find_p");
4375 
4376 	/*
4377 	 * Try to find either a CNAME or the type of record demanded by the
4378 	 * request from the policy zone.
4379 	 */
4380 	rpz_clean(zonep, dbp, nodep, rdatasetp);
4381 	result = rpz_ready(client, rdatasetp);
4382 	if (result != ISC_R_SUCCESS)
4383 		return (DNS_R_SERVFAIL);
4384 	*versionp = NULL;
4385 	result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp);
4386 	if (result != ISC_R_SUCCESS)
4387 		return (DNS_R_NXDOMAIN);
4388 	dns_fixedname_init(&foundf);
4389 	found = dns_fixedname_name(&foundf);
4390 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
4391 	dns_clientinfo_init(&ci, client);
4392 	result = dns_db_findext(*dbp, p_name, *versionp, dns_rdatatype_any, 0,
4393 				client->now, nodep, found, &cm, &ci,
4394 				*rdatasetp, NULL);
4395 	/*
4396 	 * Choose the best rdataset if we found something.
4397 	 */
4398 	if (result == ISC_R_SUCCESS) {
4399 		dns_rdatasetiter_t *rdsiter;
4400 
4401 		rdsiter = NULL;
4402 		result = dns_db_allrdatasets(*dbp, *nodep, *versionp, 0,
4403 					     &rdsiter);
4404 		if (result != ISC_R_SUCCESS) {
4405 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name,
4406 				     rpz_type, " allrdatasets()", result);
4407 			return (DNS_R_SERVFAIL);
4408 		}
4409 		for (result = dns_rdatasetiter_first(rdsiter);
4410 		     result == ISC_R_SUCCESS;
4411 		     result = dns_rdatasetiter_next(rdsiter)) {
4412 			dns_rdatasetiter_current(rdsiter, *rdatasetp);
4413 			if ((*rdatasetp)->type == dns_rdatatype_cname ||
4414 			    (*rdatasetp)->type == qtype)
4415 				break;
4416 			dns_rdataset_disassociate(*rdatasetp);
4417 		}
4418 		dns_rdatasetiter_destroy(&rdsiter);
4419 		if (result != ISC_R_SUCCESS) {
4420 			if (result != ISC_R_NOMORE) {
4421 				rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
4422 					     p_name, rpz_type,
4423 					     " rdatasetiter", result);
4424 				return (DNS_R_SERVFAIL);
4425 			}
4426 			/*
4427 			 * Ask again to get the right DNS_R_DNAME/NXRRSET/...
4428 			 * result if there is neither a CNAME nor target type.
4429 			 */
4430 			if (dns_rdataset_isassociated(*rdatasetp))
4431 				dns_rdataset_disassociate(*rdatasetp);
4432 			dns_db_detachnode(*dbp, nodep);
4433 
4434 			if (qtype == dns_rdatatype_rrsig ||
4435 			    qtype == dns_rdatatype_sig)
4436 				result = DNS_R_NXRRSET;
4437 			else
4438 				result = dns_db_findext(*dbp, p_name, *versionp,
4439 							qtype, 0, client->now,
4440 							nodep, found, &cm, &ci,
4441 							*rdatasetp, NULL);
4442 		}
4443 	}
4444 	switch (result) {
4445 	case ISC_R_SUCCESS:
4446 		if ((*rdatasetp)->type != dns_rdatatype_cname) {
4447 			*policyp = DNS_RPZ_POLICY_RECORD;
4448 		} else {
4449 			*policyp = dns_rpz_decode_cname(rpz, *rdatasetp,
4450 							self_name);
4451 			if ((*policyp == DNS_RPZ_POLICY_RECORD ||
4452 			     *policyp == DNS_RPZ_POLICY_WILDCNAME) &&
4453 			    qtype != dns_rdatatype_cname &&
4454 			    qtype != dns_rdatatype_any)
4455 				return (DNS_R_CNAME);
4456 		}
4457 		return (ISC_R_SUCCESS);
4458 	case DNS_R_NXRRSET:
4459 		*policyp = DNS_RPZ_POLICY_NODATA;
4460 		return (result);
4461 	case DNS_R_DNAME:
4462 		/*
4463 		 * DNAME policy RRs have very few if any uses that are not
4464 		 * better served with simple wildcards.  Making them work would
4465 		 * require complications to get the number of labels matched
4466 		 * in the name or the found name to the main DNS_R_DNAME case
4467 		 * in query_find().  The domain also does not appear in the
4468 		 * summary database at the right level, so this happens only
4469 		 * with a single policy zone when we have no summary database.
4470 		 * Treat it as a miss.
4471 		 */
4472 	case DNS_R_NXDOMAIN:
4473 	case DNS_R_EMPTYNAME:
4474 		return (DNS_R_NXDOMAIN);
4475 	default:
4476 		rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
4477 			     "", result);
4478 		return (DNS_R_SERVFAIL);
4479 	}
4480 }
4481 
4482 static void
4483 rpz_save_p(dns_rpz_st_t *st, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
4484 	   dns_rpz_policy_t policy, dns_name_t *p_name, dns_rpz_prefix_t prefix,
4485 	   isc_result_t result, dns_zone_t **zonep, dns_db_t **dbp,
4486 	   dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
4487 	   dns_dbversion_t *version)
4488 {
4489 	dns_rdataset_t *trdataset;
4490 
4491 	rpz_match_clear(st);
4492 	st->m.rpz = rpz;
4493 	st->m.type = rpz_type;
4494 	st->m.policy = policy;
4495 	dns_name_copy(p_name, st->p_name, NULL);
4496 	st->m.prefix = prefix;
4497 	st->m.result = result;
4498 	st->m.zone = *zonep;
4499 	*zonep = NULL;
4500 	st->m.db = *dbp;
4501 	*dbp = NULL;
4502 	st->m.node = *nodep;
4503 	*nodep = NULL;
4504 	if (*rdatasetp != NULL && dns_rdataset_isassociated(*rdatasetp)) {
4505 		/*
4506 		 * Save the replacement rdataset from the policy
4507 		 * and make the previous replacement rdataset scratch.
4508 		 */
4509 		trdataset = st->m.rdataset;
4510 		st->m.rdataset = *rdatasetp;
4511 		*rdatasetp = trdataset;
4512 		st->m.ttl = ISC_MIN(st->m.rdataset->ttl, rpz->max_policy_ttl);
4513 	} else {
4514 		st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT, rpz->max_policy_ttl);
4515 	}
4516 	st->m.version = version;
4517 }
4518 
4519 /*
4520  * Check this address in every eligible policy zone.
4521  */
4522 static isc_result_t
4523 rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr,
4524 	       dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
4525 	       dns_rpz_zbits_t zbits, dns_rdataset_t **p_rdatasetp)
4526 {
4527 	dns_rpz_zones_t *rpzs;
4528 	dns_rpz_st_t *st;
4529 	dns_rpz_zone_t *rpz;
4530 	dns_rpz_prefix_t prefix;
4531 	dns_rpz_num_t rpz_num;
4532 	dns_fixedname_t ip_namef, p_namef;
4533 	dns_name_t *ip_name, *p_name;
4534 	dns_zone_t *p_zone;
4535 	dns_db_t *p_db;
4536 	dns_dbversion_t *p_version;
4537 	dns_dbnode_t *p_node;
4538 	dns_rpz_policy_t policy;
4539 	isc_result_t result;
4540 
4541 	CTRACE("rpz_rewrite_ip");
4542 
4543 	dns_fixedname_init(&ip_namef);
4544 	ip_name = dns_fixedname_name(&ip_namef);
4545 
4546 	p_zone = NULL;
4547 	p_db = NULL;
4548 	p_node = NULL;
4549 
4550 	rpzs = client->view->rpzs;
4551 	st = client->query.rpz_st;
4552 	while (zbits != 0) {
4553 		rpz_num = dns_rpz_find_ip(rpzs, rpz_type, zbits, netaddr,
4554 					  ip_name, &prefix);
4555 		if (rpz_num == DNS_RPZ_INVALID_NUM)
4556 			break;
4557 		zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1);
4558 
4559 		/*
4560 		 * Do not try applying policy zones that cannot replace a
4561 		 * previously found policy zone.
4562 		 * Stop looking if the next best choice cannot
4563 		 * replace what we already have.
4564 		 */
4565 		rpz = rpzs->zones[rpz_num];
4566 		if (st->m.policy != DNS_RPZ_POLICY_MISS) {
4567 			if (st->m.rpz->num < rpz->num)
4568 				break;
4569 			if (st->m.rpz->num == rpz->num &&
4570 			    (st->m.type < rpz_type ||
4571 			     st->m.prefix > prefix))
4572 				break;
4573 		}
4574 
4575 		/*
4576 		 * Get the policy for a prefix at least as long
4577 		 * as the prefix of the entry we had before.
4578 		 */
4579 		dns_fixedname_init(&p_namef);
4580 		p_name = dns_fixedname_name(&p_namef);
4581 		result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name);
4582 		if (result != ISC_R_SUCCESS)
4583 			continue;
4584 		result = rpz_find_p(client, ip_name, qtype,
4585 				    p_name, rpz, rpz_type,
4586 				    &p_zone, &p_db, &p_version, &p_node,
4587 				    p_rdatasetp, &policy);
4588 		switch (result) {
4589 		case DNS_R_NXDOMAIN:
4590 			/*
4591 			 * Continue after a policy record that is missing
4592 			 * contrary to the summary data.  The summary
4593 			 * data can out of date during races with and among
4594 			 * policy zone updates.
4595 			 */
4596 			CTRACE("rpz_rewrite_ip: mismatched summary data; "
4597 			       "continuing");
4598 			continue;
4599 		case DNS_R_SERVFAIL:
4600 			rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
4601 			st->m.policy = DNS_RPZ_POLICY_ERROR;
4602 			return (DNS_R_SERVFAIL);
4603 		default:
4604 			/*
4605 			 * Forget this policy if it is not preferable
4606 			 * to the previously found policy.
4607 			 * If this policy is not good, then stop looking
4608 			 * because none of the later policy zones would work.
4609 			 *
4610 			 * With more than one applicable policy, prefer
4611 			 * the earliest configured policy,
4612 			 * client-IP over QNAME over IP over NSDNAME over NSIP,
4613 			 * the longest prefix
4614 			 * the lexically smallest address.
4615 			 * dns_rpz_find_ip() ensures st->m.rpz->num >= rpz->num.
4616 			 * We can compare new and current p_name because
4617 			 * both are of the same type and in the same zone.
4618 			 * The tests above eliminate other reasons to
4619 			 * reject this policy.  If this policy can't work,
4620 			 * then neither can later zones.
4621 			 */
4622 			if (st->m.policy != DNS_RPZ_POLICY_MISS &&
4623 			    rpz->num == st->m.rpz->num &&
4624 			     (st->m.type == rpz_type &&
4625 			      st->m.prefix == prefix &&
4626 			      0 > dns_name_rdatacompare(st->p_name, p_name)))
4627 				break;
4628 
4629 			/*
4630 			 * Stop checking after saving an enabled hit in this
4631 			 * policy zone.  The radix tree in the policy zone
4632 			 * ensures that we found the longest match.
4633 			 */
4634 			if (rpz->policy != DNS_RPZ_POLICY_DISABLED) {
4635 				CTRACE("rpz_rewrite_ip: rpz_save_p");
4636 				rpz_save_p(st, rpz, rpz_type,
4637 					   policy, p_name, prefix, result,
4638 					   &p_zone, &p_db, &p_node,
4639 					   p_rdatasetp, p_version);
4640 				break;
4641 			}
4642 
4643 			/*
4644 			 * Log DNS_RPZ_POLICY_DISABLED zones
4645 			 * and try the next eligible policy zone.
4646 			 */
4647 			rpz_log_rewrite(client, ISC_TRUE, policy, rpz_type,
4648 					p_zone, p_name);
4649 		}
4650 	}
4651 
4652 	rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
4653 	return (ISC_R_SUCCESS);
4654 }
4655 
4656 /*
4657  * Check the IP addresses in the A or AAAA rrsets for name against
4658  * all eligible rpz_type (IP or NSIP) response policy rewrite rules.
4659  */
4660 static isc_result_t
4661 rpz_rewrite_ip_rrset(ns_client_t *client,
4662 		     dns_name_t *name, dns_rdatatype_t qtype,
4663 		     dns_rpz_type_t rpz_type, dns_rdatatype_t ip_type,
4664 		     dns_db_t **ip_dbp, dns_dbversion_t *ip_version,
4665 		     dns_rdataset_t **ip_rdatasetp,
4666 		     dns_rdataset_t **p_rdatasetp, isc_boolean_t resuming)
4667 {
4668 	dns_rpz_zbits_t zbits;
4669 	isc_netaddr_t netaddr;
4670 	struct in_addr ina;
4671 	struct in6_addr in6a;
4672 	isc_result_t result;
4673 
4674 	CTRACE("rpz_rewrite_ip_rrset");
4675 
4676 	zbits = rpz_get_zbits(client, ip_type, rpz_type);
4677 	if (zbits == 0)
4678 		return (ISC_R_SUCCESS);
4679 
4680 	/*
4681 	 * Get the A or AAAA rdataset.
4682 	 */
4683 	result = rpz_rrset_find(client, name, ip_type, rpz_type, ip_dbp,
4684 				ip_version, ip_rdatasetp, resuming);
4685 	switch (result) {
4686 	case ISC_R_SUCCESS:
4687 	case DNS_R_GLUE:
4688 	case DNS_R_ZONECUT:
4689 		break;
4690 	case DNS_R_EMPTYNAME:
4691 	case DNS_R_EMPTYWILD:
4692 	case DNS_R_NXDOMAIN:
4693 	case DNS_R_NCACHENXDOMAIN:
4694 	case DNS_R_NXRRSET:
4695 	case DNS_R_NCACHENXRRSET:
4696 	case ISC_R_NOTFOUND:
4697 		return (ISC_R_SUCCESS);
4698 	case DNS_R_DELEGATION:
4699 	case DNS_R_DUPLICATE:
4700 	case DNS_R_DROP:
4701 		return (result);
4702 	case DNS_R_CNAME:
4703 	case DNS_R_DNAME:
4704 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name, rpz_type,
4705 			     " NS address rewrite rrset", result);
4706 		return (ISC_R_SUCCESS);
4707 	default:
4708 		if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) {
4709 			client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR;
4710 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
4711 				     rpz_type, " NS address rewrite rrset",
4712 				     result);
4713 		}
4714 		return (DNS_R_SERVFAIL);
4715 	}
4716 
4717 	/*
4718 	 * Check all of the IP addresses in the rdataset.
4719 	 */
4720 	for (result = dns_rdataset_first(*ip_rdatasetp);
4721 	     result == ISC_R_SUCCESS;
4722 	     result = dns_rdataset_next(*ip_rdatasetp)) {
4723 
4724 		dns_rdata_t rdata = DNS_RDATA_INIT;
4725 		dns_rdataset_current(*ip_rdatasetp, &rdata);
4726 		switch (rdata.type) {
4727 		case dns_rdatatype_a:
4728 			INSIST(rdata.length == 4);
4729 			memmove(&ina.s_addr, rdata.data, 4);
4730 			isc_netaddr_fromin(&netaddr, &ina);
4731 			break;
4732 		case dns_rdatatype_aaaa:
4733 			INSIST(rdata.length == 16);
4734 			memmove(in6a.s6_addr, rdata.data, 16);
4735 			isc_netaddr_fromin6(&netaddr, &in6a);
4736 			break;
4737 		default:
4738 			continue;
4739 		}
4740 
4741 		result = rpz_rewrite_ip(client, &netaddr, qtype, rpz_type,
4742 					zbits, p_rdatasetp);
4743 		if (result != ISC_R_SUCCESS)
4744 			return (result);
4745 	}
4746 
4747 	return (ISC_R_SUCCESS);
4748 }
4749 
4750 /*
4751  * Look for IP addresses in A and AAAA rdatasets
4752  * that trigger all eligible IP or NSIP policy rules.
4753  */
4754 static isc_result_t
4755 rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name,
4756 		      dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
4757 		      dns_rdataset_t **ip_rdatasetp, isc_boolean_t resuming)
4758 {
4759 	dns_rpz_st_t *st;
4760 	dns_dbversion_t *ip_version;
4761 	dns_db_t *ip_db;
4762 	dns_rdataset_t *p_rdataset;
4763 	isc_result_t result;
4764 
4765 	CTRACE("rpz_rewrite_ip_rrsets");
4766 
4767 	st = client->query.rpz_st;
4768 	ip_version = NULL;
4769 	ip_db = NULL;
4770 	p_rdataset = NULL;
4771 	if ((st->state & DNS_RPZ_DONE_IPv4) == 0 &&
4772 	    (qtype == dns_rdatatype_a ||
4773 	     qtype == dns_rdatatype_any ||
4774 	     rpz_type == DNS_RPZ_TYPE_NSIP)) {
4775 		/*
4776 		 * Rewrite based on an IPv4 address that will appear
4777 		 * in the ANSWER section or if we are checking IP addresses.
4778 		 */
4779 		result = rpz_rewrite_ip_rrset(client, name, qtype,
4780 					      rpz_type, dns_rdatatype_a,
4781 					      &ip_db, ip_version, ip_rdatasetp,
4782 					      &p_rdataset, resuming);
4783 		if (result == ISC_R_SUCCESS)
4784 			st->state |= DNS_RPZ_DONE_IPv4;
4785 	} else {
4786 		result = ISC_R_SUCCESS;
4787 	}
4788 	if (result == ISC_R_SUCCESS &&
4789 	    (qtype == dns_rdatatype_aaaa ||
4790 	     qtype == dns_rdatatype_any ||
4791 	     rpz_type == DNS_RPZ_TYPE_NSIP)) {
4792 		/*
4793 		 * Rewrite based on IPv6 addresses that will appear
4794 		 * in the ANSWER section or if we are checking IP addresses.
4795 		 */
4796 		result = rpz_rewrite_ip_rrset(client, name,  qtype,
4797 					      rpz_type, dns_rdatatype_aaaa,
4798 					      &ip_db, ip_version, ip_rdatasetp,
4799 					      &p_rdataset, resuming);
4800 	}
4801 	if (ip_db != NULL)
4802 		dns_db_detach(&ip_db);
4803 	query_putrdataset(client, &p_rdataset);
4804 	return (result);
4805 }
4806 
4807 /*
4808  * Try to rewrite a request for a qtype rdataset based on the trigger name
4809  * trig_name and rpz_type (DNS_RPZ_TYPE_QNAME or DNS_RPZ_TYPE_NSDNAME).
4810  * Record the results including the replacement rdataset if any
4811  * in client->query.rpz_st.
4812  * *rdatasetp is a scratch rdataset.
4813  */
4814 static isc_result_t
4815 rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name,
4816 		 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
4817 		 dns_rpz_zbits_t allowed_zbits, dns_rdataset_t **rdatasetp)
4818 {
4819 	dns_rpz_zones_t *rpzs;
4820 	dns_rpz_zone_t *rpz;
4821 	dns_rpz_st_t *st;
4822 	dns_fixedname_t p_namef;
4823 	dns_name_t *p_name;
4824 	dns_rpz_zbits_t zbits;
4825 	dns_rpz_num_t rpz_num;
4826 	dns_zone_t *p_zone;
4827 	dns_db_t *p_db;
4828 	dns_dbversion_t *p_version;
4829 	dns_dbnode_t *p_node;
4830 	dns_rpz_policy_t policy;
4831 	isc_result_t result;
4832 
4833 	CTRACE("rpz_rewrite_name");
4834 
4835 	zbits = rpz_get_zbits(client, qtype, rpz_type);
4836 	zbits &= allowed_zbits;
4837 	if (zbits == 0)
4838 		return (ISC_R_SUCCESS);
4839 
4840 	rpzs = client->view->rpzs;
4841 
4842 	/*
4843 	 * If there is only one eligible policy zone, just check it.
4844 	 * If more than one, then use the summary database to find
4845 	 * the bit mask of policy zones with policies for this trigger name.
4846 	 *	x&(~x+1) is the least significant bit set in x
4847 	 */
4848 	if (zbits != (zbits & (~zbits + 1))) {
4849 		zbits = dns_rpz_find_name(rpzs, rpz_type, zbits, trig_name);
4850 		if (zbits == 0)
4851 			return (ISC_R_SUCCESS);
4852 	}
4853 
4854 	dns_fixedname_init(&p_namef);
4855 	p_name = dns_fixedname_name(&p_namef);
4856 
4857 	p_zone = NULL;
4858 	p_db = NULL;
4859 	p_node = NULL;
4860 
4861 	st = client->query.rpz_st;
4862 
4863 	/*
4864 	 * Check the trigger name in every policy zone that the summary data
4865 	 * says has a hit for the trigger name.
4866 	 * Most of the time there are no eligible zones and the summary data
4867 	 * keeps us from getting this far.
4868 	 * We check the most eligible zone first and so usually check only
4869 	 * one policy zone.
4870 	 */
4871 	for (rpz_num = 0; zbits != 0; ++rpz_num, zbits >>= 1) {
4872 		if ((zbits & 1) == 0)
4873 			continue;
4874 
4875 		/*
4876 		 * Do not check policy zones that cannot replace a previously
4877 		 * found policy.
4878 		 */
4879 		rpz = rpzs->zones[rpz_num];
4880 		if (st->m.policy != DNS_RPZ_POLICY_MISS) {
4881 			if (st->m.rpz->num < rpz->num)
4882 				break;
4883 			if (st->m.rpz->num == rpz->num &&
4884 			    st->m.type < rpz_type)
4885 				break;
4886 		}
4887 
4888 		/*
4889 		 * Get the next policy zone's record for this trigger name.
4890 		 */
4891 		result = rpz_get_p_name(client, p_name, rpz, rpz_type,
4892 					trig_name);
4893 		if (result != ISC_R_SUCCESS)
4894 			continue;
4895 		result = rpz_find_p(client, trig_name, qtype, p_name,
4896 				    rpz, rpz_type,
4897 				    &p_zone, &p_db, &p_version, &p_node,
4898 				    rdatasetp, &policy);
4899 		switch (result) {
4900 		case DNS_R_NXDOMAIN:
4901 			/*
4902 			 * Continue after a missing policy record
4903 			 * contrary to the summary data.  The summary
4904 			 * data can out of date during races with and among
4905 			 * policy zone updates.
4906 			 */
4907 			CTRACE("rpz_rewrite_name: mismatched summary data; "
4908 			       "continuing");
4909 			continue;
4910 		case DNS_R_SERVFAIL:
4911 			rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
4912 			st->m.policy = DNS_RPZ_POLICY_ERROR;
4913 			return (DNS_R_SERVFAIL);
4914 		default:
4915 			/*
4916 			 * With more than one applicable policy, prefer
4917 			 * the earliest configured policy,
4918 			 * client-IP over QNAME over IP over NSDNAME over NSIP,
4919 			 * and the smallest name.
4920 			 * We known st->m.rpz->num >= rpz->num  and either
4921 			 * st->m.rpz->num > rpz->num or st->m.type >= rpz_type
4922 			 */
4923 			if (st->m.policy != DNS_RPZ_POLICY_MISS &&
4924 			    rpz->num == st->m.rpz->num &&
4925 			    (st->m.type < rpz_type ||
4926 			     (st->m.type == rpz_type &&
4927 			      0 >= dns_name_compare(p_name, st->p_name))))
4928 				continue;
4929 #if 0
4930 			/*
4931 			 * This code would block a customer reported information
4932 			 * leak of rpz rules by rewriting requests in the
4933 			 * rpz-ip, rpz-nsip, rpz-nsdname,and rpz-passthru TLDs.
4934 			 * Without this code, a bad guy could request
4935 			 * 24.0.3.2.10.rpz-ip. to find the policy rule for
4936 			 * 10.2.3.0/14.  It is an insignificant leak and this
4937 			 * code is not worth its cost, because the bad guy
4938 			 * could publish "evil.com A 10.2.3.4" and request
4939 			 * evil.com to get the same information.
4940 			 * Keep code with "#if 0" in case customer demand
4941 			 * is irresistible.
4942 			 *
4943 			 * We have the less frequent case of a triggered
4944 			 * policy.  Check that we have not trigger on one
4945 			 * of the pretend RPZ TLDs.
4946 			 * This test would make it impossible to rewrite
4947 			 * names in TLDs that start with "rpz-" should
4948 			 * ICANN ever allow such TLDs.
4949 			 */
4950 			unsigned int labels;
4951 			labels = dns_name_countlabels(trig_name);
4952 			if (labels >= 2) {
4953 				dns_label_t label;
4954 
4955 				dns_name_getlabel(trig_name, labels-2, &label);
4956 				if (label.length >= sizeof(DNS_RPZ_PREFIX)-1 &&
4957 				    strncasecmp((const char *)label.base+1,
4958 						DNS_RPZ_PREFIX,
4959 						sizeof(DNS_RPZ_PREFIX)-1) == 0)
4960 					continue;
4961 			}
4962 #endif
4963 			if (rpz->policy != DNS_RPZ_POLICY_DISABLED) {
4964 				CTRACE("rpz_rewrite_name: rpz_save_p");
4965 				rpz_save_p(st, rpz, rpz_type,
4966 					   policy, p_name, 0, result,
4967 					   &p_zone, &p_db, &p_node,
4968 					   rdatasetp, p_version);
4969 				/*
4970 				 * After a hit, higher numbered policy zones
4971 				 * are irrelevant
4972 				 */
4973 				rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
4974 				return (ISC_R_SUCCESS);
4975 			}
4976 			/*
4977 			 * Log DNS_RPZ_POLICY_DISABLED zones
4978 			 * and try the next eligible policy zone.
4979 			 */
4980 			rpz_log_rewrite(client, ISC_TRUE, policy, rpz_type,
4981 					p_zone, p_name);
4982 			break;
4983 		}
4984 	}
4985 
4986 	rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
4987 	return (ISC_R_SUCCESS);
4988 }
4989 
4990 static void
4991 rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname,
4992 		    isc_result_t result, int level, const char *str)
4993 {
4994 	dns_rpz_st_t *st;
4995 
4996 	CTRACE("rpz_rewrite_ns_skip");
4997 
4998 	st = client->query.rpz_st;
4999 
5000 	if (str != NULL)
5001 		rpz_log_fail(client, level, nsname, DNS_RPZ_TYPE_NSIP,
5002 			     str, result);
5003 	if (st->r.ns_rdataset != NULL &&
5004 	    dns_rdataset_isassociated(st->r.ns_rdataset))
5005 		dns_rdataset_disassociate(st->r.ns_rdataset);
5006 
5007 	st->r.label--;
5008 }
5009 
5010 /*
5011  * Look for response policy zone QNAME, NSIP, and NSDNAME rewriting.
5012  */
5013 static isc_result_t
5014 rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype,
5015 	    isc_result_t qresult, isc_boolean_t resuming,
5016 	    dns_rdataset_t *ordataset, dns_rdataset_t *osigset)
5017 {
5018 	dns_rpz_zones_t *rpzs;
5019 	dns_rpz_st_t *st;
5020 	dns_rdataset_t *rdataset;
5021 	dns_fixedname_t nsnamef;
5022 	dns_name_t *nsname;
5023 	int qresult_type;
5024 	dns_rpz_zbits_t zbits;
5025 	isc_result_t result = ISC_R_SUCCESS;
5026 	dns_rpz_have_t have;
5027 	dns_rpz_popt_t popt;
5028 	int rpz_ver;
5029 
5030 	CTRACE("rpz_rewrite");
5031 
5032 	rpzs = client->view->rpzs;
5033 	st = client->query.rpz_st;
5034 
5035 	if (rpzs == NULL ||
5036 	    (st != NULL && (st->state & DNS_RPZ_REWRITTEN) != 0))
5037 		return (DNS_R_DISALLOWED);
5038 
5039 	RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
5040 	if (rpzs->p.num_zones == 0 ||
5041 	    (!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) ||
5042 	    !rpz_ck_dnssec(client, qresult, ordataset, osigset))
5043 	{
5044 		RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
5045 		return (DNS_R_DISALLOWED);
5046 	}
5047 	have = rpzs->have;
5048 	popt = rpzs->p;
5049 	rpz_ver = rpzs->rpz_ver;
5050 	RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
5051 
5052 	if (st == NULL) {
5053 		st = isc_mem_get(client->mctx, sizeof(*st));
5054 		if (st == NULL)
5055 			return (ISC_R_NOMEMORY);
5056 		st->state = 0;
5057 	}
5058 	if (st->state == 0) {
5059 		st->state |= DNS_RPZ_ACTIVE;
5060 		memset(&st->m, 0, sizeof(st->m));
5061 		st->m.type = DNS_RPZ_TYPE_BAD;
5062 		st->m.policy = DNS_RPZ_POLICY_MISS;
5063 		st->m.ttl = ~0;
5064 		memset(&st->r, 0, sizeof(st->r));
5065 		memset(&st->q, 0, sizeof(st->q));
5066 		dns_fixedname_init(&st->_p_namef);
5067 		dns_fixedname_init(&st->_r_namef);
5068 		dns_fixedname_init(&st->_fnamef);
5069 		st->p_name = dns_fixedname_name(&st->_p_namef);
5070 		st->r_name = dns_fixedname_name(&st->_r_namef);
5071 		st->fname = dns_fixedname_name(&st->_fnamef);
5072 		st->have = have;
5073 		st->popt = popt;
5074 		st->rpz_ver = rpz_ver;
5075 		client->query.rpz_st = st;
5076 	}
5077 
5078 	/*
5079 	 * There is nothing to rewrite if the main query failed.
5080 	 */
5081 	switch (qresult) {
5082 	case ISC_R_SUCCESS:
5083 	case DNS_R_GLUE:
5084 	case DNS_R_ZONECUT:
5085 		qresult_type = 0;
5086 		break;
5087 	case DNS_R_EMPTYNAME:
5088 	case DNS_R_NXRRSET:
5089 	case DNS_R_NXDOMAIN:
5090 	case DNS_R_EMPTYWILD:
5091 	case DNS_R_NCACHENXDOMAIN:
5092 	case DNS_R_NCACHENXRRSET:
5093 	case DNS_R_CNAME:
5094 	case DNS_R_DNAME:
5095 		qresult_type = 1;
5096 		break;
5097 	case DNS_R_DELEGATION:
5098 	case ISC_R_NOTFOUND:
5099 		/*
5100 		 * If recursion is on, do only tentative rewriting.
5101 		 * If recursion is off, this the normal and only time we
5102 		 * can rewrite.
5103 		 */
5104 		if (RECURSIONOK(client))
5105 			qresult_type = 2;
5106 		else
5107 			qresult_type = 1;
5108 		break;
5109 	case ISC_R_FAILURE:
5110 	case ISC_R_TIMEDOUT:
5111 	case DNS_R_BROKENCHAIN:
5112 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, client->query.qname,
5113 			     DNS_RPZ_TYPE_QNAME,
5114 			     " stop on qresult in rpz_rewrite()", qresult);
5115 		return (ISC_R_SUCCESS);
5116 	default:
5117 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, client->query.qname,
5118 			     DNS_RPZ_TYPE_QNAME,
5119 			     " stop on unrecognized qresult in rpz_rewrite()",
5120 			     qresult);
5121 		return (ISC_R_SUCCESS);
5122 	}
5123 
5124 	rdataset = NULL;
5125 
5126 	if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) !=
5127 	    (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) {
5128 		isc_netaddr_t netaddr;
5129 		dns_rpz_zbits_t allowed;
5130 
5131 		if (qresult_type == 2) {
5132 			/*
5133 			 * This request needs recursion that has not been done.
5134 			 * Get bits for the policy zones that do not need
5135 			 * to wait for the results of recursion.
5136 			 */
5137 			allowed = st->have.qname_skip_recurse;
5138 			if (allowed == 0)
5139 				return (ISC_R_SUCCESS);
5140 		} else {
5141 			allowed = DNS_RPZ_ALL_ZBITS;
5142 		}
5143 
5144 		/*
5145 		 * Check once for triggers for the client IP address.
5146 		 */
5147 		if ((st->state & DNS_RPZ_DONE_CLIENT_IP) == 0) {
5148 			zbits = rpz_get_zbits(client, dns_rdatatype_none,
5149 					      DNS_RPZ_TYPE_CLIENT_IP);
5150 			zbits &= allowed;
5151 			if (zbits != 0) {
5152 				isc_netaddr_fromsockaddr(&netaddr,
5153 							&client->peeraddr);
5154 				result = rpz_rewrite_ip(client, &netaddr, qtype,
5155 							DNS_RPZ_TYPE_CLIENT_IP,
5156 							zbits, &rdataset);
5157 				if (result != ISC_R_SUCCESS)
5158 					goto cleanup;
5159 			}
5160 		}
5161 
5162 		/*
5163 		 * Check triggers for the query name if this is the first time
5164 		 * for the current qname.
5165 		 * There is a first time for each name in a CNAME chain
5166 		 */
5167 		if ((st->state & DNS_RPZ_DONE_QNAME) == 0) {
5168 			result = rpz_rewrite_name(client, client->query.qname,
5169 						  qtype, DNS_RPZ_TYPE_QNAME,
5170 						  allowed, &rdataset);
5171 			if (result != ISC_R_SUCCESS)
5172 				goto cleanup;
5173 
5174 			/*
5175 			 * Check IPv4 addresses in A RRs next.
5176 			 * Reset to the start of the NS names.
5177 			 */
5178 			st->r.label = dns_name_countlabels(client->query.qname);
5179 			st->state &= ~(DNS_RPZ_DONE_QNAME_IP |
5180 				       DNS_RPZ_DONE_IPv4);
5181 
5182 		}
5183 
5184 		/*
5185 		 * Quit if this was an attempt to find a qname or
5186 		 * client-IP trigger before recursion.
5187 		 * We will be back if no pre-recursion triggers hit.
5188 		 * For example, consider 2 policy zones, both with qname and
5189 		 * IP address triggers.  If the qname misses the 1st zone,
5190 		 * then we cannot know whether a hit for the qname in the
5191 		 * 2nd zone matters until after recursing to get the A RRs and
5192 		 * testing them in the first zone.
5193 		 * Do not bother saving the work from this attempt,
5194 		 * because recusion is so slow.
5195 		 */
5196 		if (qresult_type == 2)
5197 			goto cleanup;
5198 
5199 		/*
5200 		 * DNS_RPZ_DONE_QNAME but not DNS_RPZ_DONE_CLIENT_IP
5201 		 * is reset at the end of dealing with each CNAME.
5202 		 */
5203 		st->state |= (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME);
5204 	}
5205 
5206 	/*
5207 	 * Check known IP addresses for the query name if the database
5208 	 * lookup resulted in some addresses (qresult_type == 0)
5209 	 * and if we have not already checked them.
5210 	 * Any recursion required for the query has already happened.
5211 	 * Do not check addresses that will not be in the ANSWER section.
5212 	 */
5213 	if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 && qresult_type == 0 &&
5214 	    rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0) {
5215 		result = rpz_rewrite_ip_rrsets(client,
5216 					       client->query.qname, qtype,
5217 					       DNS_RPZ_TYPE_IP,
5218 					       &rdataset, resuming);
5219 		if (result != ISC_R_SUCCESS)
5220 			goto cleanup;
5221 		/*
5222 		 * We are finished checking the IP addresses for the qname.
5223 		 * Start with IPv4 if we will check NS IP addesses.
5224 		 */
5225 		st->state |= DNS_RPZ_DONE_QNAME_IP;
5226 		st->state &= ~DNS_RPZ_DONE_IPv4;
5227 	}
5228 
5229 	/*
5230 	 * Stop looking for rules if there are none of the other kinds
5231 	 * that could override what we already have.
5232 	 */
5233 	if (rpz_get_zbits(client, dns_rdatatype_any,
5234 			  DNS_RPZ_TYPE_NSDNAME) == 0 &&
5235 	    rpz_get_zbits(client, dns_rdatatype_any,
5236 			  DNS_RPZ_TYPE_NSIP) == 0) {
5237 		result = ISC_R_SUCCESS;
5238 		goto cleanup;
5239 	}
5240 
5241 	dns_fixedname_init(&nsnamef);
5242 	dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef));
5243 	while (st->r.label > st->popt.min_ns_labels) {
5244 		/*
5245 		 * Get NS rrset for each domain in the current qname.
5246 		 */
5247 		if (st->r.label == dns_name_countlabels(client->query.qname)) {
5248 			nsname = client->query.qname;
5249 		} else {
5250 			nsname = dns_fixedname_name(&nsnamef);
5251 			dns_name_split(client->query.qname, st->r.label,
5252 				       NULL, nsname);
5253 		}
5254 		if (st->r.ns_rdataset == NULL ||
5255 		    !dns_rdataset_isassociated(st->r.ns_rdataset))
5256 		{
5257 			dns_db_t *db = NULL;
5258 			result = rpz_rrset_find(client, nsname,
5259 						dns_rdatatype_ns,
5260 						DNS_RPZ_TYPE_NSDNAME,
5261 						&db, NULL, &st->r.ns_rdataset,
5262 						resuming);
5263 			if (db != NULL)
5264 				dns_db_detach(&db);
5265 			if (st->m.policy == DNS_RPZ_POLICY_ERROR)
5266 				goto cleanup;
5267 			switch (result) {
5268 			case ISC_R_SUCCESS:
5269 				result = dns_rdataset_first(st->r.ns_rdataset);
5270 				if (result != ISC_R_SUCCESS)
5271 					goto cleanup;
5272 				st->state &= ~(DNS_RPZ_DONE_NSDNAME |
5273 					       DNS_RPZ_DONE_IPv4);
5274 				break;
5275 			case DNS_R_DELEGATION:
5276 			case DNS_R_DUPLICATE:
5277 			case DNS_R_DROP:
5278 				goto cleanup;
5279 			case DNS_R_EMPTYNAME:
5280 			case DNS_R_NXRRSET:
5281 			case DNS_R_EMPTYWILD:
5282 			case DNS_R_NXDOMAIN:
5283 			case DNS_R_NCACHENXDOMAIN:
5284 			case DNS_R_NCACHENXRRSET:
5285 			case ISC_R_NOTFOUND:
5286 			case DNS_R_CNAME:
5287 			case DNS_R_DNAME:
5288 				rpz_rewrite_ns_skip(client, nsname, result,
5289 						    0, NULL);
5290 				continue;
5291 			case ISC_R_TIMEDOUT:
5292 			case DNS_R_BROKENCHAIN:
5293 			case ISC_R_FAILURE:
5294 				rpz_rewrite_ns_skip(client, nsname, result,
5295 						DNS_RPZ_DEBUG_LEVEL3,
5296 						" NS rpz_rrset_find() ");
5297 				continue;
5298 			default:
5299 				rpz_rewrite_ns_skip(client, nsname, result,
5300 						DNS_RPZ_INFO_LEVEL,
5301 						" unrecognized NS"
5302 						" rpz_rrset_find() ");
5303 				continue;
5304 			}
5305 		}
5306 		/*
5307 		 * Check all NS names.
5308 		 */
5309 		do {
5310 			dns_rdata_ns_t ns;
5311 			dns_rdata_t nsrdata = DNS_RDATA_INIT;
5312 
5313 			dns_rdataset_current(st->r.ns_rdataset, &nsrdata);
5314 			result = dns_rdata_tostruct(&nsrdata, &ns, NULL);
5315 			dns_rdata_reset(&nsrdata);
5316 			if (result != ISC_R_SUCCESS) {
5317 				rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
5318 					     nsname, DNS_RPZ_TYPE_NSIP,
5319 					     " rdata_tostruct()", result);
5320 				st->m.policy = DNS_RPZ_POLICY_ERROR;
5321 				goto cleanup;
5322 			}
5323 			/*
5324 			 * Do nothing about "NS ."
5325 			 */
5326 			if (dns_name_equal(&ns.name, dns_rootname)) {
5327 				dns_rdata_freestruct(&ns);
5328 				result = dns_rdataset_next(st->r.ns_rdataset);
5329 				continue;
5330 			}
5331 			/*
5332 			 * Check this NS name if we did not handle it
5333 			 * during a previous recursion.
5334 			 */
5335 			if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0) {
5336 				result = rpz_rewrite_name(client, &ns.name,
5337 							qtype,
5338 							DNS_RPZ_TYPE_NSDNAME,
5339 							DNS_RPZ_ALL_ZBITS,
5340 							&rdataset);
5341 				if (result != ISC_R_SUCCESS) {
5342 					dns_rdata_freestruct(&ns);
5343 					goto cleanup;
5344 				}
5345 				st->state |= DNS_RPZ_DONE_NSDNAME;
5346 			}
5347 			/*
5348 			 * Check all IP addresses for this NS name.
5349 			 */
5350 			result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype,
5351 						       DNS_RPZ_TYPE_NSIP,
5352 						       &rdataset, resuming);
5353 			dns_rdata_freestruct(&ns);
5354 			if (result != ISC_R_SUCCESS)
5355 				goto cleanup;
5356 			st->state &= ~(DNS_RPZ_DONE_NSDNAME |
5357 				       DNS_RPZ_DONE_IPv4);
5358 			result = dns_rdataset_next(st->r.ns_rdataset);
5359 		} while (result == ISC_R_SUCCESS);
5360 		dns_rdataset_disassociate(st->r.ns_rdataset);
5361 		st->r.label--;
5362 
5363 		if (rpz_get_zbits(client, dns_rdatatype_any,
5364 				  DNS_RPZ_TYPE_NSDNAME) == 0 &&
5365 		    rpz_get_zbits(client, dns_rdatatype_any,
5366 				  DNS_RPZ_TYPE_NSIP) == 0)
5367 			break;
5368 	}
5369 
5370 	/*
5371 	 * Use the best hit, if any.
5372 	 */
5373 	result = ISC_R_SUCCESS;
5374 
5375 cleanup:
5376 	if (st->m.policy != DNS_RPZ_POLICY_MISS &&
5377 	    st->m.policy != DNS_RPZ_POLICY_ERROR &&
5378 	    st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN)
5379 		st->m.policy = st->m.rpz->policy;
5380 	if (st->m.policy == DNS_RPZ_POLICY_MISS ||
5381 	    st->m.policy == DNS_RPZ_POLICY_PASSTHRU ||
5382 	    st->m.policy == DNS_RPZ_POLICY_ERROR) {
5383 		if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU &&
5384 		    result != DNS_R_DELEGATION)
5385 			rpz_log_rewrite(client, ISC_FALSE, st->m.policy,
5386 					st->m.type, st->m.zone, st->p_name);
5387 		rpz_match_clear(st);
5388 	}
5389 	if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
5390 		st->m.type = DNS_RPZ_TYPE_BAD;
5391 		result = DNS_R_SERVFAIL;
5392 	}
5393 	query_putrdataset(client, &rdataset);
5394 	if ((st->state & DNS_RPZ_RECURSING) == 0)
5395 		rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset);
5396 
5397 	return (result);
5398 }
5399 
5400 /*
5401  * See if response policy zone rewriting is allowed by a lack of interest
5402  * by the client in DNSSEC or a lack of signatures.
5403  */
5404 static isc_boolean_t
5405 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
5406 	      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
5407 {
5408 	dns_fixedname_t fixed;
5409 	dns_name_t *found;
5410 	dns_rdataset_t trdataset;
5411 	dns_rdatatype_t type;
5412 	isc_result_t result;
5413 
5414 	CTRACE("rpz_ck_dnssec");
5415 
5416 	if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client))
5417 		return (ISC_TRUE);
5418 
5419 	/*
5420 	 * We do not know if there are signatures if we have not recursed
5421 	 * for them.
5422 	 */
5423 	if (qresult == DNS_R_DELEGATION || qresult == ISC_R_NOTFOUND)
5424 		return (ISC_FALSE);
5425 
5426 	if (sigrdataset == NULL)
5427 		return (ISC_TRUE);
5428 	if (dns_rdataset_isassociated(sigrdataset))
5429 		return (ISC_FALSE);
5430 
5431 	/*
5432 	 * We are happy to rewrite nothing.
5433 	 */
5434 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset))
5435 		return (ISC_TRUE);
5436 	/*
5437 	 * Do not rewrite if there is any sign of signatures.
5438 	 */
5439 	if (rdataset->type == dns_rdatatype_nsec ||
5440 	    rdataset->type == dns_rdatatype_nsec3 ||
5441 	    rdataset->type == dns_rdatatype_rrsig)
5442 		return (ISC_FALSE);
5443 
5444 	/*
5445 	 * Look for a signature in a negative cache rdataset.
5446 	 */
5447 	if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0)
5448 		return (ISC_TRUE);
5449 	dns_fixedname_init(&fixed);
5450 	found = dns_fixedname_name(&fixed);
5451 	dns_rdataset_init(&trdataset);
5452 	for (result = dns_rdataset_first(rdataset);
5453 	     result == ISC_R_SUCCESS;
5454 	     result = dns_rdataset_next(rdataset)) {
5455 		dns_ncache_current(rdataset, found, &trdataset);
5456 		type = trdataset.type;
5457 		dns_rdataset_disassociate(&trdataset);
5458 		if (type == dns_rdatatype_nsec ||
5459 		    type == dns_rdatatype_nsec3 ||
5460 		    type == dns_rdatatype_rrsig)
5461 			return (ISC_FALSE);
5462 	}
5463 	return (ISC_TRUE);
5464 }
5465 
5466 /*
5467  * Add a CNAME to the query response, including translating foo.evil.com and
5468  *	*.evil.com CNAME *.example.com
5469  * to
5470  *	foo.evil.com CNAME foo.evil.com.example.com
5471  */
5472 static isc_result_t
5473 rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st,
5474 	      dns_name_t *cname, dns_name_t *fname, isc_buffer_t *dbuf)
5475 {
5476 	dns_fixedname_t prefix, suffix;
5477 	unsigned int labels;
5478 	isc_result_t result;
5479 
5480 	CTRACE("rpz_add_cname");
5481 
5482 	labels = dns_name_countlabels(cname);
5483 	if (labels > 2 && dns_name_iswildcard(cname)) {
5484 		dns_fixedname_init(&prefix);
5485 		dns_name_split(client->query.qname, 1,
5486 			       dns_fixedname_name(&prefix), NULL);
5487 		dns_fixedname_init(&suffix);
5488 		dns_name_split(cname, labels-1,
5489 			       NULL, dns_fixedname_name(&suffix));
5490 		result = dns_name_concatenate(dns_fixedname_name(&prefix),
5491 					      dns_fixedname_name(&suffix),
5492 					      fname, NULL);
5493 		if (result == DNS_R_NAMETOOLONG)
5494 			client->message->rcode = dns_rcode_yxdomain;
5495 	} else {
5496 		result = dns_name_copy(cname, fname, NULL);
5497 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
5498 	}
5499 	if (result != ISC_R_SUCCESS)
5500 		return (result);
5501 	query_keepname(client, fname, dbuf);
5502 	result = query_add_cname(client, client->query.qname,
5503 				 fname, dns_trust_authanswer, st->m.ttl);
5504 	if (result != ISC_R_SUCCESS)
5505 		return (result);
5506 	rpz_log_rewrite(client, ISC_FALSE, st->m.policy,
5507 			st->m.type, st->m.zone, st->p_name);
5508 	ns_client_qnamereplace(client, fname);
5509 	/*
5510 	 * Turn off DNSSEC because the results of a
5511 	 * response policy zone cannot verify.
5512 	 */
5513 	client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
5514 				NS_CLIENTATTR_WANTAD);
5515 	return (ISC_R_SUCCESS);
5516 }
5517 
5518 #define MAX_RESTARTS 16
5519 
5520 #define QUERY_ERROR(r) \
5521 do { \
5522 	eresult = r; \
5523 	want_restart = ISC_FALSE; \
5524 	line = __LINE__; \
5525 } while (/*CONSTCOND*/0)
5526 
5527 #define RECURSE_ERROR(r) \
5528 do { \
5529 	if ((r) == DNS_R_DUPLICATE || (r) == DNS_R_DROP) \
5530 		QUERY_ERROR(r); \
5531 	else \
5532 		QUERY_ERROR(DNS_R_SERVFAIL); \
5533 } while (/*CONSTCOND*/0)
5534 
5535 /*
5536  * Extract a network address from the RDATA of an A or AAAA
5537  * record.
5538  *
5539  * Returns:
5540  *	ISC_R_SUCCESS
5541  *	ISC_R_NOTIMPLEMENTED	The rdata is not a known address type.
5542  */
5543 static isc_result_t
5544 rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) {
5545 	struct in_addr ina;
5546 	struct in6_addr in6a;
5547 
5548 	switch (rdata->type) {
5549 	case dns_rdatatype_a:
5550 		INSIST(rdata->length == 4);
5551 		memmove(&ina.s_addr, rdata->data, 4);
5552 		isc_netaddr_fromin(netaddr, &ina);
5553 		return (ISC_R_SUCCESS);
5554 	case dns_rdatatype_aaaa:
5555 		INSIST(rdata->length == 16);
5556 		memmove(in6a.s6_addr, rdata->data, 16);
5557 		isc_netaddr_fromin6(netaddr, &in6a);
5558 		return (ISC_R_SUCCESS);
5559 	default:
5560 		return (ISC_R_NOTIMPLEMENTED);
5561 	}
5562 }
5563 
5564 /*
5565  * Find the sort order of 'rdata' in the topology-like
5566  * ACL forming the second element in a 2-element top-level
5567  * sortlist statement.
5568  */
5569 static int
5570 query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) {
5571 	isc_netaddr_t netaddr;
5572 
5573 	if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS)
5574 		return (INT_MAX);
5575 	return (ns_sortlist_addrorder2(&netaddr, arg));
5576 }
5577 
5578 /*
5579  * Find the sort order of 'rdata' in the matching element
5580  * of a 1-element top-level sortlist statement.
5581  */
5582 static int
5583 query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) {
5584 	isc_netaddr_t netaddr;
5585 
5586 	if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS)
5587 		return (INT_MAX);
5588 	return (ns_sortlist_addrorder1(&netaddr, arg));
5589 }
5590 
5591 /*
5592  * Find the sortlist statement that applies to 'client' and set up
5593  * the sortlist info in in client->message appropriately.
5594  */
5595 static void
5596 setup_query_sortlist(ns_client_t *client) {
5597 	isc_netaddr_t netaddr;
5598 	dns_rdatasetorderfunc_t order = NULL;
5599 	const void *order_arg = NULL;
5600 
5601 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
5602 	switch (ns_sortlist_setup(client->view->sortlist,
5603 			       &netaddr, &order_arg)) {
5604 	case NS_SORTLISTTYPE_1ELEMENT:
5605 		order = query_sortlist_order_1element;
5606 		break;
5607 	case NS_SORTLISTTYPE_2ELEMENT:
5608 		order = query_sortlist_order_2element;
5609 		break;
5610 	case NS_SORTLISTTYPE_NONE:
5611 		order = NULL;
5612 		break;
5613 	default:
5614 		INSIST(0);
5615 		break;
5616 	}
5617 	dns_message_setsortorder(client->message, order, order_arg);
5618 }
5619 
5620 static void
5621 query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) {
5622 	isc_buffer_t *dbuf, b;
5623 	dns_name_t *fname;
5624 	dns_rdataset_t *neg, *negsig;
5625 	isc_result_t result = ISC_R_NOMEMORY;
5626 
5627 	CTRACE("query_addnoqnameproof");
5628 
5629 	fname = NULL;
5630 	neg = NULL;
5631 	negsig = NULL;
5632 
5633 	dbuf = query_getnamebuf(client);
5634 	if (dbuf == NULL)
5635 		goto cleanup;
5636 	fname = query_newname(client, dbuf, &b);
5637 	neg = query_newrdataset(client);
5638 	negsig = query_newrdataset(client);
5639 	if (fname == NULL || neg == NULL || negsig == NULL)
5640 		goto cleanup;
5641 
5642 	result = dns_rdataset_getnoqname(rdataset, fname, neg, negsig);
5643 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
5644 
5645 	query_addrrset(client, &fname, &neg, &negsig, dbuf,
5646 		       DNS_SECTION_AUTHORITY);
5647 
5648 	if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) == 0)
5649 		goto cleanup;
5650 
5651 	if (fname == NULL) {
5652 		dbuf = query_getnamebuf(client);
5653 		if (dbuf == NULL)
5654 			goto cleanup;
5655 		fname = query_newname(client, dbuf, &b);
5656 	}
5657 	if (neg == NULL)
5658 		neg = query_newrdataset(client);
5659 	else if (dns_rdataset_isassociated(neg))
5660 		dns_rdataset_disassociate(neg);
5661 	if (negsig == NULL)
5662 		negsig = query_newrdataset(client);
5663 	else if (dns_rdataset_isassociated(negsig))
5664 		dns_rdataset_disassociate(negsig);
5665 	if (fname == NULL || neg == NULL || negsig == NULL)
5666 		goto cleanup;
5667 	result = dns_rdataset_getclosest(rdataset, fname, neg, negsig);
5668 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
5669 
5670 	query_addrrset(client, &fname, &neg, &negsig, dbuf,
5671 		       DNS_SECTION_AUTHORITY);
5672 
5673  cleanup:
5674 	if (neg != NULL)
5675 		query_putrdataset(client, &neg);
5676 	if (negsig != NULL)
5677 		query_putrdataset(client, &negsig);
5678 	if (fname != NULL)
5679 		query_releasename(client, &fname);
5680 }
5681 
5682 static inline void
5683 answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) {
5684 	dns_name_t *name;
5685 	dns_message_t *msg;
5686 	dns_section_t section = DNS_SECTION_ADDITIONAL;
5687 	dns_rdataset_t *rdataset = NULL;
5688 
5689 	msg = client->message;
5690 	for (name = ISC_LIST_HEAD(msg->sections[section]);
5691 	     name != NULL;
5692 	     name = ISC_LIST_NEXT(name, link))
5693 		if (dns_name_equal(name, client->query.qname)) {
5694 			for (rdataset = ISC_LIST_HEAD(name->list);
5695 			     rdataset != NULL;
5696 			     rdataset = ISC_LIST_NEXT(rdataset, link))
5697 				if (rdataset->type == qtype)
5698 					break;
5699 			break;
5700 		}
5701 	if (rdataset != NULL) {
5702 		ISC_LIST_UNLINK(msg->sections[section], name, link);
5703 		ISC_LIST_PREPEND(msg->sections[section], name, link);
5704 		ISC_LIST_UNLINK(name->list, rdataset, link);
5705 		ISC_LIST_PREPEND(name->list, rdataset, link);
5706 		rdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
5707 	}
5708 }
5709 
5710 #define NS_NAME_INIT(A,B) \
5711 	 { \
5712 		DNS_NAME_MAGIC, \
5713 		A, sizeof(A), sizeof(B), \
5714 		DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, \
5715 		B, NULL, { (void *)-1, (void *)-1}, \
5716 		{NULL, NULL} \
5717 	}
5718 
5719 static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 };
5720 static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 };
5721 static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 };
5722 
5723 static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA";
5724 
5725 static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA";
5726 static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA";
5727 static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA";
5728 static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA";
5729 static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA";
5730 static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA";
5731 static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA";
5732 static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA";
5733 static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA";
5734 static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA";
5735 static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA";
5736 static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA";
5737 static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA";
5738 static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA";
5739 static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA";
5740 static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA";
5741 
5742 static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA";
5743 
5744 static dns_name_t rfc1918names[] = {
5745 	NS_NAME_INIT(inaddr10, inaddr10_offsets),
5746 	NS_NAME_INIT(inaddr16172, inaddr172_offsets),
5747 	NS_NAME_INIT(inaddr17172, inaddr172_offsets),
5748 	NS_NAME_INIT(inaddr18172, inaddr172_offsets),
5749 	NS_NAME_INIT(inaddr19172, inaddr172_offsets),
5750 	NS_NAME_INIT(inaddr20172, inaddr172_offsets),
5751 	NS_NAME_INIT(inaddr21172, inaddr172_offsets),
5752 	NS_NAME_INIT(inaddr22172, inaddr172_offsets),
5753 	NS_NAME_INIT(inaddr23172, inaddr172_offsets),
5754 	NS_NAME_INIT(inaddr24172, inaddr172_offsets),
5755 	NS_NAME_INIT(inaddr25172, inaddr172_offsets),
5756 	NS_NAME_INIT(inaddr26172, inaddr172_offsets),
5757 	NS_NAME_INIT(inaddr27172, inaddr172_offsets),
5758 	NS_NAME_INIT(inaddr28172, inaddr172_offsets),
5759 	NS_NAME_INIT(inaddr29172, inaddr172_offsets),
5760 	NS_NAME_INIT(inaddr30172, inaddr172_offsets),
5761 	NS_NAME_INIT(inaddr31172, inaddr172_offsets),
5762 	NS_NAME_INIT(inaddr168192, inaddr192_offsets)
5763 };
5764 
5765 
5766 static unsigned char prisoner_data[] = "\010prisoner\004iana\003org";
5767 static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org";
5768 
5769 static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 };
5770 static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 };
5771 
5772 static dns_name_t prisoner = NS_NAME_INIT(prisoner_data, prisoner_offsets);
5773 static dns_name_t hostmaster = NS_NAME_INIT(hostmaster_data, hostmaster_offsets);
5774 
5775 static void
5776 warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) {
5777 	unsigned int i;
5778 	dns_rdata_t rdata = DNS_RDATA_INIT;
5779 	dns_rdata_soa_t soa;
5780 	dns_rdataset_t found;
5781 	isc_result_t result;
5782 
5783 	for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) {
5784 		if (dns_name_issubdomain(fname, &rfc1918names[i])) {
5785 			dns_rdataset_init(&found);
5786 			result = dns_ncache_getrdataset(rdataset,
5787 							&rfc1918names[i],
5788 							dns_rdatatype_soa,
5789 							&found);
5790 			if (result != ISC_R_SUCCESS)
5791 				return;
5792 
5793 			result = dns_rdataset_first(&found);
5794 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
5795 			dns_rdataset_current(&found, &rdata);
5796 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
5797 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
5798 			if (dns_name_equal(&soa.origin, &prisoner) &&
5799 			    dns_name_equal(&soa.contact, &hostmaster)) {
5800 				char buf[DNS_NAME_FORMATSIZE];
5801 				dns_name_format(fname, buf, sizeof(buf));
5802 				ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
5803 					      NS_LOGMODULE_QUERY,
5804 					      ISC_LOG_WARNING,
5805 					      "RFC 1918 response from "
5806 					      "Internet for %s", buf);
5807 			}
5808 			dns_rdataset_disassociate(&found);
5809 			return;
5810 		}
5811 	}
5812 }
5813 
5814 static void
5815 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
5816 		       dns_dbversion_t *version, ns_client_t *client,
5817 		       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
5818 		       dns_name_t *fname, isc_boolean_t exact,
5819 		       dns_name_t *found)
5820 {
5821 	unsigned char salt[256];
5822 	size_t salt_length;
5823 	isc_uint16_t iterations;
5824 	isc_result_t result;
5825 	unsigned int dboptions;
5826 	dns_fixedname_t fixed;
5827 	dns_hash_t hash;
5828 	dns_name_t name;
5829 	unsigned int skip = 0, labels;
5830 	dns_rdata_nsec3_t nsec3;
5831 	dns_rdata_t rdata = DNS_RDATA_INIT;
5832 	isc_boolean_t optout;
5833 	dns_clientinfomethods_t cm;
5834 	dns_clientinfo_t ci;
5835 
5836 	salt_length = sizeof(salt);
5837 	result = dns_db_getnsec3parameters(db, version, &hash, NULL,
5838 					   &iterations, salt, &salt_length);
5839 	if (result != ISC_R_SUCCESS)
5840 		return;
5841 
5842 	dns_name_init(&name, NULL);
5843 	dns_name_clone(qname, &name);
5844 	labels = dns_name_countlabels(&name);
5845 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
5846 	dns_clientinfo_init(&ci, client);
5847 
5848 	/*
5849 	 * Map unknown algorithm to known value.
5850 	 */
5851 	if (hash == DNS_NSEC3_UNKNOWNALG)
5852 		hash = 1;
5853 
5854  again:
5855 	dns_fixedname_init(&fixed);
5856 	result = dns_nsec3_hashname(&fixed, NULL, NULL, &name,
5857 				    dns_db_origin(db), hash,
5858 				    iterations, salt, salt_length);
5859 	if (result != ISC_R_SUCCESS)
5860 		return;
5861 
5862 	dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3;
5863 	result = dns_db_findext(db, dns_fixedname_name(&fixed), version,
5864 				dns_rdatatype_nsec3, dboptions, client->now,
5865 				NULL, fname, &cm, &ci, rdataset, sigrdataset);
5866 
5867 	if (result == DNS_R_NXDOMAIN) {
5868 		if (!dns_rdataset_isassociated(rdataset)) {
5869 			return;
5870 		}
5871 		result = dns_rdataset_first(rdataset);
5872 		INSIST(result == ISC_R_SUCCESS);
5873 		dns_rdataset_current(rdataset, &rdata);
5874 		dns_rdata_tostruct(&rdata, &nsec3, NULL);
5875 		dns_rdata_reset(&rdata);
5876 		optout = ISC_TF((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0);
5877 		if (found != NULL && optout &&
5878 		    dns_name_issubdomain(&name, dns_db_origin(db)))
5879 		{
5880 			dns_rdataset_disassociate(rdataset);
5881 			if (dns_rdataset_isassociated(sigrdataset))
5882 				dns_rdataset_disassociate(sigrdataset);
5883 			skip++;
5884 			dns_name_getlabelsequence(qname, skip, labels - skip,
5885 						  &name);
5886 			ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
5887 				      NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3),
5888 				      "looking for closest provable encloser");
5889 			goto again;
5890 		}
5891 		if (exact)
5892 			ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
5893 				      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
5894 				      "expected a exact match NSEC3, got "
5895 				      "a covering record");
5896 
5897 	} else if (result != ISC_R_SUCCESS) {
5898 		return;
5899 	} else if (!exact)
5900 		ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
5901 			      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
5902 			      "expected covering NSEC3, got an exact match");
5903 	if (found == qname) {
5904 		if (skip != 0U)
5905 			dns_name_getlabelsequence(qname, skip, labels - skip,
5906 						  found);
5907 	} else if (found != NULL)
5908 		dns_name_copy(&name, found, NULL);
5909 	return;
5910 }
5911 
5912 #ifdef ALLOW_FILTER_AAAA
5913 static isc_boolean_t
5914 is_v4_client(ns_client_t *client) {
5915 	if (isc_sockaddr_pf(&client->peeraddr) == AF_INET)
5916 		return (ISC_TRUE);
5917 	if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 &&
5918 	    IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr))
5919 		return (ISC_TRUE);
5920 	return (ISC_FALSE);
5921 }
5922 
5923 static isc_boolean_t
5924 is_v6_client(ns_client_t *client) {
5925 	if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 &&
5926 	    !IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr))
5927 		return (ISC_TRUE);
5928 	return (ISC_FALSE);
5929 }
5930 #endif
5931 
5932 static isc_uint32_t
5933 dns64_ttl(dns_db_t *db, dns_dbversion_t *version) {
5934 	dns_dbnode_t *node = NULL;
5935 	dns_rdata_soa_t soa;
5936 	dns_rdata_t rdata = DNS_RDATA_INIT;
5937 	dns_rdataset_t rdataset;
5938 	isc_result_t result;
5939 	isc_uint32_t ttl = ISC_UINT32_MAX;
5940 
5941 	dns_rdataset_init(&rdataset);
5942 
5943 	result = dns_db_getoriginnode(db, &node);
5944 	if (result != ISC_R_SUCCESS)
5945 		goto cleanup;
5946 
5947 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
5948 				     0, 0, &rdataset, NULL);
5949 	if (result != ISC_R_SUCCESS)
5950 		goto cleanup;
5951 	result = dns_rdataset_first(&rdataset);
5952 	if (result != ISC_R_SUCCESS)
5953 		goto cleanup;
5954 
5955 	dns_rdataset_current(&rdataset, &rdata);
5956 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
5957 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
5958 	ttl = ISC_MIN(rdataset.ttl, soa.minimum);
5959 
5960 cleanup:
5961 	if (dns_rdataset_isassociated(&rdataset))
5962 		dns_rdataset_disassociate(&rdataset);
5963 	if (node != NULL)
5964 		dns_db_detachnode(db, &node);
5965 	return (ttl);
5966 }
5967 
5968 static isc_boolean_t
5969 dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
5970 	     dns_rdataset_t *sigrdataset)
5971 {
5972 	isc_netaddr_t netaddr;
5973 	dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64);
5974 	unsigned int flags = 0;
5975 	unsigned int i, count;
5976 	isc_boolean_t *aaaaok;
5977 
5978 	INSIST(client->query.dns64_aaaaok == NULL);
5979 	INSIST(client->query.dns64_aaaaoklen == 0);
5980 	INSIST(client->query.dns64_aaaa == NULL);
5981 	INSIST(client->query.dns64_sigaaaa == NULL);
5982 
5983 	if (dns64 == NULL)
5984 		return (ISC_TRUE);
5985 
5986 	if (RECURSIONOK(client))
5987 		flags |= DNS_DNS64_RECURSIVE;
5988 
5989 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
5990 		flags |= DNS_DNS64_DNSSEC;
5991 
5992 	count = dns_rdataset_count(rdataset);
5993 	aaaaok = isc_mem_get(client->mctx, sizeof(isc_boolean_t) * count);
5994 
5995 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
5996 	if (dns_dns64_aaaaok(dns64, &netaddr, client->signer,
5997 			     &ns_g_server->aclenv, flags, rdataset,
5998 			     aaaaok, count)) {
5999 		for (i = 0; i < count; i++) {
6000 			if (aaaaok != NULL && !aaaaok[i]) {
6001 				client->query.dns64_aaaaok = aaaaok;
6002 				client->query.dns64_aaaaoklen = count;
6003 				break;
6004 			}
6005 		}
6006 		if (i == count && aaaaok != NULL)
6007 			isc_mem_put(client->mctx, aaaaok,
6008 				    sizeof(isc_boolean_t) * count);
6009 		return (ISC_TRUE);
6010 	}
6011 	if (aaaaok != NULL)
6012 		isc_mem_put(client->mctx, aaaaok,
6013 			    sizeof(isc_boolean_t) * count);
6014 	return (ISC_FALSE);
6015 }
6016 
6017 /*
6018  * Look for the name and type in the redirection zone.  If found update
6019  * the arguments as appropriate.  Return ISC_TRUE if a update was
6020  * performed.
6021  *
6022  * Only perform the update if the client is in the allow query acl and
6023  * returning the update would not cause a DNSSEC validation failure.
6024  */
6025 static isc_result_t
6026 redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
6027 	 dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
6028 	 dns_rdatatype_t qtype)
6029 {
6030 	dns_db_t *db = NULL;
6031 	dns_dbnode_t *node = NULL;
6032 	dns_fixedname_t fixed;
6033 	dns_name_t *found;
6034 	dns_rdataset_t trdataset;
6035 	isc_result_t result;
6036 	dns_rdatatype_t type;
6037 	dns_clientinfomethods_t cm;
6038 	dns_clientinfo_t ci;
6039 	ns_dbversion_t *dbversion;
6040 
6041 	CTRACE("redirect");
6042 
6043 	if (client->view->redirect == NULL)
6044 		return (ISC_R_NOTFOUND);
6045 
6046 	dns_fixedname_init(&fixed);
6047 	found = dns_fixedname_name(&fixed);
6048 	dns_rdataset_init(&trdataset);
6049 
6050 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
6051 	dns_clientinfo_init(&ci, client);
6052 
6053 	if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
6054 		return (ISC_R_NOTFOUND);
6055 
6056 	if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
6057 		if (rdataset->trust == dns_trust_secure)
6058 			return (ISC_R_NOTFOUND);
6059 		if (rdataset->trust == dns_trust_ultimate &&
6060 		    (rdataset->type == dns_rdatatype_nsec ||
6061 		     rdataset->type == dns_rdatatype_nsec3))
6062 			return (ISC_R_NOTFOUND);
6063 		if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
6064 			for (result = dns_rdataset_first(rdataset);
6065 			     result == ISC_R_SUCCESS;
6066 			     result = dns_rdataset_next(rdataset)) {
6067 				dns_ncache_current(rdataset, found, &trdataset);
6068 				type = trdataset.type;
6069 				dns_rdataset_disassociate(&trdataset);
6070 				if (type == dns_rdatatype_nsec ||
6071 				    type == dns_rdatatype_nsec3 ||
6072 				    type == dns_rdatatype_rrsig)
6073 					return (ISC_R_NOTFOUND);
6074 			}
6075 		}
6076 	}
6077 
6078 	result = ns_client_checkaclsilent(client, NULL,
6079 				 dns_zone_getqueryacl(client->view->redirect),
6080 					  ISC_TRUE);
6081 	if (result != ISC_R_SUCCESS)
6082 		return (ISC_R_NOTFOUND);
6083 
6084 	result = dns_zone_getdb(client->view->redirect, &db);
6085 	if (result != ISC_R_SUCCESS)
6086 		return (ISC_R_NOTFOUND);
6087 
6088 	dbversion = query_findversion(client, db);
6089 	if (dbversion == NULL) {
6090 		dns_db_detach(&db);
6091 		return (ISC_R_NOTFOUND);
6092 	}
6093 
6094 	/*
6095 	 * Lookup the requested data in the redirect zone.
6096 	 */
6097 	result = dns_db_findext(db, client->query.qname, dbversion->version,
6098 				qtype, 0, client->now, &node, found, &cm, &ci,
6099 				&trdataset, NULL);
6100 	if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
6101 		if (dns_rdataset_isassociated(rdataset))
6102 			dns_rdataset_disassociate(rdataset);
6103 		if (dns_rdataset_isassociated(&trdataset))
6104 			dns_rdataset_disassociate(&trdataset);
6105 		goto nxrrset;
6106 	} else if (result != ISC_R_SUCCESS) {
6107 		if (dns_rdataset_isassociated(&trdataset))
6108 			dns_rdataset_disassociate(&trdataset);
6109 		if (node != NULL)
6110 			dns_db_detachnode(db, &node);
6111 		dns_db_detach(&db);
6112 		return (ISC_R_NOTFOUND);
6113 	}
6114 
6115 	CTRACE("redirect: found data: done");
6116 	dns_name_copy(found, name, NULL);
6117 	if (dns_rdataset_isassociated(rdataset))
6118 		dns_rdataset_disassociate(rdataset);
6119 	if (dns_rdataset_isassociated(&trdataset)) {
6120 		dns_rdataset_clone(&trdataset, rdataset);
6121 		dns_rdataset_disassociate(&trdataset);
6122 	}
6123  nxrrset:
6124 	if (*nodep != NULL)
6125 		dns_db_detachnode(*dbp, nodep);
6126 	dns_db_detach(dbp);
6127 	dns_db_attachnode(db, node, nodep);
6128 	dns_db_attach(db, dbp);
6129 	dns_db_detachnode(db, &node);
6130 	dns_db_detach(&db);
6131 	*versionp = dbversion->version;
6132 
6133 	client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
6134 				     NS_QUERYATTR_NOADDITIONAL);
6135 
6136 	return (result);
6137 }
6138 
6139 /*
6140  * Do the bulk of query processing for the current query of 'client'.
6141  * If 'event' is non-NULL, we are returning from recursion and 'qtype'
6142  * is ignored.  Otherwise, 'qtype' is the query type.
6143  */
6144 static isc_result_t
6145 query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
6146 {
6147 	dns_db_t *db, *zdb;
6148 	dns_dbnode_t *node;
6149 	dns_rdatatype_t type = qtype;
6150 	dns_name_t *fname, *zfname, *tname, *prefix;
6151 	dns_rdataset_t *rdataset, *trdataset;
6152 	dns_rdataset_t *sigrdataset, *zrdataset, *zsigrdataset;
6153 	dns_rdataset_t **sigrdatasetp;
6154 	dns_rdata_t rdata = DNS_RDATA_INIT;
6155 	dns_rdatasetiter_t *rdsiter;
6156 	isc_boolean_t want_restart, is_zone, need_wildcardproof;
6157 	isc_boolean_t is_staticstub_zone;
6158 	isc_boolean_t authoritative = ISC_FALSE;
6159 	unsigned int n, nlabels;
6160 	dns_namereln_t namereln;
6161 	int order;
6162 	isc_buffer_t *dbuf;
6163 	isc_buffer_t b;
6164 	isc_result_t result, eresult, tresult;
6165 	dns_fixedname_t fixed;
6166 	dns_fixedname_t wildcardname;
6167 	dns_dbversion_t *version, *zversion;
6168 	dns_zone_t *zone;
6169 	dns_rdata_cname_t cname;
6170 	dns_rdata_dname_t dname;
6171 	unsigned int options;
6172 	isc_boolean_t empty_wild;
6173 	dns_rdataset_t *noqname;
6174 	dns_rpz_st_t *rpz_st;
6175 	isc_boolean_t resuming;
6176 	int line = -1;
6177 	isc_boolean_t dns64_exclude, dns64;
6178 	isc_boolean_t nxrewrite = ISC_FALSE;
6179 	isc_boolean_t redirected = ISC_FALSE;
6180 	dns_clientinfomethods_t cm;
6181 	dns_clientinfo_t ci;
6182 	isc_boolean_t associated;
6183 	dns_section_t section;
6184 	dns_ttl_t ttl;
6185 
6186 	CTRACE("query_find");
6187 
6188 	/*
6189 	 * One-time initialization.
6190 	 *
6191 	 * It's especially important to initialize anything that the cleanup
6192 	 * code might cleanup.
6193 	 */
6194 
6195 	eresult = ISC_R_SUCCESS;
6196 	fname = NULL;
6197 	zfname = NULL;
6198 	rdataset = NULL;
6199 	zrdataset = NULL;
6200 	sigrdataset = NULL;
6201 	zsigrdataset = NULL;
6202 	zversion = NULL;
6203 	node = NULL;
6204 	db = NULL;
6205 	zdb = NULL;
6206 	version = NULL;
6207 	zone = NULL;
6208 	need_wildcardproof = ISC_FALSE;
6209 	empty_wild = ISC_FALSE;
6210 	dns64_exclude = dns64 = ISC_FALSE;
6211 	options = 0;
6212 	resuming = ISC_FALSE;
6213 	is_zone = ISC_FALSE;
6214 	is_staticstub_zone = ISC_FALSE;
6215 
6216 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
6217 	dns_clientinfo_init(&ci, client);
6218 
6219 	if (event != NULL) {
6220 		/*
6221 		 * We're returning from recursion.  Restore the query context
6222 		 * and resume.
6223 		 */
6224 		want_restart = ISC_FALSE;
6225 
6226 		rpz_st = client->query.rpz_st;
6227 		if (rpz_st != NULL &&
6228 		    (rpz_st->state & DNS_RPZ_RECURSING) != 0)
6229 		{
6230 			CTRACE("resume from RPZ recursion");
6231 
6232 			is_zone = rpz_st->q.is_zone;
6233 			authoritative = rpz_st->q.authoritative;
6234 			zone = rpz_st->q.zone;
6235 			rpz_st->q.zone = NULL;
6236 			node = rpz_st->q.node;
6237 			rpz_st->q.node = NULL;
6238 			db = rpz_st->q.db;
6239 			rpz_st->q.db = NULL;
6240 			rdataset = rpz_st->q.rdataset;
6241 			rpz_st->q.rdataset = NULL;
6242 			sigrdataset = rpz_st->q.sigrdataset;
6243 			rpz_st->q.sigrdataset = NULL;
6244 			qtype = rpz_st->q.qtype;
6245 
6246 			rpz_st->r.db = event->db;
6247 			if (event->node != NULL)
6248 				dns_db_detachnode(event->db, &event->node);
6249 			rpz_st->r.r_type = event->qtype;
6250 			rpz_st->r.r_rdataset = event->rdataset;
6251 			query_putrdataset(client, &event->sigrdataset);
6252 		} else {
6253 			CTRACE("resume from normal recursion");
6254 			authoritative = ISC_FALSE;
6255 
6256 			qtype = event->qtype;
6257 			db = event->db;
6258 			node = event->node;
6259 			rdataset = event->rdataset;
6260 			sigrdataset = event->sigrdataset;
6261 		}
6262 
6263 		if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig)
6264 			type = dns_rdatatype_any;
6265 		else
6266 			type = qtype;
6267 
6268 		if (DNS64(client)) {
6269 			client->query.attributes &= ~NS_QUERYATTR_DNS64;
6270 			dns64 = ISC_TRUE;
6271 		}
6272 		if (DNS64EXCLUDE(client)) {
6273 			client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
6274 			dns64_exclude = ISC_TRUE;
6275 		}
6276 
6277 		if (rpz_st != NULL &&
6278 		    (rpz_st->state & DNS_RPZ_RECURSING) != 0)
6279 		{
6280 			/*
6281 			 * Has response policy changed out from under us?
6282 			 */
6283 			if (rpz_st->rpz_ver != client->view->rpzs->rpz_ver) {
6284 				ns_client_log(client, NS_LOGCATEGORY_CLIENT,
6285 					      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
6286 					      "query_find: RPZ settings "
6287 					      "out of date "
6288 					      "(rpz_ver %d, expected %d)",
6289 					      client->view->rpzs->rpz_ver,
6290 					      rpz_st->rpz_ver);
6291 				QUERY_ERROR(DNS_R_SERVFAIL);
6292 				goto cleanup;
6293 			}
6294 		}
6295 
6296 		/*
6297 		 * We'll need some resources...
6298 		 */
6299 		dbuf = query_getnamebuf(client);
6300 		if (dbuf == NULL) {
6301 			QUERY_ERROR(DNS_R_SERVFAIL);
6302 			goto cleanup;
6303 		}
6304 		fname = query_newname(client, dbuf, &b);
6305 		if (fname == NULL) {
6306 			QUERY_ERROR(DNS_R_SERVFAIL);
6307 			goto cleanup;
6308 		}
6309 		if (rpz_st != NULL &&
6310 		    (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
6311 			tname = rpz_st->fname;
6312 		} else {
6313 			tname = dns_fixedname_name(&event->foundname);
6314 		}
6315 		result = dns_name_copy(tname, fname, NULL);
6316 		if (result != ISC_R_SUCCESS) {
6317 			QUERY_ERROR(DNS_R_SERVFAIL);
6318 			goto cleanup;
6319 		}
6320 		if (rpz_st != NULL &&
6321 		    (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
6322 			rpz_st->r.r_result = event->result;
6323 			result = rpz_st->q.result;
6324 			isc_event_free(ISC_EVENT_PTR(&event));
6325 		} else {
6326 			result = event->result;
6327 		}
6328 		resuming = ISC_TRUE;
6329 		goto resume;
6330 	}
6331 
6332 	/*
6333 	 * Not returning from recursion.
6334 	 */
6335 
6336 	/*
6337 	 * If it's a SIG query, we'll iterate the node.
6338 	 */
6339 	if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig)
6340 		type = dns_rdatatype_any;
6341 	else
6342 		type = qtype;
6343 
6344  restart:
6345 	CTRACE("query_find: restart");
6346 	want_restart = ISC_FALSE;
6347 	authoritative = ISC_FALSE;
6348 	version = NULL;
6349 	need_wildcardproof = ISC_FALSE;
6350 
6351 	if (client->view->checknames &&
6352 	    !dns_rdata_checkowner(client->query.qname,
6353 				  client->message->rdclass,
6354 				  qtype, ISC_FALSE)) {
6355 		char namebuf[DNS_NAME_FORMATSIZE];
6356 		char typename[DNS_RDATATYPE_FORMATSIZE];
6357 		char classname[DNS_RDATACLASS_FORMATSIZE];
6358 
6359 		dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
6360 		dns_rdatatype_format(qtype, typename, sizeof(typename));
6361 		dns_rdataclass_format(client->message->rdclass, classname,
6362 				      sizeof(classname));
6363 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
6364 			      NS_LOGMODULE_QUERY, ISC_LOG_ERROR,
6365 			      "check-names failure %s/%s/%s", namebuf,
6366 			      typename, classname);
6367 		QUERY_ERROR(DNS_R_REFUSED);
6368 		goto cleanup;
6369 	}
6370 
6371 	/*
6372 	 * First we must find the right database.
6373 	 */
6374 	options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */
6375 	if (dns_rdatatype_atparent(qtype) &&
6376 	    !dns_name_equal(client->query.qname, dns_rootname))
6377 		options |= DNS_GETDB_NOEXACT;
6378 	result = query_getdb(client, client->query.qname, qtype, options,
6379 			     &zone, &db, &version, &is_zone);
6380 	if ((result != ISC_R_SUCCESS || !is_zone) && !RECURSIONOK(client) &&
6381 	    (options & DNS_GETDB_NOEXACT) != 0 && qtype == dns_rdatatype_ds) {
6382 		/*
6383 		 * Look to see if we are authoritative for the
6384 		 * child zone if the query type is DS.
6385 		 */
6386 		dns_db_t *tdb = NULL;
6387 		dns_zone_t *tzone = NULL;
6388 		dns_dbversion_t *tversion = NULL;
6389 
6390 		tresult = query_getzonedb(client, client->query.qname, qtype,
6391 					 DNS_GETDB_PARTIAL, &tzone, &tdb,
6392 					 &tversion);
6393 		if (tresult == ISC_R_SUCCESS) {
6394 			options &= ~DNS_GETDB_NOEXACT;
6395 			query_putrdataset(client, &rdataset);
6396 			if (db != NULL)
6397 				dns_db_detach(&db);
6398 			if (zone != NULL)
6399 				dns_zone_detach(&zone);
6400 			version = tversion;
6401 			db = tdb;
6402 			zone = tzone;
6403 			is_zone = ISC_TRUE;
6404 			result = ISC_R_SUCCESS;
6405 		} else {
6406 			if (tdb != NULL)
6407 				dns_db_detach(&tdb);
6408 			if (tzone != NULL)
6409 				dns_zone_detach(&tzone);
6410 		}
6411 	}
6412 	if (result != ISC_R_SUCCESS) {
6413 		if (result == DNS_R_REFUSED) {
6414 			if (WANTRECURSION(client)) {
6415 				inc_stats(client,
6416 					  dns_nsstatscounter_recurserej);
6417 			} else
6418 				inc_stats(client, dns_nsstatscounter_authrej);
6419 			if (!PARTIALANSWER(client))
6420 				QUERY_ERROR(DNS_R_REFUSED);
6421 		} else
6422 			QUERY_ERROR(DNS_R_SERVFAIL);
6423 		goto cleanup;
6424 	}
6425 
6426 	is_staticstub_zone = ISC_FALSE;
6427 	if (is_zone) {
6428 		authoritative = ISC_TRUE;
6429 		if (zone != NULL &&
6430 		    dns_zone_gettype(zone) == dns_zone_staticstub)
6431 			is_staticstub_zone = ISC_TRUE;
6432 	}
6433 
6434 	if (event == NULL && client->query.restarts == 0) {
6435 		if (is_zone) {
6436 			if (zone != NULL) {
6437 				/*
6438 				 * if is_zone = true, zone = NULL then this is
6439 				 * a DLZ zone.  Don't attempt to attach zone.
6440 				 */
6441 				dns_zone_attach(zone, &client->query.authzone);
6442 			}
6443 			dns_db_attach(db, &client->query.authdb);
6444 		}
6445 		client->query.authdbset = ISC_TRUE;
6446 
6447 		/* Track TCP vs UDP stats per zone */
6448 		if ((client->attributes & NS_CLIENTATTR_TCP) != 0)
6449 			inc_stats(client, dns_nsstatscounter_tcp);
6450 		else
6451 			inc_stats(client, dns_nsstatscounter_udp);
6452 	}
6453 
6454  db_find:
6455 	CTRACE("query_find: db_find");
6456 	/*
6457 	 * We'll need some resources...
6458 	 */
6459 	dbuf = query_getnamebuf(client);
6460 	if (dbuf == NULL) {
6461 		QUERY_ERROR(DNS_R_SERVFAIL);
6462 		goto cleanup;
6463 	}
6464 	fname = query_newname(client, dbuf, &b);
6465 	rdataset = query_newrdataset(client);
6466 	if (fname == NULL || rdataset == NULL) {
6467 		QUERY_ERROR(DNS_R_SERVFAIL);
6468 		goto cleanup;
6469 	}
6470 	if (WANTDNSSEC(client) && (!is_zone || dns_db_issecure(db))) {
6471 		sigrdataset = query_newrdataset(client);
6472 		if (sigrdataset == NULL) {
6473 			QUERY_ERROR(DNS_R_SERVFAIL);
6474 			goto cleanup;
6475 		}
6476 	}
6477 
6478 	/*
6479 	 * Now look for an answer in the database.
6480 	 */
6481 	result = dns_db_findext(db, client->query.qname, version, type,
6482 				client->query.dboptions, client->now,
6483 				&node, fname, &cm, &ci, rdataset, sigrdataset);
6484 
6485 	if (db == client->view->cachedb)
6486 		dns_cache_updatestats(client->view->cache, result);
6487 
6488  resume:
6489 	CTRACE("query_find: resume");
6490 
6491 	/*
6492 	 * Rate limit these responses to this client.
6493 	 * Do not delay counting and handling obvious referrals,
6494 	 *	since those won't come here again.
6495 	 * Delay handling delegations for which we are certain to recurse and
6496 	 *	return here (DNS_R_DELEGATION, not a child of one of our
6497 	 *	own zones, and recursion enabled)
6498 	 * Don't mess with responses rewritten by RPZ
6499 	 * Count each response at most once.
6500 	 */
6501 	if (client->view->rrl != NULL && !HAVESIT(client) &&
6502 	    ((fname != NULL && dns_name_isabsolute(fname)) ||
6503 	     (result == ISC_R_NOTFOUND && !RECURSIONOK(client))) &&
6504 	    !(result == DNS_R_DELEGATION && !is_zone && RECURSIONOK(client)) &&
6505 	    (client->query.rpz_st == NULL ||
6506 	     (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0)&&
6507 	    (client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0)
6508 	{
6509 		dns_rdataset_t nc_rdataset;
6510 		isc_boolean_t wouldlog;
6511 		char log_buf[DNS_RRL_LOG_BUF_LEN];
6512 		isc_result_t nc_result, resp_result;
6513 		dns_rrl_result_t rrl_result;
6514 
6515 		client->query.attributes |= NS_QUERYATTR_RRL_CHECKED;
6516 
6517 		wouldlog = isc_log_wouldlog(ns_g_lctx, DNS_RRL_LOG_DROP);
6518 		tname = fname;
6519 		if (result == DNS_R_NXDOMAIN) {
6520 			/*
6521 			 * Use the database origin name to rate limit NXDOMAIN
6522 			 */
6523 			if (db != NULL)
6524 				tname = dns_db_origin(db);
6525 			resp_result = result;
6526 		} else if (result == DNS_R_NCACHENXDOMAIN &&
6527 			   rdataset != NULL &&
6528 			   dns_rdataset_isassociated(rdataset) &&
6529 			   (rdataset->attributes &
6530 			    DNS_RDATASETATTR_NEGATIVE) != 0) {
6531 			/*
6532 			 * Try to use owner name in the negative cache SOA.
6533 			 */
6534 			dns_fixedname_init(&fixed);
6535 			dns_rdataset_init(&nc_rdataset);
6536 			for (nc_result = dns_rdataset_first(rdataset);
6537 			     nc_result == ISC_R_SUCCESS;
6538 			     nc_result = dns_rdataset_next(rdataset)) {
6539 				dns_ncache_current(rdataset,
6540 						   dns_fixedname_name(&fixed),
6541 						   &nc_rdataset);
6542 				if (nc_rdataset.type == dns_rdatatype_soa) {
6543 					dns_rdataset_disassociate(&nc_rdataset);
6544 					tname = dns_fixedname_name(&fixed);
6545 					break;
6546 				}
6547 				dns_rdataset_disassociate(&nc_rdataset);
6548 			}
6549 			resp_result = DNS_R_NXDOMAIN;
6550 		} else if (result == DNS_R_NXRRSET ||
6551 			   result == DNS_R_EMPTYNAME) {
6552 			resp_result = DNS_R_NXRRSET;
6553 		} else if (result == DNS_R_DELEGATION) {
6554 			resp_result = result;
6555 		} else if (result == ISC_R_NOTFOUND) {
6556 			/*
6557 			 * Handle referral to ".", including when recursion
6558 			 * is off or not requested and the hints have not
6559 			 * been loaded or we have "additional-from-cache no".
6560 			 */
6561 			tname = dns_rootname;
6562 			resp_result = DNS_R_DELEGATION;
6563 		} else {
6564 			resp_result = ISC_R_SUCCESS;
6565 		}
6566 		rrl_result = dns_rrl(client->view, &client->peeraddr,
6567 				     ISC_TF((client->attributes
6568 					     & NS_CLIENTATTR_TCP) != 0),
6569 				     client->message->rdclass, qtype, tname,
6570 				     resp_result, client->now,
6571 				     wouldlog, log_buf, sizeof(log_buf));
6572 		if (rrl_result != DNS_RRL_RESULT_OK) {
6573 			/*
6574 			 * Log dropped or slipped responses in the query
6575 			 * category so that requests are not silently lost.
6576 			 * Starts of rate-limited bursts are logged in
6577 			 * DNS_LOGCATEGORY_RRL.
6578 			 *
6579 			 * Dropped responses are counted with dropped queries
6580 			 * in QryDropped while slipped responses are counted
6581 			 * with other truncated responses in RespTruncated.
6582 			 */
6583 			if (wouldlog) {
6584 				ns_client_log(client, DNS_LOGCATEGORY_RRL,
6585 					      NS_LOGMODULE_QUERY,
6586 					      DNS_RRL_LOG_DROP,
6587 					      "%s", log_buf);
6588 			}
6589 			if (!client->view->rrl->log_only) {
6590 				if (rrl_result == DNS_RRL_RESULT_DROP) {
6591 					/*
6592 					 * These will also be counted in
6593 					 * dns_nsstatscounter_dropped
6594 					 */
6595 					inc_stats(client,
6596 						dns_nsstatscounter_ratedropped);
6597 					QUERY_ERROR(DNS_R_DROP);
6598 				} else {
6599 					/*
6600 					 * These will also be counted in
6601 					 * dns_nsstatscounter_truncatedresp
6602 					 */
6603 					inc_stats(client,
6604 						dns_nsstatscounter_rateslipped);
6605 					client->message->flags |=
6606 						DNS_MESSAGEFLAG_TC;
6607 					if (resp_result == DNS_R_NXDOMAIN)
6608 						client->message->rcode =
6609 							dns_rcode_nxdomain;
6610 				}
6611 				goto cleanup;
6612 			}
6613 		}
6614 	}
6615 
6616 	if (!RECURSING(client) &&
6617 	    !dns_name_equal(client->query.qname, dns_rootname))
6618 	{
6619 		isc_result_t rresult;
6620 
6621 		rresult = rpz_rewrite(client, qtype, result, resuming,
6622 				      rdataset, sigrdataset);
6623 		rpz_st = client->query.rpz_st;
6624 		switch (rresult) {
6625 		case ISC_R_SUCCESS:
6626 			break;
6627 		case DNS_R_DISALLOWED:
6628 			goto norpz;
6629 		case DNS_R_DELEGATION:
6630 			/*
6631 			 * recursing for NS names or addresses,
6632 			 * so save the main query state
6633 			 */
6634 			rpz_st->q.qtype = qtype;
6635 			rpz_st->q.is_zone = is_zone;
6636 			rpz_st->q.authoritative = authoritative;
6637 			rpz_st->q.zone = zone;
6638 			zone = NULL;
6639 			rpz_st->q.db = db;
6640 			db = NULL;
6641 			rpz_st->q.node = node;
6642 			node = NULL;
6643 			rpz_st->q.rdataset = rdataset;
6644 			rdataset = NULL;
6645 			rpz_st->q.sigrdataset = sigrdataset;
6646 			sigrdataset = NULL;
6647 			dns_name_copy(fname, rpz_st->fname, NULL);
6648 			rpz_st->q.result = result;
6649 			client->query.attributes |= NS_QUERYATTR_RECURSING;
6650 			goto cleanup;
6651 		default:
6652 			RECURSE_ERROR(rresult);
6653 			goto cleanup;
6654 		}
6655 
6656 		if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS)
6657 			rpz_st->state |= DNS_RPZ_REWRITTEN;
6658 		if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS &&
6659 		    rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU &&
6660 		    (rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY ||
6661 		     (client->attributes & NS_CLIENTATTR_TCP) == 0) &&
6662 		    rpz_st->m.policy != DNS_RPZ_POLICY_ERROR)
6663 		{
6664 			/*
6665 			 * We got a hit and are going to answer with our
6666 			 * fiction. Ensure that we answer with the name
6667 			 * we looked up even if we were stopped short
6668 			 * in recursion or for a deferral.
6669 			 */
6670 			rresult = dns_name_copy(client->query.qname,
6671 						fname, NULL);
6672 			RUNTIME_CHECK(rresult == ISC_R_SUCCESS);
6673 			rpz_clean(&zone, &db, &node, NULL);
6674 			if (rpz_st->m.rdataset != NULL) {
6675 				query_putrdataset(client, &rdataset);
6676 				rdataset = rpz_st->m.rdataset;
6677 				rpz_st->m.rdataset = NULL;
6678 			} else if (rdataset != NULL &&
6679 				   dns_rdataset_isassociated(rdataset)) {
6680 				dns_rdataset_disassociate(rdataset);
6681 			}
6682 			node = rpz_st->m.node;
6683 			rpz_st->m.node = NULL;
6684 			db = rpz_st->m.db;
6685 			rpz_st->m.db = NULL;
6686 			version = rpz_st->m.version;
6687 			rpz_st->m.version = NULL;
6688 			zone = rpz_st->m.zone;
6689 			rpz_st->m.zone = NULL;
6690 
6691 			switch (rpz_st->m.policy) {
6692 			case DNS_RPZ_POLICY_TCP_ONLY:
6693 				client->message->flags |= DNS_MESSAGEFLAG_TC;
6694 				if (result == DNS_R_NXDOMAIN ||
6695 				    result == DNS_R_NCACHENXDOMAIN)
6696 					client->message->rcode =
6697 						    dns_rcode_nxdomain;
6698 				rpz_log_rewrite(client, ISC_FALSE,
6699 						rpz_st->m.policy,
6700 						rpz_st->m.type, zone,
6701 						rpz_st->p_name);
6702 				goto cleanup;
6703 			case DNS_RPZ_POLICY_DROP:
6704 				QUERY_ERROR(DNS_R_DROP);
6705 				rpz_log_rewrite(client, ISC_FALSE,
6706 						rpz_st->m.policy,
6707 						rpz_st->m.type, zone,
6708 						rpz_st->p_name);
6709 				goto cleanup;
6710 			case DNS_RPZ_POLICY_NXDOMAIN:
6711 				result = DNS_R_NXDOMAIN;
6712 				nxrewrite = ISC_TRUE;
6713 				break;
6714 			case DNS_RPZ_POLICY_NODATA:
6715 				result = DNS_R_NXRRSET;
6716 				nxrewrite = ISC_TRUE;
6717 				break;
6718 			case DNS_RPZ_POLICY_RECORD:
6719 				result = rpz_st->m.result;
6720 				if (qtype == dns_rdatatype_any &&
6721 				    result != DNS_R_CNAME) {
6722 					/*
6723 					 * We will add all of the rdatasets of
6724 					 * the node by iterating later,
6725 					 * and set the TTL then.
6726 					 */
6727 					if (dns_rdataset_isassociated(rdataset))
6728 					    dns_rdataset_disassociate(rdataset);
6729 				} else {
6730 					/*
6731 					 * We will add this rdataset.
6732 					 */
6733 					rdataset->ttl = ISC_MIN(rdataset->ttl,
6734 								rpz_st->m.ttl);
6735 				}
6736 				break;
6737 			case DNS_RPZ_POLICY_WILDCNAME:
6738 				result = dns_rdataset_first(rdataset);
6739 				RUNTIME_CHECK(result == ISC_R_SUCCESS);
6740 				dns_rdataset_current(rdataset, &rdata);
6741 				result = dns_rdata_tostruct(&rdata, &cname,
6742 							    NULL);
6743 				RUNTIME_CHECK(result == ISC_R_SUCCESS);
6744 				dns_rdata_reset(&rdata);
6745 				result = rpz_add_cname(client, rpz_st,
6746 						       &cname.cname,
6747 						       fname, dbuf);
6748 				if (result != ISC_R_SUCCESS)
6749 					goto cleanup;
6750 				fname = NULL;
6751 				want_restart = ISC_TRUE;
6752 				goto cleanup;
6753 			case DNS_RPZ_POLICY_CNAME:
6754 				/*
6755 				 * Add overridding CNAME from a named.conf
6756 				 * response-policy statement
6757 				 */
6758 				result = rpz_add_cname(client, rpz_st,
6759 						       &rpz_st->m.rpz->cname,
6760 						       fname, dbuf);
6761 				if (result != ISC_R_SUCCESS)
6762 					goto cleanup;
6763 				fname = NULL;
6764 				want_restart = ISC_TRUE;
6765 				goto cleanup;
6766 			default:
6767 				INSIST(0);
6768 			}
6769 
6770 			/*
6771 			 * Turn off DNSSEC because the results of a
6772 			 * response policy zone cannot verify.
6773 			 */
6774 			client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
6775 						NS_CLIENTATTR_WANTAD);
6776 			client->message->flags &= ~DNS_MESSAGEFLAG_AD;
6777 			query_putrdataset(client, &sigrdataset);
6778 			rpz_st->q.is_zone = is_zone;
6779 			is_zone = ISC_TRUE;
6780 			rpz_log_rewrite(client, ISC_FALSE, rpz_st->m.policy,
6781 					rpz_st->m.type, zone, rpz_st->p_name);
6782 		}
6783 	}
6784 
6785  norpz:
6786 	switch (result) {
6787 	case ISC_R_SUCCESS:
6788 		/*
6789 		 * This case is handled in the main line below.
6790 		 */
6791 		break;
6792 	case DNS_R_GLUE:
6793 	case DNS_R_ZONECUT:
6794 		/*
6795 		 * These cases are handled in the main line below.
6796 		 */
6797 		INSIST(is_zone);
6798 		authoritative = ISC_FALSE;
6799 		break;
6800 	case ISC_R_NOTFOUND:
6801 		/*
6802 		 * The cache doesn't even have the root NS.  Get them from
6803 		 * the hints DB.
6804 		 */
6805 		INSIST(!is_zone);
6806 		if (db != NULL)
6807 			dns_db_detach(&db);
6808 
6809 		if (client->view->hints == NULL) {
6810 			/* We have no hints. */
6811 			result = ISC_R_FAILURE;
6812 		} else {
6813 			dns_db_attach(client->view->hints, &db);
6814 			result = dns_db_findext(db, dns_rootname,
6815 						NULL, dns_rdatatype_ns,
6816 						0, client->now, &node,
6817 						fname, &cm, &ci,
6818 						rdataset, sigrdataset);
6819 		}
6820 		if (result != ISC_R_SUCCESS) {
6821 			/*
6822 			 * Nonsensical root hints may require cleanup.
6823 			 */
6824 			if (dns_rdataset_isassociated(rdataset))
6825 				dns_rdataset_disassociate(rdataset);
6826 			if (sigrdataset != NULL &&
6827 			    dns_rdataset_isassociated(sigrdataset))
6828 				dns_rdataset_disassociate(sigrdataset);
6829 			if (node != NULL)
6830 				dns_db_detachnode(db, &node);
6831 
6832 			/*
6833 			 * We don't have any root server hints, but
6834 			 * we may have working forwarders, so try to
6835 			 * recurse anyway.
6836 			 */
6837 			if (RECURSIONOK(client)) {
6838 				result = query_recurse(client, qtype,
6839 						       client->query.qname,
6840 						       NULL, NULL, resuming);
6841 				if (result == ISC_R_SUCCESS) {
6842 					client->query.attributes |=
6843 						NS_QUERYATTR_RECURSING;
6844 					if (dns64)
6845 						client->query.attributes |=
6846 							NS_QUERYATTR_DNS64;
6847 					if (dns64_exclude)
6848 						client->query.attributes |=
6849 						      NS_QUERYATTR_DNS64EXCLUDE;
6850 				} else
6851 					RECURSE_ERROR(result);
6852 				goto cleanup;
6853 			} else {
6854 				/* Unable to give root server referral. */
6855 				QUERY_ERROR(DNS_R_SERVFAIL);
6856 				goto cleanup;
6857 			}
6858 		}
6859 		/*
6860 		 * XXXRTH  We should trigger root server priming here.
6861 		 */
6862 		/* FALLTHROUGH */
6863 	case DNS_R_DELEGATION:
6864 		authoritative = ISC_FALSE;
6865 		if (is_zone) {
6866 			/*
6867 			 * Look to see if we are authoritative for the
6868 			 * child zone if the query type is DS.
6869 			 */
6870 			if (!RECURSIONOK(client) &&
6871 			    (options & DNS_GETDB_NOEXACT) != 0 &&
6872 			    qtype == dns_rdatatype_ds) {
6873 				dns_db_t *tdb = NULL;
6874 				dns_zone_t *tzone = NULL;
6875 				dns_dbversion_t *tversion = NULL;
6876 				result = query_getzonedb(client,
6877 							 client->query.qname,
6878 							 qtype,
6879 							 DNS_GETDB_PARTIAL,
6880 							 &tzone, &tdb,
6881 							 &tversion);
6882 				if (result == ISC_R_SUCCESS) {
6883 					options &= ~DNS_GETDB_NOEXACT;
6884 					query_putrdataset(client, &rdataset);
6885 					if (sigrdataset != NULL)
6886 						query_putrdataset(client,
6887 								  &sigrdataset);
6888 					if (fname != NULL)
6889 						query_releasename(client,
6890 								  &fname);
6891 					if (node != NULL)
6892 						dns_db_detachnode(db, &node);
6893 					if (db != NULL)
6894 						dns_db_detach(&db);
6895 					if (zone != NULL)
6896 						dns_zone_detach(&zone);
6897 					version = tversion;
6898 					db = tdb;
6899 					zone = tzone;
6900 					authoritative = ISC_TRUE;
6901 					goto db_find;
6902 				}
6903 				if (tdb != NULL)
6904 					dns_db_detach(&tdb);
6905 				if (tzone != NULL)
6906 					dns_zone_detach(&tzone);
6907 			}
6908 			/*
6909 			 * We're authoritative for an ancestor of QNAME.
6910 			 */
6911 			if (!USECACHE(client) || !RECURSIONOK(client)) {
6912 				dns_fixedname_init(&fixed);
6913 				dns_name_copy(fname,
6914 					      dns_fixedname_name(&fixed), NULL);
6915 
6916 				/*
6917 				 * If we don't have a cache, this is the best
6918 				 * answer.
6919 				 *
6920 				 * If the client is making a nonrecursive
6921 				 * query we always give out the authoritative
6922 				 * delegation.  This way even if we get
6923 				 * junk in our cache, we won't fail in our
6924 				 * role as the delegating authority if another
6925 				 * nameserver asks us about a delegated
6926 				 * subzone.
6927 				 *
6928 				 * We enable the retrieval of glue for this
6929 				 * database by setting client->query.gluedb.
6930 				 */
6931 				client->query.gluedb = db;
6932 				client->query.isreferral = ISC_TRUE;
6933 				/*
6934 				 * We must ensure NOADDITIONAL is off,
6935 				 * because the generation of
6936 				 * additional data is required in
6937 				 * delegations.
6938 				 */
6939 				client->query.attributes &=
6940 					~NS_QUERYATTR_NOADDITIONAL;
6941 				if (sigrdataset != NULL)
6942 					sigrdatasetp = &sigrdataset;
6943 				else
6944 					sigrdatasetp = NULL;
6945 				query_addrrset(client, &fname,
6946 					       &rdataset, sigrdatasetp,
6947 					       dbuf, DNS_SECTION_AUTHORITY);
6948 				client->query.gluedb = NULL;
6949 				if (WANTDNSSEC(client))
6950 					query_addds(client, db, node, version,
6951 						   dns_fixedname_name(&fixed));
6952 			} else {
6953 				/*
6954 				 * We might have a better answer or delegation
6955 				 * in the cache.  We'll remember the current
6956 				 * values of fname, rdataset, and sigrdataset.
6957 				 * We'll then go looking for QNAME in the
6958 				 * cache.  If we find something better, we'll
6959 				 * use it instead.
6960 				 */
6961 				query_keepname(client, fname, dbuf);
6962 				zdb = db;
6963 				zfname = fname;
6964 				fname = NULL;
6965 				zrdataset = rdataset;
6966 				rdataset = NULL;
6967 				zsigrdataset = sigrdataset;
6968 				sigrdataset = NULL;
6969 				dns_db_detachnode(db, &node);
6970 				zversion = version;
6971 				version = NULL;
6972 				db = NULL;
6973 				dns_db_attach(client->view->cachedb, &db);
6974 				is_zone = ISC_FALSE;
6975 				goto db_find;
6976 			}
6977 		} else {
6978 			if (zfname != NULL &&
6979 			    (!dns_name_issubdomain(fname, zfname) ||
6980 			     (is_staticstub_zone &&
6981 			      dns_name_equal(fname, zfname)))) {
6982 				/*
6983 				 * In the following cases use "authoritative"
6984 				 * data instead of the cache delegation:
6985 				 * 1. We've already got a delegation from
6986 				 *    authoritative data, and it is better
6987 				 *    than what we found in the cache.
6988 				 * 2. The query name matches the origin name
6989 				 *    of a static-stub zone.  This needs to be
6990 				 *    considered for the case where the NS of
6991 				 *    the static-stub zone and the cached NS
6992 				 *    are different.  We still need to contact
6993 				 *    the nameservers configured in the
6994 				 *    static-stub zone.
6995 				 */
6996 				query_releasename(client, &fname);
6997 				fname = zfname;
6998 				zfname = NULL;
6999 				/*
7000 				 * We've already done query_keepname() on
7001 				 * zfname, so we must set dbuf to NULL to
7002 				 * prevent query_addrrset() from trying to
7003 				 * call query_keepname() again.
7004 				 */
7005 				dbuf = NULL;
7006 				query_putrdataset(client, &rdataset);
7007 				if (sigrdataset != NULL)
7008 					query_putrdataset(client,
7009 							  &sigrdataset);
7010 				rdataset = zrdataset;
7011 				zrdataset = NULL;
7012 				sigrdataset = zsigrdataset;
7013 				zsigrdataset = NULL;
7014 				version = zversion;
7015 				zversion = NULL;
7016 				/*
7017 				 * We don't clean up zdb here because we
7018 				 * may still need it.  It will get cleaned
7019 				 * up by the main cleanup code.
7020 				 */
7021 			}
7022 
7023 			if (RECURSIONOK(client)) {
7024 				/*
7025 				 * Recurse!
7026 				 */
7027 				if (dns_rdatatype_atparent(type))
7028 					result = query_recurse(client, qtype,
7029 							 client->query.qname,
7030 							 NULL, NULL, resuming);
7031 				else if (dns64)
7032 					result = query_recurse(client,
7033 							 dns_rdatatype_a,
7034 							 client->query.qname,
7035 							 NULL, NULL, resuming);
7036 				else
7037 					result = query_recurse(client, qtype,
7038 							 client->query.qname,
7039 							 fname, rdataset,
7040 							 resuming);
7041 
7042 				if (result == ISC_R_SUCCESS) {
7043 					client->query.attributes |=
7044 						NS_QUERYATTR_RECURSING;
7045 					if (dns64)
7046 						client->query.attributes |=
7047 							NS_QUERYATTR_DNS64;
7048 					if (dns64_exclude)
7049 						client->query.attributes |=
7050 						      NS_QUERYATTR_DNS64EXCLUDE;
7051 				} else if (result == DNS_R_DUPLICATE ||
7052 					 result == DNS_R_DROP)
7053 					QUERY_ERROR(result);
7054 				else
7055 					RECURSE_ERROR(result);
7056 			} else {
7057 				dns_fixedname_init(&fixed);
7058 				dns_name_copy(fname,
7059 					      dns_fixedname_name(&fixed), NULL);
7060 				/*
7061 				 * This is the best answer.
7062 				 */
7063 				client->query.attributes |=
7064 					NS_QUERYATTR_CACHEGLUEOK;
7065 				client->query.gluedb = zdb;
7066 				client->query.isreferral = ISC_TRUE;
7067 				/*
7068 				 * We must ensure NOADDITIONAL is off,
7069 				 * because the generation of
7070 				 * additional data is required in
7071 				 * delegations.
7072 				 */
7073 				client->query.attributes &=
7074 					~NS_QUERYATTR_NOADDITIONAL;
7075 				if (sigrdataset != NULL)
7076 					sigrdatasetp = &sigrdataset;
7077 				else
7078 					sigrdatasetp = NULL;
7079 				query_addrrset(client, &fname,
7080 					       &rdataset, sigrdatasetp,
7081 					       dbuf, DNS_SECTION_AUTHORITY);
7082 				client->query.gluedb = NULL;
7083 				client->query.attributes &=
7084 					~NS_QUERYATTR_CACHEGLUEOK;
7085 				if (WANTDNSSEC(client))
7086 					query_addds(client, db, node, version,
7087 						   dns_fixedname_name(&fixed));
7088 			}
7089 		}
7090 		goto cleanup;
7091 
7092 	case DNS_R_EMPTYNAME:
7093 	case DNS_R_NXRRSET:
7094 	iszone_nxrrset:
7095 		INSIST(is_zone);
7096 
7097 #ifdef dns64_bis_return_excluded_addresses
7098 		if (dns64)
7099 #else
7100 		if (dns64 && !dns64_exclude)
7101 #endif
7102 		{
7103 			/*
7104 			 * Restore the answers from the previous AAAA lookup.
7105 			 */
7106 			if (rdataset != NULL)
7107 				query_putrdataset(client, &rdataset);
7108 			if (sigrdataset != NULL)
7109 				query_putrdataset(client, &sigrdataset);
7110 			rdataset = client->query.dns64_aaaa;
7111 			sigrdataset = client->query.dns64_sigaaaa;
7112 			client->query.dns64_aaaa = NULL;
7113 			client->query.dns64_sigaaaa = NULL;
7114 			if (fname == NULL) {
7115 				dbuf = query_getnamebuf(client);
7116 				if (dbuf == NULL) {
7117 					QUERY_ERROR(DNS_R_SERVFAIL);
7118 					goto cleanup;
7119 				}
7120 				fname = query_newname(client, dbuf, &b);
7121 				if (fname == NULL) {
7122 					QUERY_ERROR(DNS_R_SERVFAIL);
7123 					goto cleanup;
7124 				}
7125 			}
7126 			dns_name_copy(client->query.qname, fname, NULL);
7127 			dns64 = ISC_FALSE;
7128 #ifdef dns64_bis_return_excluded_addresses
7129 			/*
7130 			 * Resume the diverted processing of the AAAA response?
7131 			 */
7132 			if (dns64_excluded)
7133 				break;
7134 #endif
7135 		} else if (result == DNS_R_NXRRSET &&
7136 			   !ISC_LIST_EMPTY(client->view->dns64) &&
7137 			   client->message->rdclass == dns_rdataclass_in &&
7138 			   qtype == dns_rdatatype_aaaa)
7139 		{
7140 			/*
7141 			 * Look to see if there are A records for this
7142 			 * name.
7143 			 */
7144 			INSIST(client->query.dns64_aaaa == NULL);
7145 			INSIST(client->query.dns64_sigaaaa == NULL);
7146 			client->query.dns64_aaaa = rdataset;
7147 			client->query.dns64_sigaaaa = sigrdataset;
7148 			client->query.dns64_ttl = dns64_ttl(db, version);
7149 			query_releasename(client, &fname);
7150 			dns_db_detachnode(db, &node);
7151 			rdataset = NULL;
7152 			sigrdataset = NULL;
7153 			type = qtype = dns_rdatatype_a;
7154 			rpz_st = client->query.rpz_st;
7155 			if (rpz_st != NULL) {
7156 				/*
7157 				 * Arrange for RPZ rewriting of any A records.
7158 				 */
7159 				if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0)
7160 					is_zone = rpz_st->q.is_zone;
7161 				rpz_st_clear(client);
7162 			}
7163 			dns64 = ISC_TRUE;
7164 			goto db_find;
7165 		}
7166 
7167 		/*
7168 		 * Look for a NSEC3 record if we don't have a NSEC record.
7169 		 */
7170  nxrrset_rrsig:
7171 		if (redirected)
7172 			goto cleanup;
7173 		if (!dns_rdataset_isassociated(rdataset) &&
7174 		     WANTDNSSEC(client)) {
7175 			if ((fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
7176 				dns_name_t *found;
7177 				dns_name_t *qname;
7178 
7179 				dns_fixedname_init(&fixed);
7180 				found = dns_fixedname_name(&fixed);
7181 				qname = client->query.qname;
7182 
7183 				query_findclosestnsec3(qname, db, version,
7184 						       client, rdataset,
7185 						       sigrdataset, fname,
7186 						       ISC_TRUE, found);
7187 				/*
7188 				 * Did we find the closest provable encloser
7189 				 * instead? If so add the nearest to the
7190 				 * closest provable encloser.
7191 				 */
7192 				if (dns_rdataset_isassociated(rdataset) &&
7193 				    !dns_name_equal(qname, found) &&
7194 				    !(ns_g_nonearest &&
7195 				      qtype != dns_rdatatype_ds))
7196 				{
7197 					unsigned int count;
7198 					unsigned int skip;
7199 
7200 					/*
7201 					 * Add the closest provable encloser.
7202 					 */
7203 					query_addrrset(client, &fname,
7204 						       &rdataset, &sigrdataset,
7205 						       dbuf,
7206 						       DNS_SECTION_AUTHORITY);
7207 
7208 					count = dns_name_countlabels(found)
7209 							 + 1;
7210 					skip = dns_name_countlabels(qname) -
7211 							 count;
7212 					dns_name_getlabelsequence(qname, skip,
7213 								  count,
7214 								  found);
7215 
7216 					fixfname(client, &fname, &dbuf, &b);
7217 					fixrdataset(client, &rdataset);
7218 					fixrdataset(client, &sigrdataset);
7219 					if (fname == NULL ||
7220 					    rdataset == NULL ||
7221 					    sigrdataset == NULL) {
7222 						QUERY_ERROR(DNS_R_SERVFAIL);
7223 						goto cleanup;
7224 					}
7225 					/*
7226 					 * 'nearest' doesn't exist so
7227 					 * 'exist' is set to ISC_FALSE.
7228 					 */
7229 					query_findclosestnsec3(found, db,
7230 							       version,
7231 							       client,
7232 							       rdataset,
7233 							       sigrdataset,
7234 							       fname,
7235 							       ISC_FALSE,
7236 							       NULL);
7237 				}
7238 			} else {
7239 				query_releasename(client, &fname);
7240 				query_addwildcardproof(client, db, version,
7241 						       client->query.qname,
7242 						       ISC_FALSE, ISC_TRUE);
7243 			}
7244 		}
7245 		if (dns_rdataset_isassociated(rdataset)) {
7246 			/*
7247 			 * If we've got a NSEC record, we need to save the
7248 			 * name now because we're going call query_addsoa()
7249 			 * below, and it needs to use the name buffer.
7250 			 */
7251 			query_keepname(client, fname, dbuf);
7252 		} else if (fname != NULL) {
7253 			/*
7254 			 * We're not going to use fname, and need to release
7255 			 * our hold on the name buffer so query_addsoa()
7256 			 * may use it.
7257 			 */
7258 			query_releasename(client, &fname);
7259 		}
7260 
7261 		/*
7262 		 * Add SOA to the additional section if generated by a RPZ
7263 		 * rewrite.
7264 		 */
7265 		associated = dns_rdataset_isassociated(rdataset);
7266 		section = nxrewrite ? DNS_SECTION_ADDITIONAL :
7267 				      DNS_SECTION_AUTHORITY;
7268 
7269 		result = query_addsoa(client, db, version, ISC_UINT32_MAX,
7270 				      associated, section);
7271 		if (result != ISC_R_SUCCESS) {
7272 			QUERY_ERROR(result);
7273 			goto cleanup;
7274 		}
7275 
7276 		/*
7277 		 * Add NSEC record if we found one.
7278 		 */
7279 		if (WANTDNSSEC(client)) {
7280 			if (dns_rdataset_isassociated(rdataset))
7281 				query_addnxrrsetnsec(client, db, version,
7282 						     &fname, &rdataset,
7283 						     &sigrdataset);
7284 		}
7285 		goto cleanup;
7286 
7287 	case DNS_R_EMPTYWILD:
7288 		empty_wild = ISC_TRUE;
7289 		/* FALLTHROUGH */
7290 
7291 	case DNS_R_NXDOMAIN:
7292 		INSIST(is_zone);
7293 		if (!empty_wild) {
7294 			tresult = redirect(client, fname, rdataset, &node,
7295 					   &db, &version, type);
7296 			if (tresult == ISC_R_SUCCESS)
7297 				break;
7298 			if (tresult == DNS_R_NXRRSET) {
7299 				redirected = ISC_TRUE;
7300 				goto iszone_nxrrset;
7301 			}
7302 			if (tresult == DNS_R_NCACHENXRRSET) {
7303 				redirected = ISC_TRUE;
7304 				is_zone = ISC_FALSE;
7305 				goto ncache_nxrrset;
7306 			}
7307 		}
7308 		if (dns_rdataset_isassociated(rdataset)) {
7309 			/*
7310 			 * If we've got a NSEC record, we need to save the
7311 			 * name now because we're going call query_addsoa()
7312 			 * below, and it needs to use the name buffer.
7313 			 */
7314 			query_keepname(client, fname, dbuf);
7315 		} else if (fname != NULL) {
7316 			/*
7317 			 * We're not going to use fname, and need to release
7318 			 * our hold on the name buffer so query_addsoa()
7319 			 * may use it.
7320 			 */
7321 			query_releasename(client, &fname);
7322 		}
7323 
7324 		/*
7325 		 * Add SOA to the additional section if generated by a
7326 		 * RPZ rewrite.
7327 		 *
7328 		 * If the query was for a SOA record force the
7329 		 * ttl to zero so that it is possible for clients to find
7330 		 * the containing zone of an arbitrary name with a stub
7331 		 * resolver and not have it cached.
7332 		 */
7333 		associated = dns_rdataset_isassociated(rdataset);
7334 		section = nxrewrite ? DNS_SECTION_ADDITIONAL :
7335 				      DNS_SECTION_AUTHORITY;
7336 		ttl = ISC_UINT32_MAX;
7337 		if (!nxrewrite && qtype == dns_rdatatype_soa &&
7338 		    zone != NULL && dns_zone_getzeronosoattl(zone))
7339 			ttl = 0;
7340 		result = query_addsoa(client, db, version, ttl, associated,
7341 				      section);
7342 		if (result != ISC_R_SUCCESS) {
7343 			QUERY_ERROR(result);
7344 			goto cleanup;
7345 		}
7346 
7347 		if (WANTDNSSEC(client)) {
7348 			/*
7349 			 * Add NSEC record if we found one.
7350 			 */
7351 			if (dns_rdataset_isassociated(rdataset))
7352 				query_addrrset(client, &fname, &rdataset,
7353 					       &sigrdataset,
7354 					       NULL, DNS_SECTION_AUTHORITY);
7355 			query_addwildcardproof(client, db, version,
7356 					       client->query.qname, ISC_FALSE,
7357 					       ISC_FALSE);
7358 		}
7359 
7360 		/*
7361 		 * Set message rcode.
7362 		 */
7363 		if (empty_wild)
7364 			client->message->rcode = dns_rcode_noerror;
7365 		else
7366 			client->message->rcode = dns_rcode_nxdomain;
7367 		goto cleanup;
7368 
7369 	case DNS_R_NCACHENXDOMAIN:
7370 		tresult = redirect(client, fname, rdataset, &node,
7371 				   &db, &version, type);
7372 		if (tresult == ISC_R_SUCCESS)
7373 			break;
7374 		if (tresult == DNS_R_NXRRSET) {
7375 			redirected = ISC_TRUE;
7376 			is_zone = ISC_TRUE;
7377 			goto iszone_nxrrset;
7378 		}
7379 		if (tresult == DNS_R_NCACHENXRRSET) {
7380 			redirected = ISC_TRUE;
7381 			result = tresult;
7382 			goto ncache_nxrrset;
7383 		}
7384 		/* FALLTHROUGH */
7385 
7386 	case DNS_R_NCACHENXRRSET:
7387 	ncache_nxrrset:
7388 		INSIST(!is_zone);
7389 		authoritative = ISC_FALSE;
7390 		/*
7391 		 * Set message rcode, if required.
7392 		 */
7393 		if (result == DNS_R_NCACHENXDOMAIN)
7394 			client->message->rcode = dns_rcode_nxdomain;
7395 		/*
7396 		 * Look for RFC 1918 leakage from Internet.
7397 		 */
7398 		if (result == DNS_R_NCACHENXDOMAIN &&
7399 		    qtype == dns_rdatatype_ptr &&
7400 		    client->message->rdclass == dns_rdataclass_in &&
7401 		    dns_name_countlabels(fname) == 7)
7402 			warn_rfc1918(client, fname, rdataset);
7403 
7404 #ifdef dns64_bis_return_excluded_addresses
7405 		if (dns64)
7406 #else
7407 		if (dns64 && !dns64_exclude)
7408 #endif
7409 		{
7410 			/*
7411 			 * Restore the answers from the previous AAAA lookup.
7412 			 */
7413 			if (rdataset != NULL)
7414 				query_putrdataset(client, &rdataset);
7415 			if (sigrdataset != NULL)
7416 				query_putrdataset(client, &sigrdataset);
7417 			rdataset = client->query.dns64_aaaa;
7418 			sigrdataset = client->query.dns64_sigaaaa;
7419 			client->query.dns64_aaaa = NULL;
7420 			client->query.dns64_sigaaaa = NULL;
7421 			if (fname == NULL) {
7422 				dbuf = query_getnamebuf(client);
7423 				if (dbuf == NULL) {
7424 					QUERY_ERROR(DNS_R_SERVFAIL);
7425 					goto cleanup;
7426 				}
7427 				fname = query_newname(client, dbuf, &b);
7428 				if (fname == NULL) {
7429 					QUERY_ERROR(DNS_R_SERVFAIL);
7430 					goto cleanup;
7431 				}
7432 			}
7433 			dns_name_copy(client->query.qname, fname, NULL);
7434 			dns64 = ISC_FALSE;
7435 #ifdef dns64_bis_return_excluded_addresses
7436 			if (dns64_excluded)
7437 				break;
7438 #endif
7439 		} else if (result == DNS_R_NCACHENXRRSET &&
7440 			   !ISC_LIST_EMPTY(client->view->dns64) &&
7441 			   client->message->rdclass == dns_rdataclass_in &&
7442 			   qtype == dns_rdatatype_aaaa)
7443 		{
7444 			/*
7445 			 * Look to see if there are A records for this
7446 			 * name.
7447 			 */
7448 			INSIST(client->query.dns64_aaaa == NULL);
7449 			INSIST(client->query.dns64_sigaaaa == NULL);
7450 			client->query.dns64_aaaa = rdataset;
7451 			client->query.dns64_sigaaaa = sigrdataset;
7452 			/*
7453 			 * If the ttl is zero we need to workout if we have just
7454 			 * decremented to zero or if there was no negative cache
7455 			 * ttl in the answer.
7456 			 */
7457 			if (rdataset->ttl != 0)
7458 				client->query.dns64_ttl = rdataset->ttl;
7459 			else if (dns_rdataset_first(rdataset) == ISC_R_SUCCESS)
7460 				client->query.dns64_ttl = 0;
7461 			query_releasename(client, &fname);
7462 			dns_db_detachnode(db, &node);
7463 			rdataset = NULL;
7464 			sigrdataset = NULL;
7465 			fname = NULL;
7466 			type = qtype = dns_rdatatype_a;
7467 			rpz_st = client->query.rpz_st;
7468 			if (rpz_st != NULL) {
7469 				/*
7470 				 * Arrange for RPZ rewriting of any A records.
7471 				 */
7472 				if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0)
7473 					is_zone = rpz_st->q.is_zone;
7474 				rpz_st_clear(client);
7475 			}
7476 			dns64 = ISC_TRUE;
7477 			goto db_find;
7478 		}
7479 
7480 		/*
7481 		 * We don't call query_addrrset() because we don't need any
7482 		 * of its extra features (and things would probably break!).
7483 		 */
7484 		query_keepname(client, fname, dbuf);
7485 		dns_message_addname(client->message, fname,
7486 				    DNS_SECTION_AUTHORITY);
7487 		ISC_LIST_APPEND(fname->list, rdataset, link);
7488 		fname = NULL;
7489 		rdataset = NULL;
7490 		goto cleanup;
7491 
7492 	case DNS_R_CNAME:
7493 		/*
7494 		 * Keep a copy of the rdataset.  We have to do this because
7495 		 * query_addrrset may clear 'rdataset' (to prevent the
7496 		 * cleanup code from cleaning it up).
7497 		 */
7498 		trdataset = rdataset;
7499 		/*
7500 		 * Add the CNAME to the answer section.
7501 		 */
7502 		if (sigrdataset != NULL)
7503 			sigrdatasetp = &sigrdataset;
7504 		else
7505 			sigrdatasetp = NULL;
7506 		if (WANTDNSSEC(client) &&
7507 		    (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
7508 		{
7509 			dns_fixedname_init(&wildcardname);
7510 			dns_name_copy(fname, dns_fixedname_name(&wildcardname),
7511 				      NULL);
7512 			need_wildcardproof = ISC_TRUE;
7513 		}
7514 		if (NOQNAME(rdataset) && WANTDNSSEC(client))
7515 			noqname = rdataset;
7516 		else
7517 			noqname = NULL;
7518 		if (!is_zone && RECURSIONOK(client))
7519 			query_prefetch(client, fname, rdataset);
7520 		query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
7521 			       DNS_SECTION_ANSWER);
7522 		if (noqname != NULL)
7523 			query_addnoqnameproof(client, noqname);
7524 		/*
7525 		 * We set the PARTIALANSWER attribute so that if anything goes
7526 		 * wrong later on, we'll return what we've got so far.
7527 		 */
7528 		client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
7529 		/*
7530 		 * Reset qname to be the target name of the CNAME and restart
7531 		 * the query.
7532 		 */
7533 		tname = NULL;
7534 		result = dns_message_gettempname(client->message, &tname);
7535 		if (result != ISC_R_SUCCESS)
7536 			goto cleanup;
7537 		result = dns_rdataset_first(trdataset);
7538 		if (result != ISC_R_SUCCESS) {
7539 			dns_message_puttempname(client->message, &tname);
7540 			goto cleanup;
7541 		}
7542 		dns_rdataset_current(trdataset, &rdata);
7543 		result = dns_rdata_tostruct(&rdata, &cname, NULL);
7544 		dns_rdata_reset(&rdata);
7545 		if (result != ISC_R_SUCCESS) {
7546 			dns_message_puttempname(client->message, &tname);
7547 			goto cleanup;
7548 		}
7549 		dns_name_init(tname, NULL);
7550 		result = dns_name_dup(&cname.cname, client->mctx, tname);
7551 		if (result != ISC_R_SUCCESS) {
7552 			dns_message_puttempname(client->message, &tname);
7553 			dns_rdata_freestruct(&cname);
7554 			goto cleanup;
7555 		}
7556 		dns_rdata_freestruct(&cname);
7557 		ns_client_qnamereplace(client, tname);
7558 		want_restart = ISC_TRUE;
7559 		if (!WANTRECURSION(client))
7560 			options |= DNS_GETDB_NOLOG;
7561 		goto addauth;
7562 	case DNS_R_DNAME:
7563 		/*
7564 		 * Compare the current qname to the found name.  We need
7565 		 * to know how many labels and bits are in common because
7566 		 * we're going to have to split qname later on.
7567 		 */
7568 		namereln = dns_name_fullcompare(client->query.qname, fname,
7569 						&order, &nlabels);
7570 		INSIST(namereln == dns_namereln_subdomain);
7571 		/*
7572 		 * Keep a copy of the rdataset.  We have to do this because
7573 		 * query_addrrset may clear 'rdataset' (to prevent the
7574 		 * cleanup code from cleaning it up).
7575 		 */
7576 		trdataset = rdataset;
7577 		/*
7578 		 * Add the DNAME to the answer section.
7579 		 */
7580 		if (sigrdataset != NULL)
7581 			sigrdatasetp = &sigrdataset;
7582 		else
7583 			sigrdatasetp = NULL;
7584 		if (WANTDNSSEC(client) &&
7585 		    (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
7586 		{
7587 			dns_fixedname_init(&wildcardname);
7588 			dns_name_copy(fname, dns_fixedname_name(&wildcardname),
7589 				      NULL);
7590 			need_wildcardproof = ISC_TRUE;
7591 		}
7592 		if (!is_zone && RECURSIONOK(client))
7593 			query_prefetch(client, fname, rdataset);
7594 		query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
7595 			       DNS_SECTION_ANSWER);
7596 		/*
7597 		 * We set the PARTIALANSWER attribute so that if anything goes
7598 		 * wrong later on, we'll return what we've got so far.
7599 		 */
7600 		client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
7601 		/*
7602 		 * Get the target name of the DNAME.
7603 		 */
7604 		tname = NULL;
7605 		result = dns_message_gettempname(client->message, &tname);
7606 		if (result != ISC_R_SUCCESS)
7607 			goto cleanup;
7608 		result = dns_rdataset_first(trdataset);
7609 		if (result != ISC_R_SUCCESS) {
7610 			dns_message_puttempname(client->message, &tname);
7611 			goto cleanup;
7612 		}
7613 		dns_rdataset_current(trdataset, &rdata);
7614 		result = dns_rdata_tostruct(&rdata, &dname, NULL);
7615 		dns_rdata_reset(&rdata);
7616 		if (result != ISC_R_SUCCESS) {
7617 			dns_message_puttempname(client->message, &tname);
7618 			goto cleanup;
7619 		}
7620 		dns_name_clone(&dname.dname, tname);
7621 		dns_rdata_freestruct(&dname);
7622 		/*
7623 		 * Construct the new qname consisting of
7624 		 * <found name prefix>.<dname target>
7625 		 */
7626 		dns_fixedname_init(&fixed);
7627 		prefix = dns_fixedname_name(&fixed);
7628 		dns_name_split(client->query.qname, nlabels, prefix, NULL);
7629 		INSIST(fname == NULL);
7630 		dbuf = query_getnamebuf(client);
7631 		if (dbuf == NULL) {
7632 			dns_message_puttempname(client->message, &tname);
7633 			goto cleanup;
7634 		}
7635 		fname = query_newname(client, dbuf, &b);
7636 		if (fname == NULL) {
7637 			dns_message_puttempname(client->message, &tname);
7638 			goto cleanup;
7639 		}
7640 		result = dns_name_concatenate(prefix, tname, fname, NULL);
7641 		dns_message_puttempname(client->message, &tname);
7642 
7643 		/*
7644 		 * RFC2672, section 4.1, subsection 3c says
7645 		 * we should return YXDOMAIN if the constructed
7646 		 * name would be too long.
7647 		 */
7648 		if (result == DNS_R_NAMETOOLONG)
7649 			client->message->rcode = dns_rcode_yxdomain;
7650 		if (result != ISC_R_SUCCESS)
7651 			goto cleanup;
7652 
7653 		query_keepname(client, fname, dbuf);
7654 		/*
7655 		 * Synthesize a CNAME consisting of
7656 		 *   <old qname> <dname ttl> CNAME <new qname>
7657 		 *	    with <dname trust value>
7658 		 *
7659 		 * Synthesize a CNAME so old old clients that don't understand
7660 		 * DNAME can chain.
7661 		 *
7662 		 * We do not try to synthesize a signature because we hope
7663 		 * that security aware servers will understand DNAME.  Also,
7664 		 * even if we had an online key, making a signature
7665 		 * on-the-fly is costly, and not really legitimate anyway
7666 		 * since the synthesized CNAME is NOT in the zone.
7667 		 */
7668 		result = query_add_cname(client, client->query.qname, fname,
7669 					 trdataset->trust, trdataset->ttl);
7670 		if (result != ISC_R_SUCCESS)
7671 			goto cleanup;
7672 		/*
7673 		 * Switch to the new qname and restart.
7674 		 */
7675 		ns_client_qnamereplace(client, fname);
7676 		fname = NULL;
7677 		want_restart = ISC_TRUE;
7678 		if (!WANTRECURSION(client))
7679 			options |= DNS_GETDB_NOLOG;
7680 		goto addauth;
7681 	default:
7682 		/*
7683 		 * Something has gone wrong.
7684 		 */
7685 		QUERY_ERROR(DNS_R_SERVFAIL);
7686 		goto cleanup;
7687 	}
7688 
7689 	if (WANTDNSSEC(client) &&
7690 	    (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
7691 	{
7692 		dns_fixedname_init(&wildcardname);
7693 		dns_name_copy(fname, dns_fixedname_name(&wildcardname), NULL);
7694 		need_wildcardproof = ISC_TRUE;
7695 	}
7696 
7697 #ifdef ALLOW_FILTER_AAAA
7698 	/*
7699 	 * The filter-aaaa-on-v4 option should suppress AAAAs for IPv4
7700 	 * clients if there is an A; filter-aaaa-on-v6 option does the same
7701 	 * for IPv6 clients.
7702 	 */
7703 	client->filter_aaaa = dns_aaaa_ok;
7704 	if (client->view->v4_aaaa != dns_aaaa_ok ||
7705 	    client->view->v6_aaaa != dns_aaaa_ok)
7706 	{
7707 		result = ns_client_checkaclsilent(client, NULL,
7708 						  client->view->aaaa_acl,
7709 						  ISC_TRUE);
7710 		if (result == ISC_R_SUCCESS &&
7711 		    client->view->v4_aaaa != dns_aaaa_ok &&
7712 		    is_v4_client(client))
7713 			client->filter_aaaa = client->view->v4_aaaa;
7714 		else if (result == ISC_R_SUCCESS &&
7715 			 client->view->v6_aaaa != dns_aaaa_ok &&
7716 			 is_v6_client(client))
7717 			client->filter_aaaa = client->view->v6_aaaa;
7718 	}
7719 
7720 #endif
7721 
7722 	if (type == dns_rdatatype_any) {
7723 #ifdef ALLOW_FILTER_AAAA
7724 		isc_boolean_t have_aaaa, have_a, have_sig;
7725 
7726 		/*
7727 		 * If we are not authoritative, assume there is a A
7728 		 * even in if it is not in our cache.  This assumption could
7729 		 * be wrong but it is a good bet.
7730 		 */
7731 		have_aaaa = ISC_FALSE;
7732 		have_a = !authoritative;
7733 		have_sig = ISC_FALSE;
7734 #endif
7735 		/*
7736 		 * XXXRTH  Need to handle zonecuts with special case
7737 		 * code.
7738 		 */
7739 		n = 0;
7740 		rdsiter = NULL;
7741 		result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
7742 		if (result != ISC_R_SUCCESS) {
7743 			QUERY_ERROR(DNS_R_SERVFAIL);
7744 			goto cleanup;
7745 		}
7746 
7747 		/*
7748 		 * Calling query_addrrset() with a non-NULL dbuf is going
7749 		 * to either keep or release the name.  We don't want it to
7750 		 * release fname, since we may have to call query_addrrset()
7751 		 * more than once.  That means we have to call query_keepname()
7752 		 * now, and pass a NULL dbuf to query_addrrset().
7753 		 *
7754 		 * If we do a query_addrrset() below, we must set fname to
7755 		 * NULL before leaving this block, otherwise we might try to
7756 		 * cleanup fname even though we're using it!
7757 		 */
7758 		query_keepname(client, fname, dbuf);
7759 		tname = fname;
7760 		result = dns_rdatasetiter_first(rdsiter);
7761 		while (result == ISC_R_SUCCESS) {
7762 			dns_rdatasetiter_current(rdsiter, rdataset);
7763 #ifdef ALLOW_FILTER_AAAA
7764 			/*
7765 			 * Notice the presence of A and AAAAs so
7766 			 * that AAAAs can be hidden from IPv4 clients.
7767 			 */
7768 			if (client->filter_aaaa != dns_aaaa_ok) {
7769 				if (rdataset->type == dns_rdatatype_aaaa)
7770 					have_aaaa = ISC_TRUE;
7771 				else if (rdataset->type == dns_rdatatype_a)
7772 					have_a = ISC_TRUE;
7773 			}
7774 #endif
7775 			if (is_zone && qtype == dns_rdatatype_any &&
7776 			    !dns_db_issecure(db) &&
7777 			    dns_rdatatype_isdnssec(rdataset->type)) {
7778 				/*
7779 				 * The zone is transitioning from insecure
7780 				 * to secure. Hide the dnssec records from
7781 				 * ANY queries.
7782 				 */
7783 				dns_rdataset_disassociate(rdataset);
7784 			} else if ((qtype == dns_rdatatype_any ||
7785 			     rdataset->type == qtype) && rdataset->type != 0) {
7786 #ifdef ALLOW_FILTER_AAAA
7787 				if (dns_rdatatype_isdnssec(rdataset->type))
7788 					have_sig = ISC_TRUE;
7789 #endif
7790 				if (NOQNAME(rdataset) && WANTDNSSEC(client))
7791 					noqname = rdataset;
7792 				else
7793 					noqname = NULL;
7794 				rpz_st = client->query.rpz_st;
7795 				if (rpz_st != NULL)
7796 					rdataset->ttl = ISC_MIN(rdataset->ttl,
7797 							    rpz_st->m.ttl);
7798 				if (!is_zone && RECURSIONOK(client)) {
7799 					dns_name_t *name;
7800 					name = (fname != NULL) ? fname : tname;
7801 					query_prefetch(client, name, rdataset);
7802 				}
7803 				query_addrrset(client,
7804 					       fname != NULL ? &fname : &tname,
7805 					       &rdataset, NULL,
7806 					       NULL, DNS_SECTION_ANSWER);
7807 				if (noqname != NULL)
7808 					query_addnoqnameproof(client, noqname);
7809 				n++;
7810 				INSIST(tname != NULL);
7811 				/*
7812 				 * rdataset is non-NULL only in certain
7813 				 * pathological cases involving DNAMEs.
7814 				 */
7815 				if (rdataset != NULL)
7816 					query_putrdataset(client, &rdataset);
7817 				rdataset = query_newrdataset(client);
7818 				if (rdataset == NULL)
7819 					break;
7820 			} else {
7821 				/*
7822 				 * We're not interested in this rdataset.
7823 				 */
7824 				dns_rdataset_disassociate(rdataset);
7825 			}
7826 			result = dns_rdatasetiter_next(rdsiter);
7827 		}
7828 
7829 #ifdef ALLOW_FILTER_AAAA
7830 		/*
7831 		 * Filter AAAAs if there is an A and there is no signature
7832 		 * or we are supposed to break DNSSEC.
7833 		 */
7834 		if (client->filter_aaaa == dns_aaaa_break_dnssec)
7835 			client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
7836 		else if (client->filter_aaaa != dns_aaaa_ok &&
7837 			 have_aaaa && have_a &&
7838 			 (!have_sig || !WANTDNSSEC(client)))
7839 			  client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
7840 #endif
7841 		if (fname != NULL)
7842 			dns_message_puttempname(client->message, &fname);
7843 
7844 		if (n == 0) {
7845 			/*
7846 			 * No matching rdatasets found in cache. If we were
7847 			 * searching for RRSIG/SIG, that's probably okay;
7848 			 * otherwise this is an error condition.
7849 			 */
7850 			if ((qtype == dns_rdatatype_rrsig ||
7851 			     qtype == dns_rdatatype_sig) &&
7852 			    result == ISC_R_NOMORE) {
7853 				if (!is_zone) {
7854 					authoritative = ISC_FALSE;
7855 					dns_rdatasetiter_destroy(&rdsiter);
7856 					client->attributes &= ~NS_CLIENTATTR_RA;
7857 					goto addauth;
7858 				}
7859 
7860 				if (qtype == dns_rdatatype_rrsig &&
7861 				    dns_db_issecure(db)) {
7862 					char namebuf[DNS_NAME_FORMATSIZE];
7863 					dns_name_format(client->query.qname,
7864 							namebuf,
7865 							sizeof(namebuf));
7866 					ns_client_log(client,
7867 						      DNS_LOGCATEGORY_DNSSEC,
7868 						      NS_LOGMODULE_QUERY,
7869 						      ISC_LOG_WARNING,
7870 						      "missing signature "
7871 						      "for %s", namebuf);
7872 				}
7873 
7874 				dns_rdatasetiter_destroy(&rdsiter);
7875 				fname = query_newname(client, dbuf, &b);
7876 				goto nxrrset_rrsig;
7877 			} else
7878 				result = DNS_R_SERVFAIL;
7879 		}
7880 
7881 		dns_rdatasetiter_destroy(&rdsiter);
7882 		if (result != ISC_R_NOMORE) {
7883 			QUERY_ERROR(DNS_R_SERVFAIL);
7884 			goto cleanup;
7885 		}
7886 	} else {
7887 		/*
7888 		 * This is the "normal" case -- an ordinary question to which
7889 		 * we know the answer.
7890 		 */
7891 
7892 #ifdef ALLOW_FILTER_AAAA
7893 		/*
7894 		 * Optionally hide AAAAs from IPv4 clients if there is an A.
7895 		 * We add the AAAAs now, but might refuse to render them later
7896 		 * after DNSSEC is figured out.
7897 		 * This could be more efficient, but the whole idea is
7898 		 * so fundamentally wrong, unavoidably inaccurate, and
7899 		 * unneeded that it is best to keep it as short as possible.
7900 		 */
7901 		if (client->filter_aaaa == dns_aaaa_break_dnssec ||
7902 		    (client->filter_aaaa == dns_aaaa_filter &&
7903 		     (!WANTDNSSEC(client) || sigrdataset == NULL ||
7904 		     !dns_rdataset_isassociated(sigrdataset))))
7905 		{
7906 			if (qtype == dns_rdatatype_aaaa) {
7907 				trdataset = query_newrdataset(client);
7908 				result = dns_db_findrdataset(db, node, version,
7909 							     dns_rdatatype_a, 0,
7910 							     client->now,
7911 							     trdataset, NULL);
7912 				if (dns_rdataset_isassociated(trdataset))
7913 					dns_rdataset_disassociate(trdataset);
7914 				query_putrdataset(client, &trdataset);
7915 
7916 				/*
7917 				 * We have an AAAA but the A is not in our cache.
7918 				 * Assume any result other than DNS_R_DELEGATION
7919 				 * or ISC_R_NOTFOUND means there is no A and
7920 				 * so AAAAs are ok.
7921 				 * Assume there is no A if we can't recurse
7922 				 * for this client, although that could be
7923 				 * the wrong answer. What else can we do?
7924 				 * Besides, that we have the AAAA and are using
7925 				 * this mechanism suggests that we care more
7926 				 * about As than AAAAs and would have cached
7927 				 * the A if it existed.
7928 				 */
7929 				if (result == ISC_R_SUCCESS) {
7930 					client->attributes |=
7931 						    NS_CLIENTATTR_FILTER_AAAA;
7932 
7933 				} else if (authoritative ||
7934 					   !RECURSIONOK(client) ||
7935 					   (result != DNS_R_DELEGATION &&
7936 					    result != ISC_R_NOTFOUND)) {
7937 					client->attributes &=
7938 						    ~NS_CLIENTATTR_FILTER_AAAA;
7939 				} else {
7940 					/*
7941 					 * This is an ugly kludge to recurse
7942 					 * for the A and discard the result.
7943 					 *
7944 					 * Continue to add the AAAA now.
7945 					 * We'll make a note to not render it
7946 					 * if the recursion for the A succeeds.
7947 					 */
7948 					result = query_recurse(client,
7949 							dns_rdatatype_a,
7950 							client->query.qname,
7951 							NULL, NULL, resuming);
7952 					if (result == ISC_R_SUCCESS) {
7953 					    client->attributes |=
7954 						    NS_CLIENTATTR_FILTER_AAAA_RC;
7955 					    client->query.attributes |=
7956 							NS_QUERYATTR_RECURSING;
7957 					}
7958 				}
7959 
7960 			} else if (qtype == dns_rdatatype_a &&
7961 				   (client->attributes &
7962 					    NS_CLIENTATTR_FILTER_AAAA_RC) != 0) {
7963 				client->attributes &=
7964 					    ~NS_CLIENTATTR_FILTER_AAAA_RC;
7965 				client->attributes |=
7966 					    NS_CLIENTATTR_FILTER_AAAA;
7967 				dns_rdataset_disassociate(rdataset);
7968 				if (sigrdataset != NULL &&
7969 				    dns_rdataset_isassociated(sigrdataset))
7970 					dns_rdataset_disassociate(sigrdataset);
7971 				goto cleanup;
7972 			}
7973 		}
7974 #endif
7975 		/*
7976 		 * Check to see if the AAAA RRset has non-excluded addresses
7977 		 * in it.  If not look for a A RRset.
7978 		 */
7979 		INSIST(client->query.dns64_aaaaok == NULL);
7980 
7981 		if (qtype == dns_rdatatype_aaaa && !dns64_exclude &&
7982 		    !ISC_LIST_EMPTY(client->view->dns64) &&
7983 		    client->message->rdclass == dns_rdataclass_in &&
7984 		    !dns64_aaaaok(client, rdataset, sigrdataset)) {
7985 			/*
7986 			 * Look to see if there are A records for this
7987 			 * name.
7988 			 */
7989 			client->query.dns64_aaaa = rdataset;
7990 			client->query.dns64_sigaaaa = sigrdataset;
7991 			client->query.dns64_ttl = rdataset->ttl;
7992 			query_releasename(client, &fname);
7993 			dns_db_detachnode(db, &node);
7994 			rdataset = NULL;
7995 			sigrdataset = NULL;
7996 			type = qtype = dns_rdatatype_a;
7997 			rpz_st = client->query.rpz_st;
7998 			if (rpz_st != NULL) {
7999 				/*
8000 				 * Arrange for RPZ rewriting of any A records.
8001 				 */
8002 				if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0)
8003 					is_zone = rpz_st->q.is_zone;
8004 				rpz_st_clear(client);
8005 			}
8006 			dns64_exclude = dns64 = ISC_TRUE;
8007 			goto db_find;
8008 		}
8009 
8010 		if (sigrdataset != NULL)
8011 			sigrdatasetp = &sigrdataset;
8012 		else
8013 			sigrdatasetp = NULL;
8014 		if (NOQNAME(rdataset) && WANTDNSSEC(client))
8015 			noqname = rdataset;
8016 		else
8017 			noqname = NULL;
8018 		/*
8019 		 * BIND 8 priming queries need the additional section.
8020 		 */
8021 		if (is_zone && qtype == dns_rdatatype_ns &&
8022 		    dns_name_equal(client->query.qname, dns_rootname))
8023 			client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL;
8024 
8025 		/*
8026 		 * Return the time to expire for slave zones.
8027 		 */
8028 		if (zone != NULL) {
8029 			dns_zone_t *raw = NULL, *mayberaw;
8030 
8031 			if (is_zone)
8032 				dns_zone_getraw(zone, &raw);
8033 			mayberaw = (raw != NULL) ? raw : zone;
8034 
8035 			if (is_zone && qtype == dns_rdatatype_soa &&
8036 			    ((client->attributes &
8037 			      NS_CLIENTATTR_WANTEXPIRE) != 0) &&
8038 			    client->query.restarts == 0 &&
8039 			    dns_zone_gettype(mayberaw) == dns_zone_slave)
8040 			{
8041 				isc_time_t expiretime;
8042 				isc_uint32_t secs;
8043 				dns_zone_getexpiretime(zone, &expiretime);
8044 				secs = isc_time_seconds(&expiretime);
8045 				if (secs >= client->now &&
8046 				    result == ISC_R_SUCCESS) {
8047 					client->attributes |=
8048 						NS_CLIENTATTR_HAVEEXPIRE;
8049 					client->expire = secs - client->now;
8050 				}
8051 			}
8052 			if (raw != NULL)
8053 				dns_zone_detach(&raw);
8054 		}
8055 
8056 		if (dns64) {
8057 			qtype = type = dns_rdatatype_aaaa;
8058 			result = query_dns64(client, &fname, rdataset,
8059 					     sigrdataset, dbuf,
8060 					     DNS_SECTION_ANSWER);
8061 			dns_rdataset_disassociate(rdataset);
8062 			dns_message_puttemprdataset(client->message, &rdataset);
8063 			if (result == ISC_R_NOMORE) {
8064 #ifndef dns64_bis_return_excluded_addresses
8065 				if (dns64_exclude) {
8066 					if (!is_zone)
8067 						goto cleanup;
8068 					/*
8069 					 * Add a fake SOA record.
8070 					 */
8071 					(void)query_addsoa(client, db, version,
8072 							   600, ISC_FALSE,
8073 							DNS_SECTION_AUTHORITY);
8074 					goto cleanup;
8075 				}
8076 #endif
8077 				if (is_zone)
8078 					goto iszone_nxrrset;
8079 				else
8080 					goto ncache_nxrrset;
8081 			} else if (result != ISC_R_SUCCESS) {
8082 				eresult = result;
8083 				goto cleanup;
8084 			}
8085 		} else if (client->query.dns64_aaaaok != NULL) {
8086 			query_filter64(client, &fname, rdataset, dbuf,
8087 				       DNS_SECTION_ANSWER);
8088 			query_putrdataset(client, &rdataset);
8089 		} else {
8090 			if (!is_zone && RECURSIONOK(client))
8091 				query_prefetch(client, fname, rdataset);
8092 			query_addrrset(client, &fname, &rdataset,
8093 				       sigrdatasetp, dbuf, DNS_SECTION_ANSWER);
8094 		}
8095 
8096 		if (noqname != NULL)
8097 			query_addnoqnameproof(client, noqname);
8098 		/*
8099 		 * We shouldn't ever fail to add 'rdataset'
8100 		 * because it's already in the answer.
8101 		 */
8102 		INSIST(rdataset == NULL);
8103 	}
8104 
8105  addauth:
8106 	CTRACE("query_find: addauth");
8107 	/*
8108 	 * Add NS records to the authority section (if we haven't already
8109 	 * added them to the answer section).
8110 	 */
8111 	if (!want_restart && !NOAUTHORITY(client)) {
8112 		if (is_zone) {
8113 			if (!((qtype == dns_rdatatype_ns ||
8114 			       qtype == dns_rdatatype_any) &&
8115 			      dns_name_equal(client->query.qname,
8116 					     dns_db_origin(db))))
8117 				(void)query_addns(client, db, version);
8118 		} else if (qtype != dns_rdatatype_ns) {
8119 			if (fname != NULL)
8120 				query_releasename(client, &fname);
8121 			query_addbestns(client);
8122 		}
8123 	}
8124 
8125 	/*
8126 	 * Add NSEC records to the authority section if they're needed for
8127 	 * DNSSEC wildcard proofs.
8128 	 */
8129 	if (need_wildcardproof && dns_db_issecure(db))
8130 		query_addwildcardproof(client, db, version,
8131 				       dns_fixedname_name(&wildcardname),
8132 				       ISC_TRUE, ISC_FALSE);
8133  cleanup:
8134 	CTRACE("query_find: cleanup");
8135 	/*
8136 	 * General cleanup.
8137 	 */
8138 	rpz_st = client->query.rpz_st;
8139 	if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) {
8140 		rpz_match_clear(rpz_st);
8141 		rpz_st->state &= ~DNS_RPZ_DONE_QNAME;
8142 	}
8143 	if (rdataset != NULL)
8144 		query_putrdataset(client, &rdataset);
8145 	if (sigrdataset != NULL)
8146 		query_putrdataset(client, &sigrdataset);
8147 	if (fname != NULL)
8148 		query_releasename(client, &fname);
8149 	if (node != NULL)
8150 		dns_db_detachnode(db, &node);
8151 	if (db != NULL)
8152 		dns_db_detach(&db);
8153 	if (zone != NULL)
8154 		dns_zone_detach(&zone);
8155 	if (zdb != NULL) {
8156 		query_putrdataset(client, &zrdataset);
8157 		if (zsigrdataset != NULL)
8158 			query_putrdataset(client, &zsigrdataset);
8159 		if (zfname != NULL)
8160 			query_releasename(client, &zfname);
8161 		dns_db_detach(&zdb);
8162 	}
8163 	if (event != NULL)
8164 		isc_event_free(ISC_EVENT_PTR(&event));
8165 
8166 	/*
8167 	 * AA bit.
8168 	 */
8169 	if (client->query.restarts == 0 && !authoritative) {
8170 		/*
8171 		 * We're not authoritative, so we must ensure the AA bit
8172 		 * isn't set.
8173 		 */
8174 		client->message->flags &= ~DNS_MESSAGEFLAG_AA;
8175 	}
8176 
8177 	/*
8178 	 * Restart the query?
8179 	 */
8180 	if (want_restart && client->query.restarts < MAX_RESTARTS) {
8181 		client->query.restarts++;
8182 		goto restart;
8183 	}
8184 
8185 	if (eresult != ISC_R_SUCCESS &&
8186 	    (!PARTIALANSWER(client) || WANTRECURSION(client)
8187 	     || eresult == DNS_R_DROP)) {
8188 		if (eresult == DNS_R_DUPLICATE || eresult == DNS_R_DROP) {
8189 			/*
8190 			 * This was a duplicate query that we are
8191 			 * recursing on or the result of rate limiting.
8192 			 * Don't send a response now for a duplicate query,
8193 			 * because the original will still cause a response.
8194 			 */
8195 			query_next(client, eresult);
8196 		} else {
8197 			/*
8198 			 * If we don't have any answer to give the client,
8199 			 * or if the client requested recursion and thus wanted
8200 			 * the complete answer, send an error response.
8201 			 */
8202 			INSIST(line >= 0);
8203 			query_error(client, eresult, line);
8204 		}
8205 		ns_client_detach(&client);
8206 	} else if (!RECURSING(client)) {
8207 		/*
8208 		 * We are done.  Set up sortlist data for the message
8209 		 * rendering code, make a final tweak to the AA bit if the
8210 		 * auth-nxdomain config option says so, then render and
8211 		 * send the response.
8212 		 */
8213 		setup_query_sortlist(client);
8214 
8215 		/*
8216 		 * If this is a referral and the answer to the question
8217 		 * is in the glue sort it to the start of the additional
8218 		 * section.
8219 		 */
8220 		if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) &&
8221 		    client->message->rcode == dns_rcode_noerror &&
8222 		    (qtype == dns_rdatatype_a || qtype == dns_rdatatype_aaaa))
8223 			answer_in_glue(client, qtype);
8224 
8225 		if (client->message->rcode == dns_rcode_nxdomain &&
8226 		    client->view->auth_nxdomain == ISC_TRUE)
8227 			client->message->flags |= DNS_MESSAGEFLAG_AA;
8228 
8229 		/*
8230 		 * If the response is somehow unexpected for the client and this
8231 		 * is a result of recursion, return an error to the caller
8232 		 * to indicate it may need to be logged.
8233 		 */
8234 		if (resuming &&
8235 		    (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) ||
8236 		     client->message->rcode != dns_rcode_noerror))
8237 			eresult = ISC_R_FAILURE;
8238 
8239 		query_send(client);
8240 		ns_client_detach(&client);
8241 	}
8242 	CTRACE("query_find: done");
8243 
8244 	return (eresult);
8245 }
8246 
8247 static inline void
8248 log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
8249 	char namebuf[DNS_NAME_FORMATSIZE];
8250 	char typename[DNS_RDATATYPE_FORMATSIZE];
8251 	char classname[DNS_RDATACLASS_FORMATSIZE];
8252 	char onbuf[ISC_NETADDR_FORMATSIZE];
8253 	dns_rdataset_t *rdataset;
8254 	int level = ISC_LOG_INFO;
8255 
8256 	if (! isc_log_wouldlog(ns_g_lctx, level))
8257 		return;
8258 
8259 	rdataset = ISC_LIST_HEAD(client->query.qname->list);
8260 	INSIST(rdataset != NULL);
8261 	dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
8262 	dns_rdataclass_format(rdataset->rdclass, classname, sizeof(classname));
8263 	dns_rdatatype_format(rdataset->type, typename, sizeof(typename));
8264 	isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf));
8265 
8266 	ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
8267 		      level, "query: %s %s %s %s%s%s%s%s%s (%s)", namebuf,
8268 		      classname, typename, WANTRECURSION(client) ? "+" : "-",
8269 		      (client->signer != NULL) ? "S" : "",
8270 		      (client->ednsversion >= 0) ? "E" : "",
8271 		      ((client->attributes & NS_CLIENTATTR_TCP) != 0) ?
8272 				 "T" : "",
8273 		      ((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "",
8274 		      ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "",
8275 		      onbuf);
8276 }
8277 
8278 static inline void
8279 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) {
8280 	char namebuf[DNS_NAME_FORMATSIZE];
8281 	char typename[DNS_RDATATYPE_FORMATSIZE];
8282 	char classname[DNS_RDATACLASS_FORMATSIZE];
8283 	const char *namep, *typep, *classp, *sep1, *sep2;
8284 	dns_rdataset_t *rdataset;
8285 
8286 	if (!isc_log_wouldlog(ns_g_lctx, level))
8287 		return;
8288 
8289 	namep = typep = classp = sep1 = sep2 = "";
8290 
8291 	/*
8292 	 * Query errors can happen for various reasons.  In some cases we cannot
8293 	 * even assume the query contains a valid question section, so we should
8294 	 * expect exceptional cases.
8295 	 */
8296 	if (client->query.origqname != NULL) {
8297 		dns_name_format(client->query.origqname, namebuf,
8298 				sizeof(namebuf));
8299 		namep = namebuf;
8300 		sep1 = " for ";
8301 
8302 		rdataset = ISC_LIST_HEAD(client->query.origqname->list);
8303 		if (rdataset != NULL) {
8304 			dns_rdataclass_format(rdataset->rdclass, classname,
8305 					      sizeof(classname));
8306 			classp = classname;
8307 			dns_rdatatype_format(rdataset->type, typename,
8308 					     sizeof(typename));
8309 			typep = typename;
8310 			sep2 = "/";
8311 		}
8312 	}
8313 
8314 	ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS, NS_LOGMODULE_QUERY,
8315 		      level, "query failed (%s)%s%s%s%s%s%s at %s:%d",
8316 		      isc_result_totext(result), sep1, namep, sep2,
8317 		      classp, sep2, typep, __FILE__, line);
8318 }
8319 
8320 void
8321 ns_query_start(ns_client_t *client) {
8322 	isc_result_t result;
8323 	dns_message_t *message = client->message;
8324 	dns_rdataset_t *rdataset;
8325 	ns_client_t *qclient;
8326 	dns_rdatatype_t qtype;
8327 	unsigned int saved_extflags = client->extflags;
8328 	unsigned int saved_flags = client->message->flags;
8329 
8330 	CTRACE("ns_query_start");
8331 
8332 	/*
8333 	 * Test only.
8334 	 */
8335 	if (ns_g_clienttest && (client->attributes & NS_CLIENTATTR_TCP) == 0)
8336 		RUNTIME_CHECK(ns_client_replace(client) == ISC_R_SUCCESS);
8337 
8338 	/*
8339 	 * Ensure that appropriate cleanups occur.
8340 	 */
8341 	client->next = query_next_callback;
8342 
8343 	/*
8344 	 * Behave as if we don't support DNSSEC if not enabled.
8345 	 */
8346 	if (!client->view->enablednssec) {
8347 		message->flags &= ~DNS_MESSAGEFLAG_CD;
8348 		client->extflags &= ~DNS_MESSAGEEXTFLAG_DO;
8349 	}
8350 
8351 	if ((message->flags & DNS_MESSAGEFLAG_RD) != 0)
8352 		client->query.attributes |= NS_QUERYATTR_WANTRECURSION;
8353 
8354 	if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0)
8355 		client->attributes |= NS_CLIENTATTR_WANTDNSSEC;
8356 
8357 	if (client->view->minimalresponses)
8358 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
8359 					     NS_QUERYATTR_NOADDITIONAL);
8360 
8361 	if ((client->view->cachedb == NULL)
8362 	    || (!client->view->additionalfromcache)) {
8363 		/*
8364 		 * We don't have a cache.  Turn off cache support and
8365 		 * recursion.
8366 		 */
8367 		client->query.attributes &=
8368 			~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK);
8369 	} else if ((client->attributes & NS_CLIENTATTR_RA) == 0 ||
8370 		   (message->flags & DNS_MESSAGEFLAG_RD) == 0) {
8371 		/*
8372 		 * If the client isn't allowed to recurse (due to
8373 		 * "recursion no", the allow-recursion ACL, or the
8374 		 * lack of a resolver in this view), or if it
8375 		 * doesn't want recursion, turn recursion off.
8376 		 */
8377 		client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
8378 	}
8379 
8380 	/*
8381 	 * Get the question name.
8382 	 */
8383 	result = dns_message_firstname(message, DNS_SECTION_QUESTION);
8384 	if (result != ISC_R_SUCCESS) {
8385 		query_error(client, result, __LINE__);
8386 		return;
8387 	}
8388 	dns_message_currentname(message, DNS_SECTION_QUESTION,
8389 				&client->query.qname);
8390 	client->query.origqname = client->query.qname;
8391 	result = dns_message_nextname(message, DNS_SECTION_QUESTION);
8392 	if (result != ISC_R_NOMORE) {
8393 		if (result == ISC_R_SUCCESS) {
8394 			/*
8395 			 * There's more than one QNAME in the question
8396 			 * section.
8397 			 */
8398 			query_error(client, DNS_R_FORMERR, __LINE__);
8399 		} else
8400 			query_error(client, result, __LINE__);
8401 		return;
8402 	}
8403 
8404 	if (ns_g_server->log_queries)
8405 		log_query(client, saved_flags, saved_extflags);
8406 
8407 	/*
8408 	 * Check for multiple question queries, since edns1 is dead.
8409 	 */
8410 	if (message->counts[DNS_SECTION_QUESTION] > 1) {
8411 		query_error(client, DNS_R_FORMERR, __LINE__);
8412 		return;
8413 	}
8414 
8415 	/*
8416 	 * Check for meta-queries like IXFR and AXFR.
8417 	 */
8418 	rdataset = ISC_LIST_HEAD(client->query.qname->list);
8419 	INSIST(rdataset != NULL);
8420 	qtype = rdataset->type;
8421 	dns_rdatatypestats_increment(ns_g_server->rcvquerystats, qtype);
8422 
8423 	if (dns_rdatatype_ismeta(qtype)) {
8424 		switch (qtype) {
8425 		case dns_rdatatype_any:
8426 			break; /* Let query_find handle it. */
8427 		case dns_rdatatype_ixfr:
8428 		case dns_rdatatype_axfr:
8429 			ns_xfr_start(client, rdataset->type);
8430 			return;
8431 		case dns_rdatatype_maila:
8432 		case dns_rdatatype_mailb:
8433 			query_error(client, DNS_R_NOTIMP, __LINE__);
8434 			return;
8435 		case dns_rdatatype_tkey:
8436 			result = dns_tkey_processquery(client->message,
8437 						ns_g_server->tkeyctx,
8438 						client->view->dynamickeys);
8439 			if (result == ISC_R_SUCCESS)
8440 				query_send(client);
8441 			else
8442 				query_error(client, result, __LINE__);
8443 			return;
8444 		default: /* TSIG, etc. */
8445 			query_error(client, DNS_R_FORMERR, __LINE__);
8446 			return;
8447 		}
8448 	}
8449 
8450 	/*
8451 	 * Turn on minimal response for DNSKEY and DS queries.
8452 	 */
8453 	if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds)
8454 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
8455 					     NS_QUERYATTR_NOADDITIONAL);
8456 
8457 	/*
8458 	 * Turn on minimal responses for EDNS/UDP bufsize 512 queries.
8459 	 */
8460 	if (client->ednsversion >= 0 && client->udpsize <= 512U &&
8461 	    (client->attributes & NS_CLIENTATTR_TCP) == 0)
8462 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
8463 					     NS_QUERYATTR_NOADDITIONAL);
8464 
8465 	/*
8466 	 * If the client has requested that DNSSEC checking be disabled,
8467 	 * allow lookups to return pending data and instruct the resolver
8468 	 * to return data before validation has completed.
8469 	 *
8470 	 * We don't need to set DNS_DBFIND_PENDINGOK when validation is
8471 	 * disabled as there will be no pending data.
8472 	 */
8473 	if (message->flags & DNS_MESSAGEFLAG_CD ||
8474 	    qtype == dns_rdatatype_rrsig)
8475 	{
8476 		client->query.dboptions |= DNS_DBFIND_PENDINGOK;
8477 		client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
8478 	} else if (!client->view->enablevalidation)
8479 		client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
8480 
8481 	/*
8482 	 * Allow glue NS records to be added to the authority section
8483 	 * if the answer is secure.
8484 	 */
8485 	if (message->flags & DNS_MESSAGEFLAG_CD)
8486 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
8487 
8488 	/*
8489 	 * Set NS_CLIENTATTR_WANTDNSSEC if the client has set AD in the query.
8490 	 * This allows AD to be returned on queries without DO set.
8491 	 */
8492 	if ((message->flags & DNS_MESSAGEFLAG_AD) != 0)
8493 		client->attributes |= NS_CLIENTATTR_WANTAD;
8494 
8495 	/*
8496 	 * This is an ordinary query.
8497 	 */
8498 	result = dns_message_reply(message, ISC_TRUE);
8499 	if (result != ISC_R_SUCCESS) {
8500 		query_next(client, result);
8501 		return;
8502 	}
8503 
8504 	/*
8505 	 * Assume authoritative response until it is known to be
8506 	 * otherwise.
8507 	 *
8508 	 * If "-T noaa" has been set on the command line don't set
8509 	 * AA on authoritative answers.
8510 	 */
8511 	if (!ns_g_noaa)
8512 		message->flags |= DNS_MESSAGEFLAG_AA;
8513 
8514 	/*
8515 	 * Set AD.  We must clear it if we add non-validated data to a
8516 	 * response.
8517 	 */
8518 	if (WANTDNSSEC(client) || WANTAD(client))
8519 		message->flags |= DNS_MESSAGEFLAG_AD;
8520 
8521 	qclient = NULL;
8522 	ns_client_attach(client, &qclient);
8523 	(void)query_find(qclient, NULL, qtype);
8524 }
8525