xref: /netbsd-src/external/mpl/bind/dist/lib/ns/query.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 /*	$NetBSD: query.c,v 1.10 2020/08/03 17:23:43 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 /*! \file */
15 
16 #include <inttypes.h>
17 #include <stdbool.h>
18 #include <string.h>
19 
20 #include <isc/hex.h>
21 #include <isc/mem.h>
22 #include <isc/once.h>
23 #include <isc/print.h>
24 #include <isc/random.h>
25 #include <isc/rwlock.h>
26 #include <isc/serial.h>
27 #include <isc/stats.h>
28 #include <isc/string.h>
29 #include <isc/thread.h>
30 #include <isc/util.h>
31 
32 #include <dns/adb.h>
33 #include <dns/badcache.h>
34 #include <dns/byaddr.h>
35 #include <dns/cache.h>
36 #include <dns/db.h>
37 #include <dns/dlz.h>
38 #include <dns/dns64.h>
39 #include <dns/dnsrps.h>
40 #include <dns/dnssec.h>
41 #include <dns/events.h>
42 #include <dns/keytable.h>
43 #include <dns/message.h>
44 #include <dns/ncache.h>
45 #include <dns/nsec.h>
46 #include <dns/nsec3.h>
47 #include <dns/order.h>
48 #include <dns/rdata.h>
49 #include <dns/rdataclass.h>
50 #include <dns/rdatalist.h>
51 #include <dns/rdataset.h>
52 #include <dns/rdatasetiter.h>
53 #include <dns/rdatastruct.h>
54 #include <dns/rdatatype.h>
55 #include <dns/resolver.h>
56 #include <dns/result.h>
57 #include <dns/stats.h>
58 #include <dns/tkey.h>
59 #include <dns/types.h>
60 #include <dns/view.h>
61 #include <dns/zone.h>
62 #include <dns/zt.h>
63 
64 #include <ns/client.h>
65 #include <ns/hooks.h>
66 #include <ns/interfacemgr.h>
67 #include <ns/log.h>
68 #include <ns/server.h>
69 #include <ns/sortlist.h>
70 #include <ns/stats.h>
71 #include <ns/xfrout.h>
72 
73 #include <ns/pfilter.h>
74 
75 #if 0
76 /*
77  * It has been recommended that DNS64 be changed to return excluded
78  * AAAA addresses if DNS64 synthesis does not occur.  This minimises
79  * the impact on the lookup results.  While most DNS AAAA lookups are
80  * done to send IP packets to a host, not all of them are and filtering
81  * excluded addresses has a negative impact on those uses.
82  */
83 #define dns64_bis_return_excluded_addresses 1
84 #endif /* if 0 */
85 
86 /*%
87  * Maximum number of chained queries before we give up
88  * to prevent CNAME loops.
89  */
90 #define MAX_RESTARTS 16
91 
92 #define QUERY_ERROR(qctx, r)                \
93 	do {                                \
94 		qctx->result = r;           \
95 		qctx->want_restart = false; \
96 		qctx->line = __LINE__;      \
97 	} while (/*CONSTCOND*/0)
98 
99 /*% Partial answer? */
100 #define PARTIALANSWER(c) \
101 	(((c)->query.attributes & NS_QUERYATTR_PARTIALANSWER) != 0)
102 /*% Use Cache? */
103 #define USECACHE(c) (((c)->query.attributes & NS_QUERYATTR_CACHEOK) != 0)
104 /*% Recursion OK? */
105 #define RECURSIONOK(c) (((c)->query.attributes & NS_QUERYATTR_RECURSIONOK) != 0)
106 /*% Recursing? */
107 #define RECURSING(c) (((c)->query.attributes & NS_QUERYATTR_RECURSING) != 0)
108 /*% Want Recursion? */
109 #define WANTRECURSION(c) \
110 	(((c)->query.attributes & NS_QUERYATTR_WANTRECURSION) != 0)
111 /*% Is TCP? */
112 #define TCP(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0)
113 
114 /*% Want DNSSEC? */
115 #define WANTDNSSEC(c) (((c)->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
116 /*% Want WANTAD? */
117 #define WANTAD(c) (((c)->attributes & NS_CLIENTATTR_WANTAD) != 0)
118 /*% Client presented a valid COOKIE. */
119 #define HAVECOOKIE(c) (((c)->attributes & NS_CLIENTATTR_HAVECOOKIE) != 0)
120 /*% Client presented a COOKIE. */
121 #define WANTCOOKIE(c) (((c)->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0)
122 /*% Client presented a CLIENT-SUBNET option. */
123 #define HAVEECS(c) (((c)->attributes & NS_CLIENTATTR_HAVEECS) != 0)
124 /*% No authority? */
125 #define NOAUTHORITY(c) (((c)->query.attributes & NS_QUERYATTR_NOAUTHORITY) != 0)
126 /*% No additional? */
127 #define NOADDITIONAL(c) \
128 	(((c)->query.attributes & NS_QUERYATTR_NOADDITIONAL) != 0)
129 /*% Secure? */
130 #define SECURE(c) (((c)->query.attributes & NS_QUERYATTR_SECURE) != 0)
131 /*% DNS64 A lookup? */
132 #define DNS64(c) (((c)->query.attributes & NS_QUERYATTR_DNS64) != 0)
133 
134 #define DNS64EXCLUDE(c) \
135 	(((c)->query.attributes & NS_QUERYATTR_DNS64EXCLUDE) != 0)
136 
137 #define REDIRECT(c) (((c)->query.attributes & NS_QUERYATTR_REDIRECT) != 0)
138 
139 /*% Does the rdataset 'r' have an attached 'No QNAME Proof'? */
140 #define NOQNAME(r) (((r)->attributes & DNS_RDATASETATTR_NOQNAME) != 0)
141 
142 /*% Does the rdataset 'r' contain a stale answer? */
143 #define STALE(r) (((r)->attributes & DNS_RDATASETATTR_STALE) != 0)
144 
145 #ifdef WANT_QUERYTRACE
146 static inline void
147 client_trace(ns_client_t *client, int level, const char *message) {
148 	if (client != NULL && client->query.qname != NULL) {
149 		if (isc_log_wouldlog(ns_lctx, level)) {
150 			char qbuf[DNS_NAME_FORMATSIZE];
151 			char tbuf[DNS_RDATATYPE_FORMATSIZE];
152 			dns_name_format(client->query.qname, qbuf,
153 					sizeof(qbuf));
154 			dns_rdatatype_format(client->query.qtype, tbuf,
155 					     sizeof(tbuf));
156 			isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT,
157 				      NS_LOGMODULE_QUERY, level,
158 				      "query client=%p thread=0x%lx "
159 				      "(%s/%s): %s",
160 				      client, (unsigned long)isc_thread_self(),
161 				      qbuf, tbuf, message);
162 		}
163 	} else {
164 		isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT,
165 			      NS_LOGMODULE_QUERY, level,
166 			      "query client=%p thread=0x%lx "
167 			      "(<unknown-query>): %s",
168 			      client, (unsigned long)isc_thread_self(),
169 			      message);
170 	}
171 }
172 #define CTRACE(l, m)  client_trace(client, l, m)
173 #define CCTRACE(l, m) client_trace(qctx->client, l, m)
174 #else /* ifdef WANT_QUERYTRACE */
175 #define CTRACE(l, m)  ((void)m)
176 #define CCTRACE(l, m) ((void)m)
177 #endif /* WANT_QUERYTRACE */
178 
179 #define DNS_GETDB_NOEXACT   0x01U
180 #define DNS_GETDB_NOLOG	    0x02U
181 #define DNS_GETDB_PARTIAL   0x04U
182 #define DNS_GETDB_IGNOREACL 0x08U
183 
184 #define PENDINGOK(x) (((x)&DNS_DBFIND_PENDINGOK) != 0)
185 
186 #define SFCACHE_CDFLAG 0x1
187 
188 /*
189  * These have the same semantics as:
190  *
191  * 	foo_attach(b, a);
192  *	foo_detach(&a);
193  *
194  * without the locking and magic testing.
195  *
196  * We use SAVE and RESTORE as that shows the operation being performed.
197  */
198 #define SAVE(a, b)                 \
199 	do {                       \
200 		INSIST(a == NULL); \
201 		a = b;             \
202 		b = NULL;          \
203 	} while (/*CONSTCOND*/0)
204 #define RESTORE(a, b) SAVE(a, b)
205 
206 static bool
207 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
208 	 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
209 
210 static void
211 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
212 		       dns_dbversion_t *version, ns_client_t *client,
213 		       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
214 		       dns_name_t *fname, bool exact, dns_name_t *found);
215 
216 static inline void
217 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level);
218 
219 static void
220 rpz_st_clear(ns_client_t *client);
221 
222 static bool
223 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
224 	      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
225 
226 static void
227 log_noexistnodata(void *val, int level, const char *fmt, ...)
228 	ISC_FORMAT_PRINTF(3, 4);
229 
230 /*
231  * Return the hooktable in use with 'qctx', or if there isn't one
232  * set, return the default hooktable.
233  */
234 static inline ns_hooktable_t *
235 get_hooktab(query_ctx_t *qctx) {
236 	if (qctx == NULL || qctx->view == NULL || qctx->view->hooktable == NULL)
237 	{
238 		return (ns__hook_table);
239 	}
240 
241 	return (qctx->view->hooktable);
242 }
243 
244 /*
245  * Call the specified hook function in every configured module that implements
246  * that function. If any hook function returns NS_HOOK_RETURN, we
247  * set 'result' and terminate processing by jumping to the 'cleanup' tag.
248  *
249  * (Note that a hook function may set the 'result' to ISC_R_SUCCESS but
250  * still terminate processing within the calling function. That's why this
251  * is a macro instead of an inline function; it needs to be able to use
252  * 'goto cleanup' regardless of the return value.)
253  */
254 #define CALL_HOOK(_id, _qctx)                                       \
255 	do {                                                        \
256 		isc_result_t _res;                                  \
257 		ns_hooktable_t *_tab = get_hooktab(_qctx);          \
258 		ns_hook_t *_hook;                                   \
259 		_hook = ISC_LIST_HEAD((*_tab)[_id]);                \
260 		while (_hook != NULL) {                             \
261 			ns_hook_action_t _func = _hook->action;     \
262 			void *_data = _hook->action_data;           \
263 			INSIST(_func != NULL);                      \
264 			switch (_func(_qctx, _data, &_res)) {       \
265 			case NS_HOOK_CONTINUE:                      \
266 				_hook = ISC_LIST_NEXT(_hook, link); \
267 				break;                              \
268 			case NS_HOOK_RETURN:                        \
269 				result = _res;                      \
270 				goto cleanup;                       \
271 			default:                                    \
272 				INSIST(0);                          \
273 			}                                           \
274 		}                                                   \
275 	} while (false)
276 
277 /*
278  * Call the specified hook function in every configured module that
279  * implements that function. All modules are called; hook function return
280  * codes are ignored. This is intended for use with initialization and
281  * destruction calls which *must* run in every configured module.
282  *
283  * (This could be implemented as an inline void function, but is left as a
284  * macro for symmetry with CALL_HOOK above.)
285  */
286 #define CALL_HOOK_NORETURN(_id, _qctx)                          \
287 	do {                                                    \
288 		isc_result_t _res;                              \
289 		ns_hooktable_t *_tab = get_hooktab(_qctx);      \
290 		ns_hook_t *_hook;                               \
291 		_hook = ISC_LIST_HEAD((*_tab)[_id]);            \
292 		while (_hook != NULL) {                         \
293 			ns_hook_action_t _func = _hook->action; \
294 			void *_data = _hook->action_data;       \
295 			INSIST(_func != NULL);                  \
296 			_func(_qctx, _data, &_res);             \
297 			_hook = ISC_LIST_NEXT(_hook, link);     \
298 		}                                               \
299 	} while (false)
300 
301 /*
302  * The functions defined below implement the query logic that previously lived
303  * in the single very complex function query_find().  The query_ctx_t structure
304  * defined in <ns/query.h> maintains state from function to function.  The call
305  * flow for the general query processing algorithm is described below:
306  *
307  * 1. Set up query context and other resources for a client
308  *    query (query_setup())
309  *
310  * 2. Start the search (ns__query_start())
311  *
312  * 3. Identify authoritative data sources which may have an answer;
313  *    search them (query_lookup()). If an answer is found, go to 7.
314  *
315  * 4. If recursion or cache access are allowed, search the cache
316  *    (query_lookup() again, using the cache database) to find a better
317  *    answer. If an answer is found, go to 7.
318  *
319  * 5. If recursion is allowed, begin recursion (ns_query_recurse()).
320  *    Go to 15 to clean up this phase of the query. When recursion
321  *    is complete, processing will resume at 6.
322  *
323  * 6. Resume from recursion; set up query context for resumed processing.
324  *
325  * 7. Determine what sort of answer we've found (query_gotanswer())
326  *    and call other functions accordingly:
327  *      - not found (auth or cache), go to 8
328  *      - delegation, go to 9
329  *      - no such domain (auth), go to 10
330  *      - empty answer (auth), go to 11
331  *      - negative response (cache), go to 12
332  *      - answer found, go to 13
333  *
334  * 8. The answer was not found in the database (query_notfound().
335  *    Set up a referral and go to 9.
336  *
337  * 9. Handle a delegation response (query_delegation()). If we need
338  *    to and are allowed to recurse (query_delegation_recurse()), go to 5,
339  *    otherwise go to 15 to clean up and return the delegation to the client.
340  *
341  * 10. No such domain (query_nxdomain()). Attempt redirection; if
342  *     unsuccessful, add authority section records (query_addsoa(),
343  *     query_addauth()), then go to 15 to return NXDOMAIN to client.
344  *
345  * 11. Empty answer (query_nodata()). Add authority section records
346  *     (query_addsoa(), query_addauth()) and signatures if authoritative
347  *     (query_sign_nodata()) then go to 15 and return
348  *     NOERROR/ANCOUNT=0 to client.
349  *
350  * 12. No such domain or empty answer returned from cache (query_ncache()).
351  *     Set response code appropriately, go to 11.
352  *
353  * 13. Prepare a response (query_prepresponse()) and then fill it
354  *     appropriately (query_respond(), or for type ANY,
355  *     query_respond_any()).
356  *
357  * 14. If a restart is needed due to CNAME/DNAME chaining, go to 2.
358  *
359  * 15. Clean up resources. If recursing, stop and wait for the event
360  *     handler to be called back (step 6).  If an answer is ready,
361  *     return it to the client.
362  *
363  * (XXX: This description omits several special cases including
364  * DNS64, RPZ, RRL, and the SERVFAIL cache. It also doesn't discuss
365  * plugins.)
366  */
367 
368 static void
369 query_trace(query_ctx_t *qctx);
370 
371 static void
372 qctx_init(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype,
373 	  query_ctx_t *qctx);
374 
375 static isc_result_t
376 query_setup(ns_client_t *client, dns_rdatatype_t qtype);
377 
378 static isc_result_t
379 query_lookup(query_ctx_t *qctx);
380 
381 static void
382 fetch_callback(isc_task_t *task, isc_event_t *event);
383 
384 static void
385 recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype,
386 		const dns_name_t *qname, const dns_name_t *qdomain);
387 
388 static isc_result_t
389 query_resume(query_ctx_t *qctx);
390 
391 static isc_result_t
392 query_checkrrl(query_ctx_t *qctx, isc_result_t result);
393 
394 static isc_result_t
395 query_checkrpz(query_ctx_t *qctx, isc_result_t result);
396 
397 static isc_result_t
398 query_rpzcname(query_ctx_t *qctx, dns_name_t *cname);
399 
400 static isc_result_t
401 query_gotanswer(query_ctx_t *qctx, isc_result_t result);
402 
403 static void
404 query_addnoqnameproof(query_ctx_t *qctx);
405 
406 static isc_result_t
407 query_respond_any(query_ctx_t *qctx);
408 
409 static isc_result_t
410 query_respond(query_ctx_t *qctx);
411 
412 static isc_result_t
413 query_dns64(query_ctx_t *qctx);
414 
415 static void
416 query_filter64(query_ctx_t *qctx);
417 
418 static isc_result_t
419 query_notfound(query_ctx_t *qctx);
420 
421 static isc_result_t
422 query_zone_delegation(query_ctx_t *qctx);
423 
424 static isc_result_t
425 query_delegation(query_ctx_t *qctx);
426 
427 static isc_result_t
428 query_delegation_recurse(query_ctx_t *qctx);
429 
430 static void
431 query_addds(query_ctx_t *qctx);
432 
433 static isc_result_t
434 query_nodata(query_ctx_t *qctx, isc_result_t result);
435 
436 static isc_result_t
437 query_sign_nodata(query_ctx_t *qctx);
438 
439 static void
440 query_addnxrrsetnsec(query_ctx_t *qctx);
441 
442 static isc_result_t
443 query_nxdomain(query_ctx_t *qctx, bool empty_wild);
444 
445 static isc_result_t
446 query_redirect(query_ctx_t *qctx);
447 
448 static isc_result_t
449 query_ncache(query_ctx_t *qctx, isc_result_t result);
450 
451 static isc_result_t
452 query_coveringnsec(query_ctx_t *qctx);
453 
454 static isc_result_t
455 query_zerottl_refetch(query_ctx_t *qctx);
456 
457 static isc_result_t
458 query_cname(query_ctx_t *qctx);
459 
460 static isc_result_t
461 query_dname(query_ctx_t *qctx);
462 
463 static isc_result_t
464 query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl);
465 
466 static isc_result_t
467 query_prepresponse(query_ctx_t *qctx);
468 
469 static isc_result_t
470 query_addsoa(query_ctx_t *qctx, unsigned int override_ttl,
471 	     dns_section_t section);
472 
473 static isc_result_t
474 query_addns(query_ctx_t *qctx);
475 
476 static void
477 query_addbestns(query_ctx_t *qctx);
478 
479 static void
480 query_addwildcardproof(query_ctx_t *qctx, bool ispositive, bool nodata);
481 
482 static void
483 query_addauth(query_ctx_t *qctx);
484 
485 /*
486  * Increment query statistics counters.
487  */
488 static inline void
489 inc_stats(ns_client_t *client, isc_statscounter_t counter) {
490 	dns_zone_t *zone = client->query.authzone;
491 	dns_rdatatype_t qtype;
492 	dns_rdataset_t *rdataset;
493 	isc_stats_t *zonestats;
494 	dns_stats_t *querystats = NULL;
495 
496 	ns_stats_increment(client->sctx->nsstats, counter);
497 
498 	if (zone == NULL) {
499 		return;
500 	}
501 
502 	/* Do regular response type stats */
503 	zonestats = dns_zone_getrequeststats(zone);
504 
505 	if (zonestats != NULL) {
506 		isc_stats_increment(zonestats, counter);
507 	}
508 
509 	/* Do query type statistics
510 	 *
511 	 * We only increment per-type if we're using the authoritative
512 	 * answer counter, preventing double-counting.
513 	 */
514 	if (counter == ns_statscounter_authans) {
515 		querystats = dns_zone_getrcvquerystats(zone);
516 		if (querystats != NULL) {
517 			rdataset = ISC_LIST_HEAD(client->query.qname->list);
518 			if (rdataset != NULL) {
519 				qtype = rdataset->type;
520 				dns_rdatatypestats_increment(querystats, qtype);
521 			}
522 		}
523 	}
524 }
525 
526 static void
527 query_send(ns_client_t *client) {
528 	isc_statscounter_t counter;
529 
530 	if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0) {
531 		inc_stats(client, ns_statscounter_nonauthans);
532 	} else {
533 		inc_stats(client, ns_statscounter_authans);
534 	}
535 
536 	if (client->message->rcode == dns_rcode_noerror) {
537 		dns_section_t answer = DNS_SECTION_ANSWER;
538 		if (ISC_LIST_EMPTY(client->message->sections[answer])) {
539 			if (client->query.isreferral) {
540 				counter = ns_statscounter_referral;
541 			} else {
542 				counter = ns_statscounter_nxrrset;
543 			}
544 		} else {
545 			counter = ns_statscounter_success;
546 		}
547 	} else if (client->message->rcode == dns_rcode_nxdomain) {
548 		counter = ns_statscounter_nxdomain;
549 	} else if (client->message->rcode == dns_rcode_badcookie) {
550 		counter = ns_statscounter_badcookie;
551 	} else { /* We end up here in case of YXDOMAIN, and maybe others */
552 		counter = ns_statscounter_failure;
553 	}
554 
555 	inc_stats(client, counter);
556 	ns_client_send(client);
557 	isc_nmhandle_unref(client->handle);
558 }
559 
560 static void
561 query_error(ns_client_t *client, isc_result_t result, int line) {
562 	int loglevel = ISC_LOG_DEBUG(3);
563 
564 	switch (dns_result_torcode(result)) {
565 	case dns_rcode_servfail:
566 		loglevel = ISC_LOG_DEBUG(1);
567 		inc_stats(client, ns_statscounter_servfail);
568 		break;
569 	case dns_rcode_formerr:
570 		inc_stats(client, ns_statscounter_formerr);
571 		break;
572 	default:
573 		inc_stats(client, ns_statscounter_failure);
574 		break;
575 	}
576 
577 	if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0) {
578 		loglevel = ISC_LOG_INFO;
579 	}
580 
581 	log_queryerror(client, result, line, loglevel);
582 
583 	ns_client_error(client, result);
584 	isc_nmhandle_unref(client->handle);
585 }
586 
587 static void
588 query_next(ns_client_t *client, isc_result_t result) {
589 	if (result == DNS_R_DUPLICATE) {
590 		inc_stats(client, ns_statscounter_duplicate);
591 	} else if (result == DNS_R_DROP) {
592 		inc_stats(client, ns_statscounter_dropped);
593 	} else {
594 		inc_stats(client, ns_statscounter_failure);
595 	}
596 	ns_client_drop(client, result);
597 	isc_nmhandle_unref(client->handle);
598 }
599 
600 static inline void
601 query_freefreeversions(ns_client_t *client, bool everything) {
602 	ns_dbversion_t *dbversion, *dbversion_next;
603 	unsigned int i;
604 
605 	for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0;
606 	     dbversion != NULL; dbversion = dbversion_next, i++)
607 	{
608 		dbversion_next = ISC_LIST_NEXT(dbversion, link);
609 		/*
610 		 * If we're not freeing everything, we keep the first three
611 		 * dbversions structures around.
612 		 */
613 		if (i > 3 || everything) {
614 			ISC_LIST_UNLINK(client->query.freeversions, dbversion,
615 					link);
616 			isc_mem_put(client->mctx, dbversion,
617 				    sizeof(*dbversion));
618 		}
619 	}
620 }
621 
622 void
623 ns_query_cancel(ns_client_t *client) {
624 	REQUIRE(NS_CLIENT_VALID(client));
625 
626 	LOCK(&client->query.fetchlock);
627 	if (client->query.fetch != NULL) {
628 		dns_resolver_cancelfetch(client->query.fetch);
629 
630 		client->query.fetch = NULL;
631 	}
632 	UNLOCK(&client->query.fetchlock);
633 }
634 
635 static inline void
636 query_reset(ns_client_t *client, bool everything) {
637 	isc_buffer_t *dbuf, *dbuf_next;
638 	ns_dbversion_t *dbversion, *dbversion_next;
639 
640 	CTRACE(ISC_LOG_DEBUG(3), "query_reset");
641 
642 	/*%
643 	 * Reset the query state of a client to its default state.
644 	 */
645 
646 	/*
647 	 * Cancel the fetch if it's running.
648 	 */
649 	ns_query_cancel(client);
650 
651 	/*
652 	 * Cleanup any active versions.
653 	 */
654 	for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
655 	     dbversion != NULL; dbversion = dbversion_next)
656 	{
657 		dbversion_next = ISC_LIST_NEXT(dbversion, link);
658 		dns_db_closeversion(dbversion->db, &dbversion->version, false);
659 		dns_db_detach(&dbversion->db);
660 		ISC_LIST_INITANDAPPEND(client->query.freeversions, dbversion,
661 				       link);
662 	}
663 	ISC_LIST_INIT(client->query.activeversions);
664 
665 	if (client->query.authdb != NULL) {
666 		dns_db_detach(&client->query.authdb);
667 	}
668 	if (client->query.authzone != NULL) {
669 		dns_zone_detach(&client->query.authzone);
670 	}
671 
672 	if (client->query.dns64_aaaa != NULL) {
673 		ns_client_putrdataset(client, &client->query.dns64_aaaa);
674 	}
675 	if (client->query.dns64_sigaaaa != NULL) {
676 		ns_client_putrdataset(client, &client->query.dns64_sigaaaa);
677 	}
678 	if (client->query.dns64_aaaaok != NULL) {
679 		isc_mem_put(client->mctx, client->query.dns64_aaaaok,
680 			    client->query.dns64_aaaaoklen * sizeof(bool));
681 		client->query.dns64_aaaaok = NULL;
682 		client->query.dns64_aaaaoklen = 0;
683 	}
684 
685 	ns_client_putrdataset(client, &client->query.redirect.rdataset);
686 	ns_client_putrdataset(client, &client->query.redirect.sigrdataset);
687 	if (client->query.redirect.db != NULL) {
688 		if (client->query.redirect.node != NULL) {
689 			dns_db_detachnode(client->query.redirect.db,
690 					  &client->query.redirect.node);
691 		}
692 		dns_db_detach(&client->query.redirect.db);
693 	}
694 	if (client->query.redirect.zone != NULL) {
695 		dns_zone_detach(&client->query.redirect.zone);
696 	}
697 
698 	query_freefreeversions(client, everything);
699 
700 	for (dbuf = ISC_LIST_HEAD(client->query.namebufs); dbuf != NULL;
701 	     dbuf = dbuf_next)
702 	{
703 		dbuf_next = ISC_LIST_NEXT(dbuf, link);
704 		if (dbuf_next != NULL || everything) {
705 			ISC_LIST_UNLINK(client->query.namebufs, dbuf, link);
706 			isc_buffer_free(&dbuf);
707 		}
708 	}
709 
710 	if (client->query.restarts > 0) {
711 		/*
712 		 * client->query.qname was dynamically allocated.
713 		 */
714 		dns_message_puttempname(client->message, &client->query.qname);
715 	}
716 	client->query.qname = NULL;
717 	client->query.attributes = (NS_QUERYATTR_RECURSIONOK |
718 				    NS_QUERYATTR_CACHEOK | NS_QUERYATTR_SECURE);
719 	client->query.restarts = 0;
720 	client->query.timerset = false;
721 	if (client->query.rpz_st != NULL) {
722 		rpz_st_clear(client);
723 		if (everything) {
724 			INSIST(client->query.rpz_st->rpsdb == NULL);
725 			isc_mem_put(client->mctx, client->query.rpz_st,
726 				    sizeof(*client->query.rpz_st));
727 			client->query.rpz_st = NULL;
728 		}
729 	}
730 	client->query.origqname = NULL;
731 	client->query.dboptions = 0;
732 	client->query.fetchoptions = 0;
733 	client->query.gluedb = NULL;
734 	client->query.authdbset = false;
735 	client->query.isreferral = false;
736 	client->query.dns64_options = 0;
737 	client->query.dns64_ttl = UINT32_MAX;
738 	recparam_update(&client->query.recparam, 0, NULL, NULL);
739 	client->query.root_key_sentinel_keyid = 0;
740 	client->query.root_key_sentinel_is_ta = false;
741 	client->query.root_key_sentinel_not_ta = false;
742 }
743 
744 static void
745 query_cleanup(ns_client_t *client) {
746 	query_reset(client, false);
747 }
748 
749 void
750 ns_query_free(ns_client_t *client) {
751 	REQUIRE(NS_CLIENT_VALID(client));
752 
753 	query_reset(client, true);
754 }
755 
756 isc_result_t
757 ns_query_init(ns_client_t *client) {
758 	isc_result_t result;
759 
760 	REQUIRE(NS_CLIENT_VALID(client));
761 
762 	ISC_LIST_INIT(client->query.namebufs);
763 	ISC_LIST_INIT(client->query.activeversions);
764 	ISC_LIST_INIT(client->query.freeversions);
765 	client->query.restarts = 0;
766 	client->query.timerset = false;
767 	client->query.rpz_st = NULL;
768 	client->query.qname = NULL;
769 	/*
770 	 * This mutex is destroyed when the client is destroyed in
771 	 * exit_check().
772 	 */
773 	isc_mutex_init(&client->query.fetchlock);
774 
775 	client->query.fetch = NULL;
776 	client->query.prefetch = NULL;
777 	client->query.authdb = NULL;
778 	client->query.authzone = NULL;
779 	client->query.authdbset = false;
780 	client->query.isreferral = false;
781 	client->query.dns64_aaaa = NULL;
782 	client->query.dns64_sigaaaa = NULL;
783 	client->query.dns64_aaaaok = NULL;
784 	client->query.dns64_aaaaoklen = 0;
785 	client->query.redirect.db = NULL;
786 	client->query.redirect.node = NULL;
787 	client->query.redirect.zone = NULL;
788 	client->query.redirect.qtype = dns_rdatatype_none;
789 	client->query.redirect.result = ISC_R_SUCCESS;
790 	client->query.redirect.rdataset = NULL;
791 	client->query.redirect.sigrdataset = NULL;
792 	client->query.redirect.authoritative = false;
793 	client->query.redirect.is_zone = false;
794 	client->query.redirect.fname =
795 		dns_fixedname_initname(&client->query.redirect.fixed);
796 	query_reset(client, false);
797 	result = ns_client_newdbversion(client, 3);
798 	if (result != ISC_R_SUCCESS) {
799 		isc_mutex_destroy(&client->query.fetchlock);
800 		return (result);
801 	}
802 	result = ns_client_newnamebuf(client);
803 	if (result != ISC_R_SUCCESS) {
804 		query_freefreeversions(client, true);
805 		isc_mutex_destroy(&client->query.fetchlock);
806 	}
807 
808 	return (result);
809 }
810 
811 /*%
812  * Check if 'client' is allowed to query the cache of its associated view.
813  * Unless 'options' has DNS_GETDB_NOLOG set, log the result of cache ACL
814  * evaluation using the appropriate level, along with 'name' and 'qtype'.
815  *
816  * The cache ACL is only evaluated once for each client and then the result is
817  * cached: if NS_QUERYATTR_CACHEACLOKVALID is set in client->query.attributes,
818  * cache ACL evaluation has already been performed.  The evaluation result is
819  * also stored in client->query.attributes: if NS_QUERYATTR_CACHEACLOK is set,
820  * the client is allowed cache access.
821  *
822  * Returns:
823  *
824  *\li	#ISC_R_SUCCESS	'client' is allowed to access cache
825  *\li	#DNS_R_REFUSED	'client' is not allowed to access cache
826  */
827 static isc_result_t
828 query_checkcacheaccess(ns_client_t *client, const dns_name_t *name,
829 		       dns_rdatatype_t qtype, unsigned int options) {
830 	isc_result_t result;
831 
832 	if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) == 0) {
833 		/*
834 		 * The view's cache ACLs have not yet been evaluated.
835 		 * Do it now. Both allow-query-cache and
836 		 * allow-query-cache-on must be satsified.
837 		 */
838 		bool log = ((options & DNS_GETDB_NOLOG) == 0);
839 		char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")];
840 
841 		result = ns_client_checkaclsilent(client, NULL,
842 						  client->view->cacheacl, true);
843 		if (result == ISC_R_SUCCESS) {
844 			result = ns_client_checkaclsilent(
845 				client, &client->destaddr,
846 				client->view->cacheonacl, true);
847 		}
848 		if (result == ISC_R_SUCCESS) {
849 			/*
850 			 * We were allowed by the "allow-query-cache" ACL.
851 			 */
852 			client->query.attributes |= NS_QUERYATTR_CACHEACLOK;
853 			if (log && isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(3)))
854 			{
855 				ns_client_aclmsg("query (cache)", name, qtype,
856 						 client->view->rdclass, msg,
857 						 sizeof(msg));
858 				ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
859 					      NS_LOGMODULE_QUERY,
860 					      ISC_LOG_DEBUG(3), "%s approved",
861 					      msg);
862 			}
863 		} else if (log) {
864 			pfilter_notify(result, client, "checkcacheaccess");
865 
866 			/*
867 			 * We were denied by the "allow-query-cache" ACL.
868 			 * There is no need to clear NS_QUERYATTR_CACHEACLOK
869 			 * since it is cleared by query_reset(), before query
870 			 * processing starts.
871 			 */
872 			ns_client_aclmsg("query (cache)", name, qtype,
873 					 client->view->rdclass, msg,
874 					 sizeof(msg));
875 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
876 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
877 				      "%s denied", msg);
878 		}
879 
880 		/*
881 		 * Evaluation has been finished; make sure we will just consult
882 		 * NS_QUERYATTR_CACHEACLOK for this client from now on.
883 		 */
884 		client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID;
885 	}
886 
887 	return ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) != 0
888 			? ISC_R_SUCCESS
889 			: DNS_R_REFUSED);
890 }
891 
892 static inline isc_result_t
893 query_validatezonedb(ns_client_t *client, const dns_name_t *name,
894 		     dns_rdatatype_t qtype, unsigned int options,
895 		     dns_zone_t *zone, dns_db_t *db,
896 		     dns_dbversion_t **versionp) {
897 	isc_result_t result;
898 	dns_acl_t *queryacl, *queryonacl;
899 	ns_dbversion_t *dbversion;
900 
901 	REQUIRE(zone != NULL);
902 	REQUIRE(db != NULL);
903 
904 	/*
905 	 * Mirror zone data is treated as cache data.
906 	 */
907 	if (dns_zone_gettype(zone) == dns_zone_mirror) {
908 		return (query_checkcacheaccess(client, name, qtype, options));
909 	}
910 
911 	/*
912 	 * This limits our searching to the zone where the first name
913 	 * (the query target) was looked for.  This prevents following
914 	 * CNAMES or DNAMES into other zones and prevents returning
915 	 * additional data from other zones. This does not apply if we're
916 	 * answering a query where recursion is requested and allowed.
917 	 */
918 	if (client->query.rpz_st == NULL &&
919 	    !(WANTRECURSION(client) && RECURSIONOK(client)) &&
920 	    client->query.authdbset && db != client->query.authdb)
921 	{
922 		return (DNS_R_REFUSED);
923 	}
924 
925 	/*
926 	 * Non recursive query to a static-stub zone is prohibited; its
927 	 * zone content is not public data, but a part of local configuration
928 	 * and should not be disclosed.
929 	 */
930 	if (dns_zone_gettype(zone) == dns_zone_staticstub &&
931 	    !RECURSIONOK(client)) {
932 		return (DNS_R_REFUSED);
933 	}
934 
935 	/*
936 	 * If the zone has an ACL, we'll check it, otherwise
937 	 * we use the view's "allow-query" ACL.  Each ACL is only checked
938 	 * once per query.
939 	 *
940 	 * Also, get the database version to use.
941 	 */
942 
943 	/*
944 	 * Get the current version of this database.
945 	 */
946 	dbversion = ns_client_findversion(client, db);
947 	if (dbversion == NULL) {
948 		CTRACE(ISC_LOG_ERROR, "unable to get db version");
949 		return (DNS_R_SERVFAIL);
950 	}
951 
952 	if ((options & DNS_GETDB_IGNOREACL) != 0) {
953 		goto approved;
954 	}
955 	if (dbversion->acl_checked) {
956 		if (!dbversion->queryok) {
957 			return (DNS_R_REFUSED);
958 		}
959 		goto approved;
960 	}
961 
962 	queryacl = dns_zone_getqueryacl(zone);
963 	if (queryacl == NULL) {
964 		queryacl = client->view->queryacl;
965 		if ((client->query.attributes & NS_QUERYATTR_QUERYOKVALID) != 0)
966 		{
967 			/*
968 			 * We've evaluated the view's queryacl already.  If
969 			 * NS_QUERYATTR_QUERYOK is set, then the client is
970 			 * allowed to make queries, otherwise the query should
971 			 * be refused.
972 			 */
973 			dbversion->acl_checked = true;
974 			if ((client->query.attributes & NS_QUERYATTR_QUERYOK) ==
975 			    0) {
976 				dbversion->queryok = false;
977 				return (DNS_R_REFUSED);
978 			}
979 			dbversion->queryok = true;
980 			goto approved;
981 		}
982 	}
983 
984 	result = ns_client_checkaclsilent(client, NULL, queryacl, true);
985 	if ((options & DNS_GETDB_NOLOG) == 0) {
986 		char msg[NS_CLIENT_ACLMSGSIZE("query")];
987 		if (result == ISC_R_SUCCESS) {
988 			if (isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(3))) {
989 				ns_client_aclmsg("query", name, qtype,
990 						 client->view->rdclass, msg,
991 						 sizeof(msg));
992 				ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
993 					      NS_LOGMODULE_QUERY,
994 					      ISC_LOG_DEBUG(3), "%s approved",
995 					      msg);
996 			}
997 		} else {
998 			pfilter_notify(result, client, "validatezonedb");
999 			ns_client_aclmsg("query", name, qtype,
1000 					 client->view->rdclass, msg,
1001 					 sizeof(msg));
1002 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1003 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
1004 				      "%s denied", msg);
1005 		}
1006 	}
1007 
1008 	if (queryacl == client->view->queryacl) {
1009 		if (result == ISC_R_SUCCESS) {
1010 			/*
1011 			 * We were allowed by the default
1012 			 * "allow-query" ACL.  Remember this so we
1013 			 * don't have to check again.
1014 			 */
1015 			client->query.attributes |= NS_QUERYATTR_QUERYOK;
1016 		}
1017 		/*
1018 		 * We've now evaluated the view's query ACL, and
1019 		 * the NS_QUERYATTR_QUERYOK attribute is now valid.
1020 		 */
1021 		client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
1022 	}
1023 
1024 	/* If and only if we've gotten this far, check allow-query-on too */
1025 	if (result == ISC_R_SUCCESS) {
1026 		queryonacl = dns_zone_getqueryonacl(zone);
1027 		if (queryonacl == NULL) {
1028 			queryonacl = client->view->queryonacl;
1029 		}
1030 
1031 		result = ns_client_checkaclsilent(client, &client->destaddr,
1032 						  queryonacl, true);
1033 		if ((options & DNS_GETDB_NOLOG) == 0 && result != ISC_R_SUCCESS)
1034 		{
1035 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1036 				      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
1037 				      "query-on denied");
1038 		}
1039 	}
1040 
1041 	dbversion->acl_checked = true;
1042 	if (result != ISC_R_SUCCESS) {
1043 		dbversion->queryok = false;
1044 		return (DNS_R_REFUSED);
1045 	}
1046 	dbversion->queryok = true;
1047 
1048 approved:
1049 	/* Transfer ownership, if necessary. */
1050 	if (versionp != NULL) {
1051 		*versionp = dbversion->version;
1052 	}
1053 	return (ISC_R_SUCCESS);
1054 }
1055 
1056 static inline isc_result_t
1057 query_getzonedb(ns_client_t *client, const dns_name_t *name,
1058 		dns_rdatatype_t qtype, unsigned int options, dns_zone_t **zonep,
1059 		dns_db_t **dbp, dns_dbversion_t **versionp) {
1060 	isc_result_t result;
1061 	unsigned int ztoptions;
1062 	dns_zone_t *zone = NULL;
1063 	dns_db_t *db = NULL;
1064 	bool partial = false;
1065 
1066 	REQUIRE(zonep != NULL && *zonep == NULL);
1067 	REQUIRE(dbp != NULL && *dbp == NULL);
1068 
1069 	/*%
1070 	 * Find a zone database to answer the query.
1071 	 */
1072 	ztoptions = DNS_ZTFIND_MIRROR;
1073 	if ((options & DNS_GETDB_NOEXACT) != 0) {
1074 		ztoptions |= DNS_ZTFIND_NOEXACT;
1075 	}
1076 
1077 	result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL,
1078 			     &zone);
1079 
1080 	if (result == DNS_R_PARTIALMATCH) {
1081 		partial = true;
1082 	}
1083 	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
1084 		result = dns_zone_getdb(zone, &db);
1085 	}
1086 
1087 	if (result != ISC_R_SUCCESS) {
1088 		goto fail;
1089 	}
1090 
1091 	result = query_validatezonedb(client, name, qtype, options, zone, db,
1092 				      versionp);
1093 
1094 	if (result != ISC_R_SUCCESS) {
1095 		goto fail;
1096 	}
1097 
1098 	/* Transfer ownership. */
1099 	*zonep = zone;
1100 	*dbp = db;
1101 
1102 	if (partial && (options & DNS_GETDB_PARTIAL) != 0) {
1103 		return (DNS_R_PARTIALMATCH);
1104 	}
1105 	return (ISC_R_SUCCESS);
1106 
1107 fail:
1108 	if (zone != NULL) {
1109 		dns_zone_detach(&zone);
1110 	}
1111 	if (db != NULL) {
1112 		dns_db_detach(&db);
1113 	}
1114 
1115 	return (result);
1116 }
1117 
1118 static void
1119 rpz_log_rewrite(ns_client_t *client, bool disabled, dns_rpz_policy_t policy,
1120 		dns_rpz_type_t type, dns_zone_t *p_zone, dns_name_t *p_name,
1121 		dns_name_t *cname, dns_rpz_num_t rpz_num) {
1122 	char cname_buf[DNS_NAME_FORMATSIZE] = { 0 };
1123 	char p_name_buf[DNS_NAME_FORMATSIZE];
1124 	char qname_buf[DNS_NAME_FORMATSIZE];
1125 	char classbuf[DNS_RDATACLASS_FORMATSIZE];
1126 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
1127 	const char *s1 = cname_buf, *s2 = cname_buf;
1128 	dns_rdataset_t *rdataset;
1129 	dns_rpz_st_t *st;
1130 	isc_stats_t *zonestats;
1131 
1132 	/*
1133 	 * Count enabled rewrites in the global counter.
1134 	 * Count both enabled and disabled rewrites for each zone.
1135 	 */
1136 	if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) {
1137 		ns_stats_increment(client->sctx->nsstats,
1138 				   ns_statscounter_rpz_rewrites);
1139 	}
1140 	if (p_zone != NULL) {
1141 		zonestats = dns_zone_getrequeststats(p_zone);
1142 		if (zonestats != NULL) {
1143 			isc_stats_increment(zonestats,
1144 					    ns_statscounter_rpz_rewrites);
1145 		}
1146 	}
1147 
1148 	if (!isc_log_wouldlog(ns_lctx, DNS_RPZ_INFO_LEVEL)) {
1149 		return;
1150 	}
1151 
1152 	st = client->query.rpz_st;
1153 	if ((st->popt.no_log & DNS_RPZ_ZBIT(rpz_num)) != 0) {
1154 		return;
1155 	}
1156 
1157 	dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf));
1158 	dns_name_format(p_name, p_name_buf, sizeof(p_name_buf));
1159 	if (cname != NULL) {
1160 		s1 = " (CNAME to: ";
1161 		dns_name_format(cname, cname_buf, sizeof(cname_buf));
1162 		s2 = ")";
1163 	}
1164 
1165 	/*
1166 	 *  Log Qclass and Qtype in addition to existing
1167 	 *  fields.
1168 	 */
1169 	rdataset = ISC_LIST_HEAD(client->query.origqname->list);
1170 	INSIST(rdataset != NULL);
1171 	dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf));
1172 	dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf));
1173 
1174 	ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY,
1175 		      DNS_RPZ_INFO_LEVEL,
1176 		      "%srpz %s %s rewrite %s/%s/%s via %s%s%s%s",
1177 		      disabled ? "disabled " : "", dns_rpz_type2str(type),
1178 		      dns_rpz_policy2str(policy), qname_buf, typebuf, classbuf,
1179 		      p_name_buf, s1, cname_buf, s2);
1180 }
1181 
1182 static void
1183 rpz_log_fail_helper(ns_client_t *client, int level, dns_name_t *p_name,
1184 		    dns_rpz_type_t rpz_type1, dns_rpz_type_t rpz_type2,
1185 		    const char *str, isc_result_t result) {
1186 	char qnamebuf[DNS_NAME_FORMATSIZE];
1187 	char p_namebuf[DNS_NAME_FORMATSIZE];
1188 	const char *failed, *via, *slash, *str_blank;
1189 	const char *rpztypestr1;
1190 	const char *rpztypestr2;
1191 
1192 	if (!isc_log_wouldlog(ns_lctx, level)) {
1193 		return;
1194 	}
1195 
1196 	/*
1197 	 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed" for problems.
1198 	 */
1199 	if (level <= DNS_RPZ_DEBUG_LEVEL1) {
1200 		failed = " failed: ";
1201 	} else {
1202 		failed = ": ";
1203 	}
1204 
1205 	rpztypestr1 = dns_rpz_type2str(rpz_type1);
1206 	if (rpz_type2 != DNS_RPZ_TYPE_BAD) {
1207 		slash = "/";
1208 		rpztypestr2 = dns_rpz_type2str(rpz_type2);
1209 	} else {
1210 		slash = "";
1211 		rpztypestr2 = "";
1212 	}
1213 
1214 	str_blank = (*str != ' ' && *str != '\0') ? " " : "";
1215 
1216 	dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf));
1217 
1218 	if (p_name != NULL) {
1219 		via = " via ";
1220 		dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
1221 	} else {
1222 		via = "";
1223 		p_namebuf[0] = '\0';
1224 	}
1225 
1226 	ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY,
1227 		      level, "rpz %s%s%s rewrite %s%s%s%s%s%s%s", rpztypestr1,
1228 		      slash, rpztypestr2, qnamebuf, via, p_namebuf, str_blank,
1229 		      str, failed, isc_result_totext(result));
1230 }
1231 
1232 static void
1233 rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name,
1234 	     dns_rpz_type_t rpz_type, const char *str, isc_result_t result) {
1235 	rpz_log_fail_helper(client, level, p_name, rpz_type, DNS_RPZ_TYPE_BAD,
1236 			    str, result);
1237 }
1238 
1239 /*
1240  * Get a policy rewrite zone database.
1241  */
1242 static isc_result_t
1243 rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type,
1244 	  dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp) {
1245 	char qnamebuf[DNS_NAME_FORMATSIZE];
1246 	char p_namebuf[DNS_NAME_FORMATSIZE];
1247 	dns_dbversion_t *rpz_version = NULL;
1248 	isc_result_t result;
1249 
1250 	CTRACE(ISC_LOG_DEBUG(3), "rpz_getdb");
1251 
1252 	result = query_getzonedb(client, p_name, dns_rdatatype_any,
1253 				 DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version);
1254 	if (result == ISC_R_SUCCESS) {
1255 		dns_rpz_st_t *st = client->query.rpz_st;
1256 
1257 		/*
1258 		 * It isn't meaningful to log this message when
1259 		 * logging is disabled for some policy zones.
1260 		 */
1261 		if (st->popt.no_log == 0 &&
1262 		    isc_log_wouldlog(ns_lctx, DNS_RPZ_DEBUG_LEVEL2)) {
1263 			dns_name_format(client->query.qname, qnamebuf,
1264 					sizeof(qnamebuf));
1265 			dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
1266 			ns_client_log(client, DNS_LOGCATEGORY_RPZ,
1267 				      NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2,
1268 				      "try rpz %s rewrite %s via %s",
1269 				      dns_rpz_type2str(rpz_type), qnamebuf,
1270 				      p_namebuf);
1271 		}
1272 		*versionp = rpz_version;
1273 		return (ISC_R_SUCCESS);
1274 	}
1275 	rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
1276 		     "query_getzonedb()", result);
1277 	return (result);
1278 }
1279 
1280 /*%
1281  * Find a cache database to answer the query.  This may fail with DNS_R_REFUSED
1282  * if the client is not allowed to use the cache.
1283  */
1284 static inline isc_result_t
1285 query_getcachedb(ns_client_t *client, const dns_name_t *name,
1286 		 dns_rdatatype_t qtype, dns_db_t **dbp, unsigned int options) {
1287 	isc_result_t result;
1288 	dns_db_t *db = NULL;
1289 
1290 	REQUIRE(dbp != NULL && *dbp == NULL);
1291 
1292 	if (!USECACHE(client)) {
1293 		return (DNS_R_REFUSED);
1294 	}
1295 
1296 	dns_db_attach(client->view->cachedb, &db);
1297 
1298 	result = query_checkcacheaccess(client, name, qtype, options);
1299 	if (result != ISC_R_SUCCESS) {
1300 		dns_db_detach(&db);
1301 	}
1302 
1303 	/*
1304 	 * If query_checkcacheaccess() succeeded, transfer ownership of 'db'.
1305 	 * Otherwise, 'db' will be NULL due to the dns_db_detach() call above.
1306 	 */
1307 	*dbp = db;
1308 
1309 	return (result);
1310 }
1311 
1312 static inline isc_result_t
1313 query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
1314 	    unsigned int options, dns_zone_t **zonep, dns_db_t **dbp,
1315 	    dns_dbversion_t **versionp, bool *is_zonep) {
1316 	isc_result_t result;
1317 	isc_result_t tresult;
1318 	unsigned int namelabels;
1319 	unsigned int zonelabels;
1320 	dns_zone_t *zone = NULL;
1321 
1322 	REQUIRE(zonep != NULL && *zonep == NULL);
1323 
1324 	/* Calculate how many labels are in name. */
1325 	namelabels = dns_name_countlabels(name);
1326 	zonelabels = 0;
1327 
1328 	/* Try to find name in bind's standard database. */
1329 	result = query_getzonedb(client, name, qtype, options, &zone, dbp,
1330 				 versionp);
1331 
1332 	/* See how many labels are in the zone's name.	  */
1333 	if (result == ISC_R_SUCCESS && zone != NULL) {
1334 		zonelabels = dns_name_countlabels(dns_zone_getorigin(zone));
1335 	}
1336 
1337 	/*
1338 	 * If # zone labels < # name labels, try to find an even better match
1339 	 * Only try if DLZ drivers are loaded for this view
1340 	 */
1341 	if (ISC_UNLIKELY(zonelabels < namelabels &&
1342 			 !ISC_LIST_EMPTY(client->view->dlz_searched)))
1343 	{
1344 		dns_clientinfomethods_t cm;
1345 		dns_clientinfo_t ci;
1346 		dns_db_t *tdbp;
1347 
1348 		dns_clientinfomethods_init(&cm, ns_client_sourceip);
1349 		dns_clientinfo_init(&ci, client, NULL);
1350 
1351 		tdbp = NULL;
1352 		tresult = dns_view_searchdlz(client->view, name, zonelabels,
1353 					     &cm, &ci, &tdbp);
1354 		/* If we successful, we found a better match. */
1355 		if (tresult == ISC_R_SUCCESS) {
1356 			ns_dbversion_t *dbversion;
1357 
1358 			/*
1359 			 * If the previous search returned a zone, detach it.
1360 			 */
1361 			if (zone != NULL) {
1362 				dns_zone_detach(&zone);
1363 			}
1364 
1365 			/*
1366 			 * If the previous search returned a database,
1367 			 * detach it.
1368 			 */
1369 			if (*dbp != NULL) {
1370 				dns_db_detach(dbp);
1371 			}
1372 
1373 			/*
1374 			 * If the previous search returned a version, clear it.
1375 			 */
1376 			*versionp = NULL;
1377 
1378 			dbversion = ns_client_findversion(client, tdbp);
1379 			if (dbversion == NULL) {
1380 				tresult = ISC_R_NOMEMORY;
1381 			} else {
1382 				/*
1383 				 * Be sure to return our database.
1384 				 */
1385 				*dbp = tdbp;
1386 				*versionp = dbversion->version;
1387 			}
1388 
1389 			/*
1390 			 * We return a null zone, No stats for DLZ zones.
1391 			 */
1392 			zone = NULL;
1393 			result = tresult;
1394 		}
1395 	}
1396 
1397 	/* If successful, Transfer ownership of zone. */
1398 	if (result == ISC_R_SUCCESS) {
1399 		*zonep = zone;
1400 		/*
1401 		 * If neither attempt above succeeded, return the cache instead
1402 		 */
1403 		*is_zonep = true;
1404 	} else {
1405 		if (result == ISC_R_NOTFOUND) {
1406 			result = query_getcachedb(client, name, qtype, dbp,
1407 						  options);
1408 		}
1409 		*is_zonep = false;
1410 	}
1411 	return (result);
1412 }
1413 
1414 static inline bool
1415 query_isduplicate(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
1416 		  dns_name_t **mnamep) {
1417 	dns_section_t section;
1418 	dns_name_t *mname = NULL;
1419 	isc_result_t result;
1420 
1421 	CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate");
1422 
1423 	for (section = DNS_SECTION_ANSWER; section <= DNS_SECTION_ADDITIONAL;
1424 	     section++) {
1425 		result = dns_message_findname(client->message, section, name,
1426 					      type, 0, &mname, NULL);
1427 		if (result == ISC_R_SUCCESS) {
1428 			/*
1429 			 * We've already got this RRset in the response.
1430 			 */
1431 			CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: true: "
1432 						 "done");
1433 			return (true);
1434 		} else if (result == DNS_R_NXRRSET) {
1435 			/*
1436 			 * The name exists, but the rdataset does not.
1437 			 */
1438 			if (section == DNS_SECTION_ADDITIONAL) {
1439 				break;
1440 			}
1441 		} else {
1442 			RUNTIME_CHECK(result == DNS_R_NXDOMAIN);
1443 		}
1444 		mname = NULL;
1445 	}
1446 
1447 	if (mnamep != NULL) {
1448 		*mnamep = mname;
1449 	}
1450 
1451 	CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: false: done");
1452 	return (false);
1453 }
1454 
1455 /*
1456  * Look up data for given 'name' and 'type' in given 'version' of 'db' for
1457  * 'client'. Called from query_additionalauth().
1458  *
1459  * If the lookup is successful:
1460  *
1461  *   - store the node containing the result at 'nodep',
1462  *
1463  *   - store the owner name of the returned node in 'fname',
1464  *
1465  *   - if 'type' is not ANY, dns_db_findext() will put the exact rdataset being
1466  *     looked for in 'rdataset' and its signatures (if any) in 'sigrdataset',
1467  *
1468  *   - if 'type' is ANY, dns_db_findext() will leave 'rdataset' and
1469  *     'sigrdataset' disassociated and the returned node will be iterated in
1470  *     query_additional_cb().
1471  *
1472  * If the lookup is not successful:
1473  *
1474  *   - 'nodep' will not be written to,
1475  *   - 'fname' may still be modified as it is passed to dns_db_findext(),
1476  *   - 'rdataset' and 'sigrdataset' will remain disassociated.
1477  */
1478 static isc_result_t
1479 query_additionalauthfind(dns_db_t *db, dns_dbversion_t *version,
1480 			 const dns_name_t *name, dns_rdatatype_t type,
1481 			 ns_client_t *client, dns_dbnode_t **nodep,
1482 			 dns_name_t *fname, dns_rdataset_t *rdataset,
1483 			 dns_rdataset_t *sigrdataset) {
1484 	dns_clientinfomethods_t cm;
1485 	dns_dbnode_t *node = NULL;
1486 	dns_clientinfo_t ci;
1487 	isc_result_t result;
1488 
1489 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
1490 	dns_clientinfo_init(&ci, client, NULL);
1491 
1492 	/*
1493 	 * Since we are looking for authoritative data, we do not set
1494 	 * the GLUEOK flag.  Glue will be looked for later, but not
1495 	 * necessarily in the same database.
1496 	 */
1497 	result = dns_db_findext(db, name, version, type,
1498 				client->query.dboptions, client->now, &node,
1499 				fname, &cm, &ci, rdataset, sigrdataset);
1500 	if (result != ISC_R_SUCCESS) {
1501 		if (dns_rdataset_isassociated(rdataset)) {
1502 			dns_rdataset_disassociate(rdataset);
1503 		}
1504 
1505 		if (sigrdataset != NULL &&
1506 		    dns_rdataset_isassociated(sigrdataset)) {
1507 			dns_rdataset_disassociate(sigrdataset);
1508 		}
1509 
1510 		if (node != NULL) {
1511 			dns_db_detachnode(db, &node);
1512 		}
1513 
1514 		return (result);
1515 	}
1516 
1517 	/*
1518 	 * Do not return signatures if the zone is not fully signed.
1519 	 */
1520 	if (sigrdataset != NULL && !dns_db_issecure(db) &&
1521 	    dns_rdataset_isassociated(sigrdataset))
1522 	{
1523 		dns_rdataset_disassociate(sigrdataset);
1524 	}
1525 
1526 	*nodep = node;
1527 
1528 	return (ISC_R_SUCCESS);
1529 }
1530 
1531 /*
1532  * For query context 'qctx', try finding authoritative additional data for
1533  * given 'name' and 'type'. Called from query_additional_cb().
1534  *
1535  * If successful:
1536  *
1537  *   - store pointers to the database and node which contain the result in
1538  *     'dbp' and 'nodep', respectively,
1539  *
1540  *   - store the owner name of the returned node in 'fname',
1541  *
1542  *   - potentially bind 'rdataset' and 'sigrdataset', as explained in the
1543  *     comment for query_additionalauthfind().
1544  *
1545  * If unsuccessful:
1546  *
1547  *   - 'dbp' and 'nodep' will not be written to,
1548  *   - 'fname' may still be modified as it is passed to dns_db_findext(),
1549  *   - 'rdataset' and 'sigrdataset' will remain disassociated.
1550  */
1551 static isc_result_t
1552 query_additionalauth(query_ctx_t *qctx, const dns_name_t *name,
1553 		     dns_rdatatype_t type, dns_db_t **dbp, dns_dbnode_t **nodep,
1554 		     dns_name_t *fname, dns_rdataset_t *rdataset,
1555 		     dns_rdataset_t *sigrdataset) {
1556 	ns_client_t *client = qctx->client;
1557 	ns_dbversion_t *dbversion = NULL;
1558 	dns_dbversion_t *version = NULL;
1559 	dns_dbnode_t *node = NULL;
1560 	dns_zone_t *zone = NULL;
1561 	dns_db_t *db = NULL;
1562 	isc_result_t result;
1563 
1564 	/*
1565 	 * First, look within the same zone database for authoritative
1566 	 * additional data.
1567 	 */
1568 	if (!client->query.authdbset || client->query.authdb == NULL) {
1569 		return (ISC_R_NOTFOUND);
1570 	}
1571 
1572 	dbversion = ns_client_findversion(client, client->query.authdb);
1573 	if (dbversion == NULL) {
1574 		return (ISC_R_NOTFOUND);
1575 	}
1576 
1577 	dns_db_attach(client->query.authdb, &db);
1578 	version = dbversion->version;
1579 
1580 	CTRACE(ISC_LOG_DEBUG(3), "query_additionalauth: same zone");
1581 
1582 	result = query_additionalauthfind(db, version, name, type, client,
1583 					  &node, fname, rdataset, sigrdataset);
1584 	if (result != ISC_R_SUCCESS &&
1585 	    qctx->view->minimalresponses == dns_minimal_no &&
1586 	    RECURSIONOK(client))
1587 	{
1588 		/*
1589 		 * If we aren't doing response minimization and recursion is
1590 		 * allowed, we can try and see if any other zone matches.
1591 		 */
1592 		version = NULL;
1593 		dns_db_detach(&db);
1594 		result = query_getzonedb(client, name, type, DNS_GETDB_NOLOG,
1595 					 &zone, &db, &version);
1596 		if (result != ISC_R_SUCCESS) {
1597 			return (result);
1598 		}
1599 		dns_zone_detach(&zone);
1600 
1601 		CTRACE(ISC_LOG_DEBUG(3), "query_additionalauth: other zone");
1602 
1603 		result = query_additionalauthfind(db, version, name, type,
1604 						  client, &node, fname,
1605 						  rdataset, sigrdataset);
1606 	}
1607 
1608 	if (result != ISC_R_SUCCESS) {
1609 		dns_db_detach(&db);
1610 	} else {
1611 		*nodep = node;
1612 		node = NULL;
1613 
1614 		*dbp = db;
1615 		db = NULL;
1616 	}
1617 
1618 	return (result);
1619 }
1620 
1621 static isc_result_t
1622 query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
1623 	query_ctx_t *qctx = arg;
1624 	ns_client_t *client = qctx->client;
1625 	isc_result_t result, eresult = ISC_R_SUCCESS;
1626 	dns_dbnode_t *node = NULL;
1627 	dns_db_t *db = NULL;
1628 	dns_name_t *fname = NULL, *mname = NULL;
1629 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
1630 	dns_rdataset_t *trdataset = NULL;
1631 	isc_buffer_t *dbuf = NULL;
1632 	isc_buffer_t b;
1633 	ns_dbversion_t *dbversion = NULL;
1634 	dns_dbversion_t *version = NULL;
1635 	bool added_something = false, need_addname = false;
1636 	dns_rdatatype_t type;
1637 	dns_clientinfomethods_t cm;
1638 	dns_clientinfo_t ci;
1639 	dns_rdatasetadditional_t additionaltype =
1640 		dns_rdatasetadditional_fromauth;
1641 
1642 	REQUIRE(NS_CLIENT_VALID(client));
1643 	REQUIRE(qtype != dns_rdatatype_any);
1644 
1645 	if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype)) {
1646 		return (ISC_R_SUCCESS);
1647 	}
1648 
1649 	CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb");
1650 
1651 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
1652 	dns_clientinfo_init(&ci, client, NULL);
1653 
1654 	/*
1655 	 * We treat type A additional section processing as if it
1656 	 * were "any address type" additional section processing.
1657 	 * To avoid multiple lookups, we do an 'any' database
1658 	 * lookup and iterate over the node.
1659 	 */
1660 	if (qtype == dns_rdatatype_a) {
1661 		type = dns_rdatatype_any;
1662 	} else {
1663 		type = qtype;
1664 	}
1665 
1666 	/*
1667 	 * Get some resources.
1668 	 */
1669 	dbuf = ns_client_getnamebuf(client);
1670 	if (dbuf == NULL) {
1671 		goto cleanup;
1672 	}
1673 	fname = ns_client_newname(client, dbuf, &b);
1674 	rdataset = ns_client_newrdataset(client);
1675 	if (fname == NULL || rdataset == NULL) {
1676 		goto cleanup;
1677 	}
1678 	if (WANTDNSSEC(client)) {
1679 		sigrdataset = ns_client_newrdataset(client);
1680 		if (sigrdataset == NULL) {
1681 			goto cleanup;
1682 		}
1683 	}
1684 
1685 	/*
1686 	 * If we want only minimal responses and are here, then it must
1687 	 * be for glue.
1688 	 */
1689 	if (qctx->view->minimalresponses == dns_minimal_yes) {
1690 		goto try_glue;
1691 	}
1692 
1693 	/*
1694 	 * First, look for authoritative additional data.
1695 	 */
1696 	result = query_additionalauth(qctx, name, type, &db, &node, fname,
1697 				      rdataset, sigrdataset);
1698 	if (result == ISC_R_SUCCESS) {
1699 		goto found;
1700 	}
1701 
1702 	/*
1703 	 * No authoritative data was found.  The cache is our next best bet.
1704 	 */
1705 	if (!qctx->view->recursion) {
1706 		goto try_glue;
1707 	}
1708 
1709 	additionaltype = dns_rdatasetadditional_fromcache;
1710 	result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG);
1711 	if (result != ISC_R_SUCCESS) {
1712 		/*
1713 		 * Most likely the client isn't allowed to query the cache.
1714 		 */
1715 		goto try_glue;
1716 	}
1717 	/*
1718 	 * Attempt to validate glue.
1719 	 */
1720 	if (sigrdataset == NULL) {
1721 		sigrdataset = ns_client_newrdataset(client);
1722 		if (sigrdataset == NULL) {
1723 			goto cleanup;
1724 		}
1725 	}
1726 
1727 	version = NULL;
1728 	result = dns_db_findext(db, name, version, type,
1729 				client->query.dboptions | DNS_DBFIND_GLUEOK |
1730 					DNS_DBFIND_ADDITIONALOK,
1731 				client->now, &node, fname, &cm, &ci, rdataset,
1732 				sigrdataset);
1733 
1734 	dns_cache_updatestats(qctx->view->cache, result);
1735 	if (!WANTDNSSEC(client)) {
1736 		ns_client_putrdataset(client, &sigrdataset);
1737 	}
1738 	if (result == ISC_R_SUCCESS) {
1739 		goto found;
1740 	}
1741 
1742 	if (dns_rdataset_isassociated(rdataset)) {
1743 		dns_rdataset_disassociate(rdataset);
1744 	}
1745 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {
1746 		dns_rdataset_disassociate(sigrdataset);
1747 	}
1748 	if (node != NULL) {
1749 		dns_db_detachnode(db, &node);
1750 	}
1751 	dns_db_detach(&db);
1752 
1753 try_glue:
1754 	/*
1755 	 * No cached data was found.  Glue is our last chance.
1756 	 * RFC1035 sayeth:
1757 	 *
1758 	 *	NS records cause both the usual additional section
1759 	 *	processing to locate a type A record, and, when used
1760 	 *	in a referral, a special search of the zone in which
1761 	 *	they reside for glue information.
1762 	 *
1763 	 * This is the "special search".  Note that we must search
1764 	 * the zone where the NS record resides, not the zone it
1765 	 * points to, and that we only do the search in the delegation
1766 	 * case (identified by client->query.gluedb being set).
1767 	 */
1768 
1769 	if (client->query.gluedb == NULL) {
1770 		goto cleanup;
1771 	}
1772 
1773 	/*
1774 	 * Don't poison caches using the bailiwick protection model.
1775 	 */
1776 	if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) {
1777 		goto cleanup;
1778 	}
1779 
1780 	dbversion = ns_client_findversion(client, client->query.gluedb);
1781 	if (dbversion == NULL) {
1782 		goto cleanup;
1783 	}
1784 
1785 	dns_db_attach(client->query.gluedb, &db);
1786 	version = dbversion->version;
1787 	additionaltype = dns_rdatasetadditional_fromglue;
1788 	result = dns_db_findext(db, name, version, type,
1789 				client->query.dboptions | DNS_DBFIND_GLUEOK,
1790 				client->now, &node, fname, &cm, &ci, rdataset,
1791 				sigrdataset);
1792 	if (result != ISC_R_SUCCESS && result != DNS_R_ZONECUT &&
1793 	    result != DNS_R_GLUE) {
1794 		goto cleanup;
1795 	}
1796 
1797 found:
1798 	/*
1799 	 * We have found a potential additional data rdataset, or
1800 	 * at least a node to iterate over.
1801 	 */
1802 	ns_client_keepname(client, fname, dbuf);
1803 
1804 	/*
1805 	 * If we have an rdataset, add it to the additional data
1806 	 * section.
1807 	 */
1808 	mname = NULL;
1809 	if (dns_rdataset_isassociated(rdataset) &&
1810 	    !query_isduplicate(client, fname, type, &mname))
1811 	{
1812 		if (mname != NULL) {
1813 			INSIST(mname != fname);
1814 			ns_client_releasename(client, &fname);
1815 			fname = mname;
1816 		} else {
1817 			need_addname = true;
1818 		}
1819 		ISC_LIST_APPEND(fname->list, rdataset, link);
1820 		trdataset = rdataset;
1821 		rdataset = NULL;
1822 		added_something = true;
1823 		/*
1824 		 * Note: we only add SIGs if we've added the type they cover,
1825 		 * so we do not need to check if the SIG rdataset is already
1826 		 * in the response.
1827 		 */
1828 		if (sigrdataset != NULL &&
1829 		    dns_rdataset_isassociated(sigrdataset)) {
1830 			ISC_LIST_APPEND(fname->list, sigrdataset, link);
1831 			sigrdataset = NULL;
1832 		}
1833 	}
1834 
1835 	if (qtype == dns_rdatatype_a) {
1836 		/*
1837 		 * We now go looking for A and AAAA records, along with
1838 		 * their signatures.
1839 		 *
1840 		 * XXXRTH  This code could be more efficient.
1841 		 */
1842 		if (rdataset != NULL) {
1843 			if (dns_rdataset_isassociated(rdataset)) {
1844 				dns_rdataset_disassociate(rdataset);
1845 			}
1846 		} else {
1847 			rdataset = ns_client_newrdataset(client);
1848 			if (rdataset == NULL) {
1849 				goto addname;
1850 			}
1851 		}
1852 		if (sigrdataset != NULL) {
1853 			if (dns_rdataset_isassociated(sigrdataset)) {
1854 				dns_rdataset_disassociate(sigrdataset);
1855 			}
1856 		} else if (WANTDNSSEC(client)) {
1857 			sigrdataset = ns_client_newrdataset(client);
1858 			if (sigrdataset == NULL) {
1859 				goto addname;
1860 			}
1861 		}
1862 		if (query_isduplicate(client, fname, dns_rdatatype_a, NULL)) {
1863 			goto aaaa_lookup;
1864 		}
1865 		result = dns_db_findrdataset(db, node, version, dns_rdatatype_a,
1866 					     0, client->now, rdataset,
1867 					     sigrdataset);
1868 		if (result == DNS_R_NCACHENXDOMAIN) {
1869 			goto addname;
1870 		} else if (result == DNS_R_NCACHENXRRSET) {
1871 			dns_rdataset_disassociate(rdataset);
1872 			if (sigrdataset != NULL &&
1873 			    dns_rdataset_isassociated(sigrdataset)) {
1874 				dns_rdataset_disassociate(sigrdataset);
1875 			}
1876 		} else if (result == ISC_R_SUCCESS) {
1877 			bool invalid = false;
1878 			mname = NULL;
1879 			if (additionaltype ==
1880 				    dns_rdatasetadditional_fromcache &&
1881 			    (DNS_TRUST_PENDING(rdataset->trust) ||
1882 			     DNS_TRUST_GLUE(rdataset->trust)))
1883 			{
1884 				/* validate() may change rdataset->trust */
1885 				invalid = !validate(client, db, fname, rdataset,
1886 						    sigrdataset);
1887 			}
1888 			if (invalid && DNS_TRUST_PENDING(rdataset->trust)) {
1889 				dns_rdataset_disassociate(rdataset);
1890 				if (sigrdataset != NULL &&
1891 				    dns_rdataset_isassociated(sigrdataset)) {
1892 					dns_rdataset_disassociate(sigrdataset);
1893 				}
1894 			} else if (!query_isduplicate(client, fname,
1895 						      dns_rdatatype_a, &mname))
1896 			{
1897 				if (mname != fname) {
1898 					if (mname != NULL) {
1899 						ns_client_releasename(client,
1900 								      &fname);
1901 						fname = mname;
1902 					} else {
1903 						need_addname = true;
1904 					}
1905 				}
1906 				ISC_LIST_APPEND(fname->list, rdataset, link);
1907 				added_something = true;
1908 				if (sigrdataset != NULL &&
1909 				    dns_rdataset_isassociated(sigrdataset)) {
1910 					ISC_LIST_APPEND(fname->list,
1911 							sigrdataset, link);
1912 					sigrdataset =
1913 						ns_client_newrdataset(client);
1914 				}
1915 				rdataset = ns_client_newrdataset(client);
1916 				if (rdataset == NULL) {
1917 					goto addname;
1918 				}
1919 				if (WANTDNSSEC(client) && sigrdataset == NULL) {
1920 					goto addname;
1921 				}
1922 			} else {
1923 				dns_rdataset_disassociate(rdataset);
1924 				if (sigrdataset != NULL &&
1925 				    dns_rdataset_isassociated(sigrdataset)) {
1926 					dns_rdataset_disassociate(sigrdataset);
1927 				}
1928 			}
1929 		}
1930 	aaaa_lookup:
1931 		if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL))
1932 		{
1933 			goto addname;
1934 		}
1935 		result = dns_db_findrdataset(db, node, version,
1936 					     dns_rdatatype_aaaa, 0, client->now,
1937 					     rdataset, sigrdataset);
1938 		if (result == DNS_R_NCACHENXDOMAIN) {
1939 			goto addname;
1940 		} else if (result == DNS_R_NCACHENXRRSET) {
1941 			dns_rdataset_disassociate(rdataset);
1942 			if (sigrdataset != NULL &&
1943 			    dns_rdataset_isassociated(sigrdataset)) {
1944 				dns_rdataset_disassociate(sigrdataset);
1945 			}
1946 		} else if (result == ISC_R_SUCCESS) {
1947 			bool invalid = false;
1948 			mname = NULL;
1949 
1950 			if (additionaltype ==
1951 				    dns_rdatasetadditional_fromcache &&
1952 			    (DNS_TRUST_PENDING(rdataset->trust) ||
1953 			     DNS_TRUST_GLUE(rdataset->trust)))
1954 			{
1955 				/* validate() may change rdataset->trust */
1956 				invalid = !validate(client, db, fname, rdataset,
1957 						    sigrdataset);
1958 			}
1959 
1960 			if (invalid && DNS_TRUST_PENDING(rdataset->trust)) {
1961 				dns_rdataset_disassociate(rdataset);
1962 				if (sigrdataset != NULL &&
1963 				    dns_rdataset_isassociated(sigrdataset)) {
1964 					dns_rdataset_disassociate(sigrdataset);
1965 				}
1966 			} else if (!query_isduplicate(client, fname,
1967 						      dns_rdatatype_aaaa,
1968 						      &mname)) {
1969 				if (mname != fname) {
1970 					if (mname != NULL) {
1971 						ns_client_releasename(client,
1972 								      &fname);
1973 						fname = mname;
1974 					} else {
1975 						need_addname = true;
1976 					}
1977 				}
1978 				ISC_LIST_APPEND(fname->list, rdataset, link);
1979 				added_something = true;
1980 				if (sigrdataset != NULL &&
1981 				    dns_rdataset_isassociated(sigrdataset)) {
1982 					ISC_LIST_APPEND(fname->list,
1983 							sigrdataset, link);
1984 					sigrdataset = NULL;
1985 				}
1986 				rdataset = NULL;
1987 			}
1988 		}
1989 	}
1990 
1991 addname:
1992 	CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: addname");
1993 	/*
1994 	 * If we haven't added anything, then we're done.
1995 	 */
1996 	if (!added_something) {
1997 		goto cleanup;
1998 	}
1999 
2000 	/*
2001 	 * We may have added our rdatasets to an existing name, if so, then
2002 	 * need_addname will be false.  Whether we used an existing name
2003 	 * or a new one, we must set fname to NULL to prevent cleanup.
2004 	 */
2005 	if (need_addname) {
2006 		dns_message_addname(client->message, fname,
2007 				    DNS_SECTION_ADDITIONAL);
2008 	}
2009 	fname = NULL;
2010 
2011 	/*
2012 	 * In a few cases, we want to add additional data for additional
2013 	 * data.  It's simpler to just deal with special cases here than
2014 	 * to try to create a general purpose mechanism and allow the
2015 	 * rdata implementations to do it themselves.
2016 	 *
2017 	 * This involves recursion, but the depth is limited.  The
2018 	 * most complex case is adding a SRV rdataset, which involves
2019 	 * recursing to add address records, which in turn can cause
2020 	 * recursion to add KEYs.
2021 	 */
2022 	if (type == dns_rdatatype_srv && trdataset != NULL) {
2023 		/*
2024 		 * If we're adding SRV records to the additional data
2025 		 * section, it's helpful if we add the SRV additional data
2026 		 * as well.
2027 		 */
2028 		eresult = dns_rdataset_additionaldata(
2029 			trdataset, query_additional_cb, qctx);
2030 	}
2031 
2032 cleanup:
2033 	CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: cleanup");
2034 	ns_client_putrdataset(client, &rdataset);
2035 	if (sigrdataset != NULL) {
2036 		ns_client_putrdataset(client, &sigrdataset);
2037 	}
2038 	if (fname != NULL) {
2039 		ns_client_releasename(client, &fname);
2040 	}
2041 	if (node != NULL) {
2042 		dns_db_detachnode(db, &node);
2043 	}
2044 	if (db != NULL) {
2045 		dns_db_detach(&db);
2046 	}
2047 
2048 	CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: done");
2049 	return (eresult);
2050 }
2051 
2052 /*
2053  * Add 'rdataset' to 'name'.
2054  */
2055 static inline void
2056 query_addtoname(dns_name_t *name, dns_rdataset_t *rdataset) {
2057 	ISC_LIST_APPEND(name->list, rdataset, link);
2058 }
2059 
2060 /*
2061  * Set the ordering for 'rdataset'.
2062  */
2063 static void
2064 query_setorder(query_ctx_t *qctx, dns_name_t *name, dns_rdataset_t *rdataset) {
2065 	ns_client_t *client = qctx->client;
2066 	dns_order_t *order = client->view->order;
2067 
2068 	CTRACE(ISC_LOG_DEBUG(3), "query_setorder");
2069 
2070 	UNUSED(client);
2071 
2072 	if (order != NULL) {
2073 		rdataset->attributes |= dns_order_find(
2074 			order, name, rdataset->type, rdataset->rdclass);
2075 	}
2076 	rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
2077 }
2078 
2079 /*
2080  * Handle glue and fetch any other needed additional data for 'rdataset'.
2081  */
2082 static void
2083 query_additional(query_ctx_t *qctx, dns_rdataset_t *rdataset) {
2084 	ns_client_t *client = qctx->client;
2085 	isc_result_t result;
2086 
2087 	CTRACE(ISC_LOG_DEBUG(3), "query_additional");
2088 
2089 	if (NOADDITIONAL(client)) {
2090 		return;
2091 	}
2092 
2093 	/*
2094 	 * Try to process glue directly.
2095 	 */
2096 	if (qctx->view->use_glue_cache &&
2097 	    (rdataset->type == dns_rdatatype_ns) &&
2098 	    (client->query.gluedb != NULL) &&
2099 	    dns_db_iszone(client->query.gluedb))
2100 	{
2101 		ns_dbversion_t *dbversion;
2102 
2103 		dbversion = ns_client_findversion(client, client->query.gluedb);
2104 		if (dbversion == NULL) {
2105 			goto regular;
2106 		}
2107 
2108 		result = dns_rdataset_addglue(rdataset, dbversion->version,
2109 					      client->message);
2110 		if (result == ISC_R_SUCCESS) {
2111 			return;
2112 		}
2113 	}
2114 
2115 regular:
2116 	/*
2117 	 * Add other additional data if needed.
2118 	 * We don't care if dns_rdataset_additionaldata() fails.
2119 	 */
2120 	(void)dns_rdataset_additionaldata(rdataset, query_additional_cb, qctx);
2121 	CTRACE(ISC_LOG_DEBUG(3), "query_additional: done");
2122 }
2123 
2124 static void
2125 query_addrrset(query_ctx_t *qctx, dns_name_t **namep,
2126 	       dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
2127 	       isc_buffer_t *dbuf, dns_section_t section) {
2128 	isc_result_t result;
2129 	ns_client_t *client = qctx->client;
2130 	dns_name_t *name = *namep, *mname = NULL;
2131 	dns_rdataset_t *rdataset = *rdatasetp, *mrdataset = NULL;
2132 	dns_rdataset_t *sigrdataset = NULL;
2133 
2134 	CTRACE(ISC_LOG_DEBUG(3), "query_addrrset");
2135 
2136 	REQUIRE(name != NULL);
2137 
2138 	if (sigrdatasetp != NULL) {
2139 		sigrdataset = *sigrdatasetp;
2140 	}
2141 
2142 	/*%
2143 	 * To the current response for 'client', add the answer RRset
2144 	 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with
2145 	 * owner name '*namep', to section 'section', unless they are
2146 	 * already there.  Also add any pertinent additional data.
2147 	 *
2148 	 * If 'dbuf' is not NULL, then '*namep' is the name whose data is
2149 	 * stored in 'dbuf'.  In this case, query_addrrset() guarantees that
2150 	 * when it returns the name will either have been kept or released.
2151 	 */
2152 	result = dns_message_findname(client->message, section, name,
2153 				      rdataset->type, rdataset->covers, &mname,
2154 				      &mrdataset);
2155 	if (result == ISC_R_SUCCESS) {
2156 		/*
2157 		 * We've already got an RRset of the given name and type.
2158 		 */
2159 		CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: dns_message_findname "
2160 					 "succeeded: done");
2161 		if (dbuf != NULL) {
2162 			ns_client_releasename(client, namep);
2163 		}
2164 		if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0) {
2165 			mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
2166 		}
2167 		return;
2168 	} else if (result == DNS_R_NXDOMAIN) {
2169 		/*
2170 		 * The name doesn't exist.
2171 		 */
2172 		if (dbuf != NULL) {
2173 			ns_client_keepname(client, name, dbuf);
2174 		}
2175 		dns_message_addname(client->message, name, section);
2176 		*namep = NULL;
2177 		mname = name;
2178 	} else {
2179 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
2180 		if (dbuf != NULL) {
2181 			ns_client_releasename(client, namep);
2182 		}
2183 	}
2184 
2185 	if (rdataset->trust != dns_trust_secure &&
2186 	    (section == DNS_SECTION_ANSWER || section == DNS_SECTION_AUTHORITY))
2187 	{
2188 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
2189 	}
2190 
2191 	/*
2192 	 * Update message name, set rdataset order, and do additional
2193 	 * section processing if needed.
2194 	 */
2195 	query_addtoname(mname, rdataset);
2196 	query_setorder(qctx, mname, rdataset);
2197 	query_additional(qctx, rdataset);
2198 
2199 	/*
2200 	 * Note: we only add SIGs if we've added the type they cover, so
2201 	 * we do not need to check if the SIG rdataset is already in the
2202 	 * response.
2203 	 */
2204 	*rdatasetp = NULL;
2205 	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {
2206 		/*
2207 		 * We have a signature.  Add it to the response.
2208 		 */
2209 		ISC_LIST_APPEND(mname->list, sigrdataset, link);
2210 		*sigrdatasetp = NULL;
2211 	}
2212 
2213 	CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: done");
2214 }
2215 
2216 /*
2217  * Mark the RRsets as secure.  Update the cache (db) to reflect the
2218  * change in trust level.
2219  */
2220 static void
2221 mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name,
2222 	    dns_rdata_rrsig_t *rrsig, dns_rdataset_t *rdataset,
2223 	    dns_rdataset_t *sigrdataset) {
2224 	isc_result_t result;
2225 	dns_dbnode_t *node = NULL;
2226 	dns_clientinfomethods_t cm;
2227 	dns_clientinfo_t ci;
2228 	isc_stdtime_t now;
2229 
2230 	rdataset->trust = dns_trust_secure;
2231 	sigrdataset->trust = dns_trust_secure;
2232 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
2233 	dns_clientinfo_init(&ci, client, NULL);
2234 
2235 	/*
2236 	 * Save the updated secure state.  Ignore failures.
2237 	 */
2238 	result = dns_db_findnodeext(db, name, true, &cm, &ci, &node);
2239 	if (result != ISC_R_SUCCESS) {
2240 		return;
2241 	}
2242 
2243 	isc_stdtime_get(&now);
2244 	dns_rdataset_trimttl(rdataset, sigrdataset, rrsig, now,
2245 			     client->view->acceptexpired);
2246 
2247 	(void)dns_db_addrdataset(db, node, NULL, client->now, rdataset, 0,
2248 				 NULL);
2249 	(void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset, 0,
2250 				 NULL);
2251 	dns_db_detachnode(db, &node);
2252 }
2253 
2254 /*
2255  * Find the secure key that corresponds to rrsig.
2256  * Note: 'keyrdataset' maintains state between successive calls,
2257  * there may be multiple keys with the same keyid.
2258  * Return false if we have exhausted all the possible keys.
2259  */
2260 static bool
2261 get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig,
2262 	dns_rdataset_t *keyrdataset, dst_key_t **keyp) {
2263 	isc_result_t result;
2264 	dns_dbnode_t *node = NULL;
2265 	bool secure = false;
2266 	dns_clientinfomethods_t cm;
2267 	dns_clientinfo_t ci;
2268 
2269 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
2270 	dns_clientinfo_init(&ci, client, NULL);
2271 
2272 	if (!dns_rdataset_isassociated(keyrdataset)) {
2273 		result = dns_db_findnodeext(db, &rrsig->signer, false, &cm, &ci,
2274 					    &node);
2275 		if (result != ISC_R_SUCCESS) {
2276 			return (false);
2277 		}
2278 
2279 		result = dns_db_findrdataset(db, node, NULL,
2280 					     dns_rdatatype_dnskey, 0,
2281 					     client->now, keyrdataset, NULL);
2282 		dns_db_detachnode(db, &node);
2283 		if (result != ISC_R_SUCCESS) {
2284 			return (false);
2285 		}
2286 
2287 		if (keyrdataset->trust != dns_trust_secure) {
2288 			return (false);
2289 		}
2290 
2291 		result = dns_rdataset_first(keyrdataset);
2292 	} else {
2293 		result = dns_rdataset_next(keyrdataset);
2294 	}
2295 
2296 	for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(keyrdataset))
2297 	{
2298 		dns_rdata_t rdata = DNS_RDATA_INIT;
2299 		isc_buffer_t b;
2300 
2301 		dns_rdataset_current(keyrdataset, &rdata);
2302 		isc_buffer_init(&b, rdata.data, rdata.length);
2303 		isc_buffer_add(&b, rdata.length);
2304 		result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b,
2305 					 client->mctx, keyp);
2306 		if (result != ISC_R_SUCCESS) {
2307 			continue;
2308 		}
2309 		if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) &&
2310 		    rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) &&
2311 		    dst_key_iszonekey(*keyp))
2312 		{
2313 			secure = true;
2314 			break;
2315 		}
2316 		dst_key_free(keyp);
2317 	}
2318 	return (secure);
2319 }
2320 
2321 static bool
2322 verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset,
2323        dns_rdata_t *rdata, ns_client_t *client) {
2324 	isc_result_t result;
2325 	dns_fixedname_t fixed;
2326 	bool ignore = false;
2327 
2328 	dns_fixedname_init(&fixed);
2329 
2330 again:
2331 	result = dns_dnssec_verify(name, rdataset, key, ignore,
2332 				   client->view->maxbits, client->mctx, rdata,
2333 				   NULL);
2334 	if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) {
2335 		ignore = true;
2336 		goto again;
2337 	}
2338 	if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) {
2339 		return (true);
2340 	}
2341 	return (false);
2342 }
2343 
2344 /*
2345  * Validate the rdataset if possible with available records.
2346  */
2347 static bool
2348 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
2349 	 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
2350 	isc_result_t result;
2351 	dns_rdata_t rdata = DNS_RDATA_INIT;
2352 	dns_rdata_rrsig_t rrsig;
2353 	dst_key_t *key = NULL;
2354 	dns_rdataset_t keyrdataset;
2355 
2356 	if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) {
2357 		return (false);
2358 	}
2359 
2360 	for (result = dns_rdataset_first(sigrdataset); result == ISC_R_SUCCESS;
2361 	     result = dns_rdataset_next(sigrdataset))
2362 	{
2363 		dns_rdata_reset(&rdata);
2364 		dns_rdataset_current(sigrdataset, &rdata);
2365 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
2366 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
2367 		if (!dns_resolver_algorithm_supported(client->view->resolver,
2368 						      name, rrsig.algorithm))
2369 		{
2370 			continue;
2371 		}
2372 		if (!dns_name_issubdomain(name, &rrsig.signer)) {
2373 			continue;
2374 		}
2375 		dns_rdataset_init(&keyrdataset);
2376 		do {
2377 			if (!get_key(client, db, &rrsig, &keyrdataset, &key)) {
2378 				break;
2379 			}
2380 			if (verify(key, name, rdataset, &rdata, client)) {
2381 				dst_key_free(&key);
2382 				dns_rdataset_disassociate(&keyrdataset);
2383 				mark_secure(client, db, name, &rrsig, rdataset,
2384 					    sigrdataset);
2385 				return (true);
2386 			}
2387 			dst_key_free(&key);
2388 		} while (1);
2389 		if (dns_rdataset_isassociated(&keyrdataset)) {
2390 			dns_rdataset_disassociate(&keyrdataset);
2391 		}
2392 	}
2393 	return (false);
2394 }
2395 
2396 static void
2397 fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) {
2398 	if (*rdataset == NULL) {
2399 		*rdataset = ns_client_newrdataset(client);
2400 	} else if (dns_rdataset_isassociated(*rdataset)) {
2401 		dns_rdataset_disassociate(*rdataset);
2402 	}
2403 }
2404 
2405 static void
2406 fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf,
2407 	 isc_buffer_t *nbuf) {
2408 	if (*fname == NULL) {
2409 		*dbuf = ns_client_getnamebuf(client);
2410 		if (*dbuf == NULL) {
2411 			return;
2412 		}
2413 		*fname = ns_client_newname(client, *dbuf, nbuf);
2414 	}
2415 }
2416 
2417 static void
2418 free_devent(ns_client_t *client, isc_event_t **eventp,
2419 	    dns_fetchevent_t **deventp) {
2420 	dns_fetchevent_t *devent = *deventp;
2421 
2422 	REQUIRE((void *)(*eventp) == (void *)(*deventp));
2423 
2424 	CTRACE(ISC_LOG_DEBUG(3), "free_devent");
2425 
2426 	if (devent->fetch != NULL) {
2427 		dns_resolver_destroyfetch(&devent->fetch);
2428 	}
2429 	if (devent->node != NULL) {
2430 		dns_db_detachnode(devent->db, &devent->node);
2431 	}
2432 	if (devent->db != NULL) {
2433 		dns_db_detach(&devent->db);
2434 	}
2435 	if (devent->rdataset != NULL) {
2436 		ns_client_putrdataset(client, &devent->rdataset);
2437 	}
2438 	if (devent->sigrdataset != NULL) {
2439 		ns_client_putrdataset(client, &devent->sigrdataset);
2440 	}
2441 
2442 	/*
2443 	 * If the two pointers are the same then leave the setting of
2444 	 * (*deventp) to NULL to isc_event_free.
2445 	 */
2446 	if ((void *)eventp != (void *)deventp) {
2447 		(*deventp) = NULL;
2448 	}
2449 	isc_event_free(eventp);
2450 }
2451 
2452 static void
2453 prefetch_done(isc_task_t *task, isc_event_t *event) {
2454 	dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
2455 	ns_client_t *client;
2456 
2457 	UNUSED(task);
2458 
2459 	REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
2460 	client = devent->ev_arg;
2461 	REQUIRE(NS_CLIENT_VALID(client));
2462 	REQUIRE(task == client->task);
2463 
2464 	CTRACE(ISC_LOG_DEBUG(3), "prefetch_done");
2465 
2466 	LOCK(&client->query.fetchlock);
2467 	if (client->query.prefetch != NULL) {
2468 		INSIST(devent->fetch == client->query.prefetch);
2469 		client->query.prefetch = NULL;
2470 	}
2471 	UNLOCK(&client->query.fetchlock);
2472 
2473 	/*
2474 	 * We're done prefetching, detach from quota.
2475 	 */
2476 	if (client->recursionquota != NULL) {
2477 		isc_quota_detach(&client->recursionquota);
2478 	}
2479 
2480 	free_devent(client, &event, &devent);
2481 	isc_nmhandle_unref(client->handle);
2482 }
2483 
2484 static void
2485 query_prefetch(ns_client_t *client, dns_name_t *qname,
2486 	       dns_rdataset_t *rdataset) {
2487 	isc_result_t result;
2488 	isc_sockaddr_t *peeraddr;
2489 	dns_rdataset_t *tmprdataset;
2490 	unsigned int options;
2491 
2492 	CTRACE(ISC_LOG_DEBUG(3), "query_prefetch");
2493 
2494 	if (client->query.prefetch != NULL ||
2495 	    client->view->prefetch_trigger == 0U ||
2496 	    rdataset->ttl > client->view->prefetch_trigger ||
2497 	    (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0)
2498 	{
2499 		return;
2500 	}
2501 
2502 	if (client->recursionquota == NULL) {
2503 		result = isc_quota_attach(&client->sctx->recursionquota,
2504 					  &client->recursionquota);
2505 		if (result == ISC_R_SOFTQUOTA) {
2506 			isc_quota_detach(&client->recursionquota);
2507 		}
2508 		if (result != ISC_R_SUCCESS) {
2509 			return;
2510 		}
2511 	}
2512 
2513 	tmprdataset = ns_client_newrdataset(client);
2514 	if (tmprdataset == NULL) {
2515 		return;
2516 	}
2517 
2518 	if (!TCP(client)) {
2519 		peeraddr = &client->peeraddr;
2520 	} else {
2521 		peeraddr = NULL;
2522 	}
2523 
2524 	isc_nmhandle_ref(client->handle);
2525 	options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH;
2526 	result = dns_resolver_createfetch(
2527 		client->view->resolver, qname, rdataset->type, NULL, NULL, NULL,
2528 		peeraddr, client->message->id, options, 0, NULL, client->task,
2529 		prefetch_done, client, tmprdataset, NULL,
2530 		&client->query.prefetch);
2531 	if (result != ISC_R_SUCCESS) {
2532 		ns_client_putrdataset(client, &tmprdataset);
2533 		isc_nmhandle_unref(client->handle);
2534 	}
2535 
2536 	dns_rdataset_clearprefetch(rdataset);
2537 	ns_stats_increment(client->sctx->nsstats, ns_statscounter_prefetch);
2538 }
2539 
2540 static inline void
2541 rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep,
2542 	  dns_rdataset_t **rdatasetp) {
2543 	if (nodep != NULL && *nodep != NULL) {
2544 		REQUIRE(dbp != NULL && *dbp != NULL);
2545 		dns_db_detachnode(*dbp, nodep);
2546 	}
2547 	if (dbp != NULL && *dbp != NULL) {
2548 		dns_db_detach(dbp);
2549 	}
2550 	if (zonep != NULL && *zonep != NULL) {
2551 		dns_zone_detach(zonep);
2552 	}
2553 	if (rdatasetp != NULL && *rdatasetp != NULL &&
2554 	    dns_rdataset_isassociated(*rdatasetp))
2555 	{
2556 		dns_rdataset_disassociate(*rdatasetp);
2557 	}
2558 }
2559 
2560 static inline void
2561 rpz_match_clear(dns_rpz_st_t *st) {
2562 	rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
2563 	st->m.version = NULL;
2564 }
2565 
2566 static inline isc_result_t
2567 rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp) {
2568 	REQUIRE(rdatasetp != NULL);
2569 
2570 	CTRACE(ISC_LOG_DEBUG(3), "rpz_ready");
2571 
2572 	if (*rdatasetp == NULL) {
2573 		*rdatasetp = ns_client_newrdataset(client);
2574 		if (*rdatasetp == NULL) {
2575 			CTRACE(ISC_LOG_ERROR, "rpz_ready: "
2576 					      "ns_client_newrdataset failed");
2577 			return (DNS_R_SERVFAIL);
2578 		}
2579 	} else if (dns_rdataset_isassociated(*rdatasetp)) {
2580 		dns_rdataset_disassociate(*rdatasetp);
2581 	}
2582 	return (ISC_R_SUCCESS);
2583 }
2584 
2585 static void
2586 rpz_st_clear(ns_client_t *client) {
2587 	dns_rpz_st_t *st = client->query.rpz_st;
2588 
2589 	CTRACE(ISC_LOG_DEBUG(3), "rpz_st_clear");
2590 
2591 	if (st->m.rdataset != NULL) {
2592 		ns_client_putrdataset(client, &st->m.rdataset);
2593 	}
2594 	rpz_match_clear(st);
2595 
2596 	rpz_clean(NULL, &st->r.db, NULL, NULL);
2597 	if (st->r.ns_rdataset != NULL) {
2598 		ns_client_putrdataset(client, &st->r.ns_rdataset);
2599 	}
2600 	if (st->r.r_rdataset != NULL) {
2601 		ns_client_putrdataset(client, &st->r.r_rdataset);
2602 	}
2603 
2604 	rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL);
2605 	if (st->q.rdataset != NULL) {
2606 		ns_client_putrdataset(client, &st->q.rdataset);
2607 	}
2608 	if (st->q.sigrdataset != NULL) {
2609 		ns_client_putrdataset(client, &st->q.sigrdataset);
2610 	}
2611 	st->state = 0;
2612 	st->m.type = DNS_RPZ_TYPE_BAD;
2613 	st->m.policy = DNS_RPZ_POLICY_MISS;
2614 	if (st->rpsdb != NULL) {
2615 		dns_db_detach(&st->rpsdb);
2616 	}
2617 }
2618 
2619 static dns_rpz_zbits_t
2620 rpz_get_zbits(ns_client_t *client, dns_rdatatype_t ip_type,
2621 	      dns_rpz_type_t rpz_type) {
2622 	dns_rpz_st_t *st;
2623 	dns_rpz_zbits_t zbits = 0;
2624 
2625 	REQUIRE(client != NULL);
2626 	REQUIRE(client->query.rpz_st != NULL);
2627 
2628 	st = client->query.rpz_st;
2629 
2630 #ifdef USE_DNSRPS
2631 	if (st->popt.dnsrps_enabled) {
2632 		if (st->rpsdb == NULL ||
2633 		    librpz->have_trig(dns_dnsrps_type2trig(rpz_type),
2634 				      ip_type == dns_rdatatype_aaaa,
2635 				      ((rpsdb_t *)st->rpsdb)->rsp))
2636 		{
2637 			return (DNS_RPZ_ALL_ZBITS);
2638 		}
2639 		return (0);
2640 	}
2641 #endif /* ifdef USE_DNSRPS */
2642 
2643 	switch (rpz_type) {
2644 	case DNS_RPZ_TYPE_CLIENT_IP:
2645 		zbits = st->have.client_ip;
2646 		break;
2647 	case DNS_RPZ_TYPE_QNAME:
2648 		zbits = st->have.qname;
2649 		break;
2650 	case DNS_RPZ_TYPE_IP:
2651 		if (ip_type == dns_rdatatype_a) {
2652 			zbits = st->have.ipv4;
2653 		} else if (ip_type == dns_rdatatype_aaaa) {
2654 			zbits = st->have.ipv6;
2655 		} else {
2656 			zbits = st->have.ip;
2657 		}
2658 		break;
2659 	case DNS_RPZ_TYPE_NSDNAME:
2660 		zbits = st->have.nsdname;
2661 		break;
2662 	case DNS_RPZ_TYPE_NSIP:
2663 		if (ip_type == dns_rdatatype_a) {
2664 			zbits = st->have.nsipv4;
2665 		} else if (ip_type == dns_rdatatype_aaaa) {
2666 			zbits = st->have.nsipv6;
2667 		} else {
2668 			zbits = st->have.nsip;
2669 		}
2670 		break;
2671 	default:
2672 		INSIST(0);
2673 		ISC_UNREACHABLE();
2674 	}
2675 
2676 	/*
2677 	 * Choose
2678 	 *	the earliest configured policy zone (rpz->num)
2679 	 *	QNAME over IP over NSDNAME over NSIP (rpz_type)
2680 	 *	the smallest name,
2681 	 *	the longest IP address prefix,
2682 	 *	the lexically smallest address.
2683 	 */
2684 	if (st->m.policy != DNS_RPZ_POLICY_MISS) {
2685 		if (st->m.type >= rpz_type) {
2686 			zbits &= DNS_RPZ_ZMASK(st->m.rpz->num);
2687 		} else {
2688 			zbits &= DNS_RPZ_ZMASK(st->m.rpz->num) >> 1;
2689 		}
2690 	}
2691 
2692 	/*
2693 	 * If the client wants recursion, allow only compatible policies.
2694 	 */
2695 	if (!RECURSIONOK(client)) {
2696 		zbits &= st->popt.no_rd_ok;
2697 	}
2698 
2699 	return (zbits);
2700 }
2701 
2702 static void
2703 query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) {
2704 	isc_result_t result;
2705 	isc_sockaddr_t *peeraddr;
2706 	dns_rdataset_t *tmprdataset;
2707 	unsigned int options;
2708 
2709 	CTRACE(ISC_LOG_DEBUG(3), "query_rpzfetch");
2710 
2711 	if (client->query.prefetch != NULL) {
2712 		return;
2713 	}
2714 
2715 	if (client->recursionquota == NULL) {
2716 		result = isc_quota_attach(&client->sctx->recursionquota,
2717 					  &client->recursionquota);
2718 		if (result == ISC_R_SOFTQUOTA) {
2719 			isc_quota_detach(&client->recursionquota);
2720 		}
2721 		if (result != ISC_R_SUCCESS) {
2722 			return;
2723 		}
2724 	}
2725 
2726 	tmprdataset = ns_client_newrdataset(client);
2727 	if (tmprdataset == NULL) {
2728 		return;
2729 	}
2730 
2731 	if (!TCP(client)) {
2732 		peeraddr = &client->peeraddr;
2733 	} else {
2734 		peeraddr = NULL;
2735 	}
2736 
2737 	options = client->query.fetchoptions;
2738 	isc_nmhandle_ref(client->handle);
2739 	result = dns_resolver_createfetch(
2740 		client->view->resolver, qname, type, NULL, NULL, NULL, peeraddr,
2741 		client->message->id, options, 0, NULL, client->task,
2742 		prefetch_done, client, tmprdataset, NULL,
2743 		&client->query.prefetch);
2744 	if (result != ISC_R_SUCCESS) {
2745 		ns_client_putrdataset(client, &tmprdataset);
2746 		isc_nmhandle_unref(client->handle);
2747 	}
2748 }
2749 
2750 /*
2751  * Get an NS, A, or AAAA rrset related to the response for the client
2752  * to check the contents of that rrset for hits by eligible policy zones.
2753  */
2754 static isc_result_t
2755 rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
2756 	       dns_rpz_type_t rpz_type, dns_db_t **dbp,
2757 	       dns_dbversion_t *version, dns_rdataset_t **rdatasetp,
2758 	       bool resuming) {
2759 	dns_rpz_st_t *st;
2760 	bool is_zone;
2761 	dns_dbnode_t *node;
2762 	dns_fixedname_t fixed;
2763 	dns_name_t *found;
2764 	isc_result_t result;
2765 	dns_clientinfomethods_t cm;
2766 	dns_clientinfo_t ci;
2767 
2768 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rrset_find");
2769 
2770 	st = client->query.rpz_st;
2771 	if ((st->state & DNS_RPZ_RECURSING) != 0) {
2772 		INSIST(st->r.r_type == type);
2773 		INSIST(dns_name_equal(name, st->r_name));
2774 		INSIST(*rdatasetp == NULL ||
2775 		       !dns_rdataset_isassociated(*rdatasetp));
2776 		st->state &= ~DNS_RPZ_RECURSING;
2777 		RESTORE(*dbp, st->r.db);
2778 		if (*rdatasetp != NULL) {
2779 			ns_client_putrdataset(client, rdatasetp);
2780 		}
2781 		RESTORE(*rdatasetp, st->r.r_rdataset);
2782 		result = st->r.r_result;
2783 		if (result == DNS_R_DELEGATION) {
2784 			CTRACE(ISC_LOG_ERROR, "RPZ recursing");
2785 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
2786 				     rpz_type, "rpz_rrset_find(1)", result);
2787 			st->m.policy = DNS_RPZ_POLICY_ERROR;
2788 			result = DNS_R_SERVFAIL;
2789 		}
2790 		return (result);
2791 	}
2792 
2793 	result = rpz_ready(client, rdatasetp);
2794 	if (result != ISC_R_SUCCESS) {
2795 		st->m.policy = DNS_RPZ_POLICY_ERROR;
2796 		return (result);
2797 	}
2798 	if (*dbp != NULL) {
2799 		is_zone = false;
2800 	} else {
2801 		dns_zone_t *zone;
2802 
2803 		version = NULL;
2804 		zone = NULL;
2805 		result = query_getdb(client, name, type, 0, &zone, dbp,
2806 				     &version, &is_zone);
2807 		if (result != ISC_R_SUCCESS) {
2808 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
2809 				     rpz_type, "rpz_rrset_find(2)", result);
2810 			st->m.policy = DNS_RPZ_POLICY_ERROR;
2811 			if (zone != NULL) {
2812 				dns_zone_detach(&zone);
2813 			}
2814 			return (result);
2815 		}
2816 		if (zone != NULL) {
2817 			dns_zone_detach(&zone);
2818 		}
2819 	}
2820 
2821 	node = NULL;
2822 	found = dns_fixedname_initname(&fixed);
2823 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
2824 	dns_clientinfo_init(&ci, client, NULL);
2825 	result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK,
2826 				client->now, &node, found, &cm, &ci, *rdatasetp,
2827 				NULL);
2828 	if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) {
2829 		/*
2830 		 * Try the cache if we're authoritative for an
2831 		 * ancestor but not the domain itself.
2832 		 */
2833 		rpz_clean(NULL, dbp, &node, rdatasetp);
2834 		version = NULL;
2835 		dns_db_attach(client->view->cachedb, dbp);
2836 		result = dns_db_findext(*dbp, name, version, type, 0,
2837 					client->now, &node, found, &cm, &ci,
2838 					*rdatasetp, NULL);
2839 	}
2840 	rpz_clean(NULL, dbp, &node, NULL);
2841 	if (result == DNS_R_DELEGATION) {
2842 		rpz_clean(NULL, NULL, NULL, rdatasetp);
2843 		/*
2844 		 * Recurse for NS rrset or A or AAAA rrset for an NS.
2845 		 * Do not recurse for addresses for the query name.
2846 		 */
2847 		if (rpz_type == DNS_RPZ_TYPE_IP) {
2848 			result = DNS_R_NXRRSET;
2849 		} else if (!client->view->rpzs->p.nsip_wait_recurse) {
2850 			query_rpzfetch(client, name, type);
2851 			result = DNS_R_NXRRSET;
2852 		} else {
2853 			dns_name_copynf(name, st->r_name);
2854 			result = ns_query_recurse(client, type, st->r_name,
2855 						  NULL, NULL, resuming);
2856 			if (result == ISC_R_SUCCESS) {
2857 				st->state |= DNS_RPZ_RECURSING;
2858 				result = DNS_R_DELEGATION;
2859 			}
2860 		}
2861 	}
2862 	return (result);
2863 }
2864 
2865 /*
2866  * Compute a policy owner name, p_name, in a policy zone given the needed
2867  * policy type and the trigger name.
2868  */
2869 static isc_result_t
2870 rpz_get_p_name(ns_client_t *client, dns_name_t *p_name, dns_rpz_zone_t *rpz,
2871 	       dns_rpz_type_t rpz_type, dns_name_t *trig_name) {
2872 	dns_offsets_t prefix_offsets;
2873 	dns_name_t prefix, *suffix;
2874 	unsigned int first, labels;
2875 	isc_result_t result;
2876 
2877 	CTRACE(ISC_LOG_DEBUG(3), "rpz_get_p_name");
2878 
2879 	/*
2880 	 * The policy owner name consists of a suffix depending on the type
2881 	 * and policy zone and a prefix that is the longest possible string
2882 	 * from the trigger name that keesp the resulting policy owner name
2883 	 * from being too long.
2884 	 */
2885 	switch (rpz_type) {
2886 	case DNS_RPZ_TYPE_CLIENT_IP:
2887 		suffix = &rpz->client_ip;
2888 		break;
2889 	case DNS_RPZ_TYPE_QNAME:
2890 		suffix = &rpz->origin;
2891 		break;
2892 	case DNS_RPZ_TYPE_IP:
2893 		suffix = &rpz->ip;
2894 		break;
2895 	case DNS_RPZ_TYPE_NSDNAME:
2896 		suffix = &rpz->nsdname;
2897 		break;
2898 	case DNS_RPZ_TYPE_NSIP:
2899 		suffix = &rpz->nsip;
2900 		break;
2901 	default:
2902 		INSIST(0);
2903 		ISC_UNREACHABLE();
2904 	}
2905 
2906 	/*
2907 	 * Start with relative version of the full trigger name,
2908 	 * and trim enough allow the addition of the suffix.
2909 	 */
2910 	dns_name_init(&prefix, prefix_offsets);
2911 	labels = dns_name_countlabels(trig_name);
2912 	first = 0;
2913 	for (;;) {
2914 		dns_name_getlabelsequence(trig_name, first, labels - first - 1,
2915 					  &prefix);
2916 		result = dns_name_concatenate(&prefix, suffix, p_name, NULL);
2917 		if (result == ISC_R_SUCCESS) {
2918 			break;
2919 		}
2920 		INSIST(result == DNS_R_NAMETOOLONG);
2921 		/*
2922 		 * Trim the trigger name until the combination is not too long.
2923 		 */
2924 		if (labels - first < 2) {
2925 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix,
2926 				     rpz_type, "concatenate()", result);
2927 			return (ISC_R_FAILURE);
2928 		}
2929 		/*
2930 		 * Complain once about trimming the trigger name.
2931 		 */
2932 		if (first == 0) {
2933 			rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix,
2934 				     rpz_type, "concatenate()", result);
2935 		}
2936 		++first;
2937 	}
2938 	return (ISC_R_SUCCESS);
2939 }
2940 
2941 /*
2942  * Look in policy zone rpz for a policy of rpz_type by p_name.
2943  * The self-name (usually the client qname or an NS name) is compared with
2944  * the target of a CNAME policy for the old style passthru encoding.
2945  * If found, the policy is recorded in *zonep, *dbp, *versionp, *nodep,
2946  * *rdatasetp, and *policyp.
2947  * The target DNS type, qtype, chooses the best rdataset for *rdatasetp.
2948  * The caller must decide if the found policy is most suitable, including
2949  * better than a previously found policy.
2950  * If it is best, the caller records it in client->query.rpz_st->m.
2951  */
2952 static isc_result_t
2953 rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype,
2954 	   dns_name_t *p_name, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
2955 	   dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp,
2956 	   dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
2957 	   dns_rpz_policy_t *policyp) {
2958 	dns_fixedname_t foundf;
2959 	dns_name_t *found;
2960 	isc_result_t result;
2961 	dns_clientinfomethods_t cm;
2962 	dns_clientinfo_t ci;
2963 	bool found_a = false;
2964 
2965 	REQUIRE(nodep != NULL);
2966 
2967 	CTRACE(ISC_LOG_DEBUG(3), "rpz_find_p");
2968 
2969 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
2970 	dns_clientinfo_init(&ci, client, NULL);
2971 
2972 	/*
2973 	 * Try to find either a CNAME or the type of record demanded by the
2974 	 * request from the policy zone.
2975 	 */
2976 	rpz_clean(zonep, dbp, nodep, rdatasetp);
2977 	result = rpz_ready(client, rdatasetp);
2978 	if (result != ISC_R_SUCCESS) {
2979 		CTRACE(ISC_LOG_ERROR, "rpz_ready() failed");
2980 		return (DNS_R_SERVFAIL);
2981 	}
2982 	*versionp = NULL;
2983 	result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp);
2984 	if (result != ISC_R_SUCCESS) {
2985 		return (DNS_R_NXDOMAIN);
2986 	}
2987 	found = dns_fixedname_initname(&foundf);
2988 
2989 	result = dns_db_findext(*dbp, p_name, *versionp, dns_rdatatype_any, 0,
2990 				client->now, nodep, found, &cm, &ci, *rdatasetp,
2991 				NULL);
2992 	/*
2993 	 * Choose the best rdataset if we found something.
2994 	 */
2995 	if (result == ISC_R_SUCCESS) {
2996 		dns_rdatasetiter_t *rdsiter;
2997 
2998 		rdsiter = NULL;
2999 		result = dns_db_allrdatasets(*dbp, *nodep, *versionp, 0,
3000 					     &rdsiter);
3001 		if (result != ISC_R_SUCCESS) {
3002 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name,
3003 				     rpz_type, "allrdatasets()", result);
3004 			CTRACE(ISC_LOG_ERROR,
3005 			       "rpz_find_p: allrdatasets failed");
3006 			return (DNS_R_SERVFAIL);
3007 		}
3008 		if (qtype == dns_rdatatype_aaaa &&
3009 		    !ISC_LIST_EMPTY(client->view->dns64)) {
3010 			for (result = dns_rdatasetiter_first(rdsiter);
3011 			     result == ISC_R_SUCCESS;
3012 			     result = dns_rdatasetiter_next(rdsiter))
3013 			{
3014 				dns_rdatasetiter_current(rdsiter, *rdatasetp);
3015 				if ((*rdatasetp)->type == dns_rdatatype_a) {
3016 					found_a = true;
3017 				}
3018 				dns_rdataset_disassociate(*rdatasetp);
3019 			}
3020 		}
3021 		for (result = dns_rdatasetiter_first(rdsiter);
3022 		     result == ISC_R_SUCCESS;
3023 		     result = dns_rdatasetiter_next(rdsiter))
3024 		{
3025 			dns_rdatasetiter_current(rdsiter, *rdatasetp);
3026 			if ((*rdatasetp)->type == dns_rdatatype_cname ||
3027 			    (*rdatasetp)->type == qtype) {
3028 				break;
3029 			}
3030 			dns_rdataset_disassociate(*rdatasetp);
3031 		}
3032 		dns_rdatasetiter_destroy(&rdsiter);
3033 		if (result != ISC_R_SUCCESS) {
3034 			if (result != ISC_R_NOMORE) {
3035 				rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
3036 					     p_name, rpz_type, "rdatasetiter",
3037 					     result);
3038 				CTRACE(ISC_LOG_ERROR, "rpz_find_p: "
3039 						      "rdatasetiter failed");
3040 				return (DNS_R_SERVFAIL);
3041 			}
3042 			/*
3043 			 * Ask again to get the right DNS_R_DNAME/NXRRSET/...
3044 			 * result if there is neither a CNAME nor target type.
3045 			 */
3046 			if (dns_rdataset_isassociated(*rdatasetp)) {
3047 				dns_rdataset_disassociate(*rdatasetp);
3048 			}
3049 			dns_db_detachnode(*dbp, nodep);
3050 
3051 			if (qtype == dns_rdatatype_rrsig ||
3052 			    qtype == dns_rdatatype_sig) {
3053 				result = DNS_R_NXRRSET;
3054 			} else {
3055 				result = dns_db_findext(*dbp, p_name, *versionp,
3056 							qtype, 0, client->now,
3057 							nodep, found, &cm, &ci,
3058 							*rdatasetp, NULL);
3059 			}
3060 		}
3061 	}
3062 	switch (result) {
3063 	case ISC_R_SUCCESS:
3064 		if ((*rdatasetp)->type != dns_rdatatype_cname) {
3065 			*policyp = DNS_RPZ_POLICY_RECORD;
3066 		} else {
3067 			*policyp = dns_rpz_decode_cname(rpz, *rdatasetp,
3068 							self_name);
3069 			if ((*policyp == DNS_RPZ_POLICY_RECORD ||
3070 			     *policyp == DNS_RPZ_POLICY_WILDCNAME) &&
3071 			    qtype != dns_rdatatype_cname &&
3072 			    qtype != dns_rdatatype_any)
3073 			{
3074 				return (DNS_R_CNAME);
3075 			}
3076 		}
3077 		return (ISC_R_SUCCESS);
3078 	case DNS_R_NXRRSET:
3079 		if (found_a) {
3080 			*policyp = DNS_RPZ_POLICY_DNS64;
3081 		} else {
3082 			*policyp = DNS_RPZ_POLICY_NODATA;
3083 		}
3084 		return (result);
3085 	case DNS_R_DNAME:
3086 	/*
3087 	 * DNAME policy RRs have very few if any uses that are not
3088 	 * better served with simple wildcards.  Making them work would
3089 	 * require complications to get the number of labels matched
3090 	 * in the name or the found name to the main DNS_R_DNAME case
3091 	 * in query_dname().  The domain also does not appear in the
3092 	 * summary database at the right level, so this happens only
3093 	 * with a single policy zone when we have no summary database.
3094 	 * Treat it as a miss.
3095 	 */
3096 	case DNS_R_NXDOMAIN:
3097 	case DNS_R_EMPTYNAME:
3098 		return (DNS_R_NXDOMAIN);
3099 	default:
3100 		rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, "",
3101 			     result);
3102 		CTRACE(ISC_LOG_ERROR, "rpz_find_p: unexpected result");
3103 		return (DNS_R_SERVFAIL);
3104 	}
3105 }
3106 
3107 static void
3108 rpz_save_p(dns_rpz_st_t *st, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
3109 	   dns_rpz_policy_t policy, dns_name_t *p_name, dns_rpz_prefix_t prefix,
3110 	   isc_result_t result, dns_zone_t **zonep, dns_db_t **dbp,
3111 	   dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
3112 	   dns_dbversion_t *version) {
3113 	dns_rdataset_t *trdataset = NULL;
3114 
3115 	rpz_match_clear(st);
3116 	st->m.rpz = rpz;
3117 	st->m.type = rpz_type;
3118 	st->m.policy = policy;
3119 	dns_name_copynf(p_name, st->p_name);
3120 	st->m.prefix = prefix;
3121 	st->m.result = result;
3122 	SAVE(st->m.zone, *zonep);
3123 	SAVE(st->m.db, *dbp);
3124 	SAVE(st->m.node, *nodep);
3125 	if (*rdatasetp != NULL && dns_rdataset_isassociated(*rdatasetp)) {
3126 		/*
3127 		 * Save the replacement rdataset from the policy
3128 		 * and make the previous replacement rdataset scratch.
3129 		 */
3130 		SAVE(trdataset, st->m.rdataset);
3131 		SAVE(st->m.rdataset, *rdatasetp);
3132 		SAVE(*rdatasetp, trdataset);
3133 		st->m.ttl = ISC_MIN(st->m.rdataset->ttl, rpz->max_policy_ttl);
3134 	} else {
3135 		st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT, rpz->max_policy_ttl);
3136 	}
3137 	SAVE(st->m.version, version);
3138 }
3139 
3140 #ifdef USE_DNSRPS
3141 /*
3142  * Check the results of a RPZ service interface lookup.
3143  * Stop after an error (<0) or not a hit on a disabled zone (0).
3144  * Continue after a hit on a disabled zone (>0).
3145  */
3146 static int
3147 dnsrps_ck(librpz_emsg_t *emsg, ns_client_t *client, rpsdb_t *rpsdb,
3148 	  bool recursed) {
3149 	isc_region_t region;
3150 	librpz_domain_buf_t pname_buf;
3151 
3152 	if (!librpz->rsp_result(emsg, &rpsdb->result, recursed, rpsdb->rsp)) {
3153 		return (-1);
3154 	}
3155 
3156 	/*
3157 	 * Forget the state from before the IP address or domain check
3158 	 * if the lookup hit nothing.
3159 	 */
3160 	if (rpsdb->result.policy == LIBRPZ_POLICY_UNDEFINED ||
3161 	    rpsdb->result.hit_id != rpsdb->hit_id ||
3162 	    rpsdb->result.policy != LIBRPZ_POLICY_DISABLED)
3163 	{
3164 		if (!librpz->rsp_pop_discard(emsg, rpsdb->rsp)) {
3165 			return (-1);
3166 		}
3167 		return (0);
3168 	}
3169 
3170 	/*
3171 	 * Log a hit on a disabled zone.
3172 	 * Forget the zone to not try it again, and restore the pre-hit state.
3173 	 */
3174 	if (!librpz->rsp_domain(emsg, &pname_buf, rpsdb->rsp)) {
3175 		return (-1);
3176 	}
3177 	region.base = pname_buf.d;
3178 	region.length = pname_buf.size;
3179 	dns_name_fromregion(client->query.rpz_st->p_name, &region);
3180 	rpz_log_rewrite(client, true, dns_dnsrps_2policy(rpsdb->result.zpolicy),
3181 			dns_dnsrps_trig2type(rpsdb->result.trig), NULL,
3182 			client->query.rpz_st->p_name, NULL,
3183 			rpsdb->result.cznum);
3184 
3185 	if (!librpz->rsp_forget_zone(emsg, rpsdb->result.cznum, rpsdb->rsp) ||
3186 	    !librpz->rsp_pop(emsg, &rpsdb->result, rpsdb->rsp))
3187 	{
3188 		return (-1);
3189 	}
3190 	return (1);
3191 }
3192 
3193 /*
3194  * Ready the shim database and rdataset for a DNSRPS hit.
3195  */
3196 static bool
3197 dnsrps_set_p(librpz_emsg_t *emsg, ns_client_t *client, dns_rpz_st_t *st,
3198 	     dns_rdatatype_t qtype, dns_rdataset_t **p_rdatasetp,
3199 	     bool recursed) {
3200 	rpsdb_t *rpsdb;
3201 	librpz_domain_buf_t pname_buf;
3202 	isc_region_t region;
3203 	dns_zone_t *p_zone;
3204 	dns_db_t *p_db;
3205 	dns_dbnode_t *p_node;
3206 	dns_rpz_policy_t policy;
3207 	dns_fixedname_t foundf;
3208 	dns_name_t *found;
3209 	dns_rdatatype_t foundtype, searchtype;
3210 	isc_result_t result;
3211 
3212 	rpsdb = (rpsdb_t *)st->rpsdb;
3213 
3214 	if (!librpz->rsp_result(emsg, &rpsdb->result, recursed, rpsdb->rsp)) {
3215 		return (false);
3216 	}
3217 
3218 	if (rpsdb->result.policy == LIBRPZ_POLICY_UNDEFINED) {
3219 		return (true);
3220 	}
3221 
3222 	/*
3223 	 * Give the fake or shim DNSRPS database its new origin.
3224 	 */
3225 	if (!librpz->rsp_soa(emsg, NULL, NULL, &rpsdb->origin_buf,
3226 			     &rpsdb->result, rpsdb->rsp))
3227 	{
3228 		return (false);
3229 	}
3230 	region.base = rpsdb->origin_buf.d;
3231 	region.length = rpsdb->origin_buf.size;
3232 	dns_name_fromregion(&rpsdb->common.origin, &region);
3233 
3234 	if (!librpz->rsp_domain(emsg, &pname_buf, rpsdb->rsp)) {
3235 		return (false);
3236 	}
3237 	region.base = pname_buf.d;
3238 	region.length = pname_buf.size;
3239 	dns_name_fromregion(st->p_name, &region);
3240 
3241 	p_zone = NULL;
3242 	p_db = NULL;
3243 	p_node = NULL;
3244 	rpz_ready(client, p_rdatasetp);
3245 	dns_db_attach(st->rpsdb, &p_db);
3246 	policy = dns_dnsrps_2policy(rpsdb->result.policy);
3247 	if (policy != DNS_RPZ_POLICY_RECORD) {
3248 		result = ISC_R_SUCCESS;
3249 	} else if (qtype == dns_rdatatype_rrsig) {
3250 		/*
3251 		 * dns_find_db() refuses to look for and fail to
3252 		 * find dns_rdatatype_rrsig.
3253 		 */
3254 		result = DNS_R_NXRRSET;
3255 		policy = DNS_RPZ_POLICY_NODATA;
3256 	} else {
3257 		/*
3258 		 * Get the next (and so first) RR from the policy node.
3259 		 * If it is a CNAME, then look for it regardless of the
3260 		 * query type.
3261 		 */
3262 		if (!librpz->rsp_rr(emsg, &foundtype, NULL, NULL, NULL,
3263 				    &rpsdb->result, rpsdb->qname->ndata,
3264 				    rpsdb->qname->length, rpsdb->rsp))
3265 		{
3266 			return (false);
3267 		}
3268 		if (foundtype == dns_rdatatype_cname) {
3269 			searchtype = dns_rdatatype_cname;
3270 		} else {
3271 			searchtype = qtype;
3272 		}
3273 		/*
3274 		 * Get the DNSPRS imitation rdataset.
3275 		 */
3276 		found = dns_fixedname_initname(&foundf);
3277 		result = dns_db_find(p_db, st->p_name, NULL, searchtype, 0, 0,
3278 				     &p_node, found, *p_rdatasetp, NULL);
3279 
3280 		if (result == ISC_R_SUCCESS) {
3281 			if (searchtype == dns_rdatatype_cname &&
3282 			    qtype != dns_rdatatype_cname) {
3283 				result = DNS_R_CNAME;
3284 			}
3285 		} else if (result == DNS_R_NXRRSET) {
3286 			policy = DNS_RPZ_POLICY_NODATA;
3287 		} else {
3288 			snprintf(emsg->c, sizeof(emsg->c), "dns_db_find(): %s",
3289 				 isc_result_totext(result));
3290 			return (false);
3291 		}
3292 	}
3293 
3294 	rpz_save_p(st, client->view->rpzs->zones[rpsdb->result.cznum],
3295 		   dns_dnsrps_trig2type(rpsdb->result.trig), policy, st->p_name,
3296 		   0, result, &p_zone, &p_db, &p_node, p_rdatasetp, NULL);
3297 
3298 	rpz_clean(NULL, NULL, NULL, p_rdatasetp);
3299 
3300 	return (true);
3301 }
3302 
3303 static isc_result_t
3304 dnsrps_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr,
3305 		  dns_rpz_type_t rpz_type, dns_rdataset_t **p_rdatasetp) {
3306 	dns_rpz_st_t *st;
3307 	rpsdb_t *rpsdb;
3308 	librpz_trig_t trig = LIBRPZ_TRIG_CLIENT_IP;
3309 	bool recursed = false;
3310 	int res;
3311 	librpz_emsg_t emsg;
3312 	isc_result_t result;
3313 
3314 	st = client->query.rpz_st;
3315 	rpsdb = (rpsdb_t *)st->rpsdb;
3316 
3317 	result = rpz_ready(client, p_rdatasetp);
3318 	if (result != ISC_R_SUCCESS) {
3319 		st->m.policy = DNS_RPZ_POLICY_ERROR;
3320 		return (result);
3321 	}
3322 
3323 	switch (rpz_type) {
3324 	case DNS_RPZ_TYPE_CLIENT_IP:
3325 		trig = LIBRPZ_TRIG_CLIENT_IP;
3326 		recursed = false;
3327 		break;
3328 	case DNS_RPZ_TYPE_IP:
3329 		trig = LIBRPZ_TRIG_IP;
3330 		recursed = true;
3331 		break;
3332 	case DNS_RPZ_TYPE_NSIP:
3333 		trig = LIBRPZ_TRIG_NSIP;
3334 		recursed = true;
3335 		break;
3336 	default:
3337 		INSIST(0);
3338 		ISC_UNREACHABLE();
3339 	}
3340 
3341 	do {
3342 		if (!librpz->rsp_push(&emsg, rpsdb->rsp) ||
3343 		    !librpz->ck_ip(&emsg,
3344 				   netaddr->family == AF_INET
3345 					   ? (const void *)&netaddr->type.in
3346 					   : (const void *)&netaddr->type.in6,
3347 				   netaddr->family, trig, ++rpsdb->hit_id,
3348 				   recursed, rpsdb->rsp) ||
3349 		    (res = dnsrps_ck(&emsg, client, rpsdb, recursed)) < 0)
3350 		{
3351 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
3352 				     rpz_type, emsg.c, DNS_R_SERVFAIL);
3353 			st->m.policy = DNS_RPZ_POLICY_ERROR;
3354 			return (DNS_R_SERVFAIL);
3355 		}
3356 	} while (res != 0);
3357 	return (ISC_R_SUCCESS);
3358 }
3359 
3360 static isc_result_t
3361 dnsrps_rewrite_name(ns_client_t *client, dns_name_t *trig_name, bool recursed,
3362 		    dns_rpz_type_t rpz_type, dns_rdataset_t **p_rdatasetp) {
3363 	dns_rpz_st_t *st;
3364 	rpsdb_t *rpsdb;
3365 	librpz_trig_t trig = LIBRPZ_TRIG_CLIENT_IP;
3366 	isc_region_t r;
3367 	int res;
3368 	librpz_emsg_t emsg;
3369 	isc_result_t result;
3370 
3371 	st = client->query.rpz_st;
3372 	rpsdb = (rpsdb_t *)st->rpsdb;
3373 
3374 	result = rpz_ready(client, p_rdatasetp);
3375 	if (result != ISC_R_SUCCESS) {
3376 		st->m.policy = DNS_RPZ_POLICY_ERROR;
3377 		return (result);
3378 	}
3379 
3380 	switch (rpz_type) {
3381 	case DNS_RPZ_TYPE_QNAME:
3382 		trig = LIBRPZ_TRIG_QNAME;
3383 		break;
3384 	case DNS_RPZ_TYPE_NSDNAME:
3385 		trig = LIBRPZ_TRIG_NSDNAME;
3386 		break;
3387 	default:
3388 		INSIST(0);
3389 		ISC_UNREACHABLE();
3390 	}
3391 
3392 	dns_name_toregion(trig_name, &r);
3393 	do {
3394 		if (!librpz->rsp_push(&emsg, rpsdb->rsp) ||
3395 		    !librpz->ck_domain(&emsg, r.base, r.length, trig,
3396 				       ++rpsdb->hit_id, recursed, rpsdb->rsp) ||
3397 		    (res = dnsrps_ck(&emsg, client, rpsdb, recursed)) < 0)
3398 		{
3399 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
3400 				     rpz_type, emsg.c, DNS_R_SERVFAIL);
3401 			st->m.policy = DNS_RPZ_POLICY_ERROR;
3402 			return (DNS_R_SERVFAIL);
3403 		}
3404 	} while (res != 0);
3405 	return (ISC_R_SUCCESS);
3406 }
3407 #endif /* USE_DNSRPS */
3408 
3409 /*
3410  * Check this address in every eligible policy zone.
3411  */
3412 static isc_result_t
3413 rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr,
3414 	       dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
3415 	       dns_rpz_zbits_t zbits, dns_rdataset_t **p_rdatasetp) {
3416 	dns_rpz_zones_t *rpzs;
3417 	dns_rpz_st_t *st;
3418 	dns_rpz_zone_t *rpz;
3419 	dns_rpz_prefix_t prefix;
3420 	dns_rpz_num_t rpz_num;
3421 	dns_fixedname_t ip_namef, p_namef;
3422 	dns_name_t *ip_name, *p_name;
3423 	dns_zone_t *p_zone;
3424 	dns_db_t *p_db;
3425 	dns_dbversion_t *p_version;
3426 	dns_dbnode_t *p_node;
3427 	dns_rpz_policy_t policy;
3428 	isc_result_t result;
3429 
3430 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip");
3431 
3432 	rpzs = client->view->rpzs;
3433 	st = client->query.rpz_st;
3434 #ifdef USE_DNSRPS
3435 	if (st->popt.dnsrps_enabled) {
3436 		return (dnsrps_rewrite_ip(client, netaddr, rpz_type,
3437 					  p_rdatasetp));
3438 	}
3439 #endif /* ifdef USE_DNSRPS */
3440 
3441 	ip_name = dns_fixedname_initname(&ip_namef);
3442 
3443 	p_zone = NULL;
3444 	p_db = NULL;
3445 	p_node = NULL;
3446 
3447 	while (zbits != 0) {
3448 		rpz_num = dns_rpz_find_ip(rpzs, rpz_type, zbits, netaddr,
3449 					  ip_name, &prefix);
3450 		if (rpz_num == DNS_RPZ_INVALID_NUM) {
3451 			break;
3452 		}
3453 		zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1);
3454 
3455 		/*
3456 		 * Do not try applying policy zones that cannot replace a
3457 		 * previously found policy zone.
3458 		 * Stop looking if the next best choice cannot
3459 		 * replace what we already have.
3460 		 */
3461 		rpz = rpzs->zones[rpz_num];
3462 		if (st->m.policy != DNS_RPZ_POLICY_MISS) {
3463 			if (st->m.rpz->num < rpz->num) {
3464 				break;
3465 			}
3466 			if (st->m.rpz->num == rpz->num &&
3467 			    (st->m.type < rpz_type || st->m.prefix > prefix))
3468 			{
3469 				break;
3470 			}
3471 		}
3472 
3473 		/*
3474 		 * Get the policy for a prefix at least as long
3475 		 * as the prefix of the entry we had before.
3476 		 */
3477 		p_name = dns_fixedname_initname(&p_namef);
3478 		result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name);
3479 		if (result != ISC_R_SUCCESS) {
3480 			continue;
3481 		}
3482 		result = rpz_find_p(client, ip_name, qtype, p_name, rpz,
3483 				    rpz_type, &p_zone, &p_db, &p_version,
3484 				    &p_node, p_rdatasetp, &policy);
3485 		switch (result) {
3486 		case DNS_R_NXDOMAIN:
3487 			/*
3488 			 * Continue after a policy record that is missing
3489 			 * contrary to the summary data.  The summary
3490 			 * data can out of date during races with and among
3491 			 * policy zone updates.
3492 			 */
3493 			CTRACE(ISC_LOG_ERROR, "rpz_rewrite_ip: mismatched "
3494 					      "summary data; "
3495 					      "continuing");
3496 			continue;
3497 		case DNS_R_SERVFAIL:
3498 			rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
3499 			st->m.policy = DNS_RPZ_POLICY_ERROR;
3500 			return (DNS_R_SERVFAIL);
3501 		default:
3502 			/*
3503 			 * Forget this policy if it is not preferable
3504 			 * to the previously found policy.
3505 			 * If this policy is not good, then stop looking
3506 			 * because none of the later policy zones would work.
3507 			 *
3508 			 * With more than one applicable policy, prefer
3509 			 * the earliest configured policy,
3510 			 * client-IP over QNAME over IP over NSDNAME over NSIP,
3511 			 * the longest prefix
3512 			 * the lexically smallest address.
3513 			 * dns_rpz_find_ip() ensures st->m.rpz->num >= rpz->num.
3514 			 * We can compare new and current p_name because
3515 			 * both are of the same type and in the same zone.
3516 			 * The tests above eliminate other reasons to
3517 			 * reject this policy.  If this policy can't work,
3518 			 * then neither can later zones.
3519 			 */
3520 			if (st->m.policy != DNS_RPZ_POLICY_MISS &&
3521 			    rpz->num == st->m.rpz->num &&
3522 			    (st->m.type == rpz_type && st->m.prefix == prefix &&
3523 			     0 > dns_name_rdatacompare(st->p_name, p_name)))
3524 			{
3525 				break;
3526 			}
3527 
3528 			/*
3529 			 * Stop checking after saving an enabled hit in this
3530 			 * policy zone.  The radix tree in the policy zone
3531 			 * ensures that we found the longest match.
3532 			 */
3533 			if (rpz->policy != DNS_RPZ_POLICY_DISABLED) {
3534 				CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip: "
3535 							 "rpz_save_p");
3536 				rpz_save_p(st, rpz, rpz_type, policy, p_name,
3537 					   prefix, result, &p_zone, &p_db,
3538 					   &p_node, p_rdatasetp, p_version);
3539 				break;
3540 			}
3541 
3542 			/*
3543 			 * Log DNS_RPZ_POLICY_DISABLED zones
3544 			 * and try the next eligible policy zone.
3545 			 */
3546 			rpz_log_rewrite(client, true, policy, rpz_type, p_zone,
3547 					p_name, NULL, rpz_num);
3548 		}
3549 	}
3550 
3551 	rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
3552 	return (ISC_R_SUCCESS);
3553 }
3554 
3555 /*
3556  * Check the IP addresses in the A or AAAA rrsets for name against
3557  * all eligible rpz_type (IP or NSIP) response policy rewrite rules.
3558  */
3559 static isc_result_t
3560 rpz_rewrite_ip_rrset(ns_client_t *client, dns_name_t *name,
3561 		     dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
3562 		     dns_rdatatype_t ip_type, dns_db_t **ip_dbp,
3563 		     dns_dbversion_t *ip_version, dns_rdataset_t **ip_rdatasetp,
3564 		     dns_rdataset_t **p_rdatasetp, bool resuming) {
3565 	dns_rpz_zbits_t zbits;
3566 	isc_netaddr_t netaddr;
3567 	struct in_addr ina;
3568 	struct in6_addr in6a;
3569 	isc_result_t result;
3570 
3571 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrset");
3572 
3573 	zbits = rpz_get_zbits(client, ip_type, rpz_type);
3574 	if (zbits == 0) {
3575 		return (ISC_R_SUCCESS);
3576 	}
3577 
3578 	/*
3579 	 * Get the A or AAAA rdataset.
3580 	 */
3581 	result = rpz_rrset_find(client, name, ip_type, rpz_type, ip_dbp,
3582 				ip_version, ip_rdatasetp, resuming);
3583 	switch (result) {
3584 	case ISC_R_SUCCESS:
3585 	case DNS_R_GLUE:
3586 	case DNS_R_ZONECUT:
3587 		break;
3588 	case DNS_R_EMPTYNAME:
3589 	case DNS_R_EMPTYWILD:
3590 	case DNS_R_NXDOMAIN:
3591 	case DNS_R_NCACHENXDOMAIN:
3592 	case DNS_R_NXRRSET:
3593 	case DNS_R_NCACHENXRRSET:
3594 	case ISC_R_NOTFOUND:
3595 		return (ISC_R_SUCCESS);
3596 	case DNS_R_DELEGATION:
3597 	case DNS_R_DUPLICATE:
3598 	case DNS_R_DROP:
3599 		return (result);
3600 	case DNS_R_CNAME:
3601 	case DNS_R_DNAME:
3602 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name, rpz_type,
3603 			     "NS address rewrite rrset", result);
3604 		return (ISC_R_SUCCESS);
3605 	default:
3606 		if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) {
3607 			client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR;
3608 			rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
3609 				     rpz_type, "NS address rewrite rrset",
3610 				     result);
3611 		}
3612 		CTRACE(ISC_LOG_ERROR, "rpz_rewrite_ip_rrset: unexpected "
3613 				      "result");
3614 		return (DNS_R_SERVFAIL);
3615 	}
3616 
3617 	/*
3618 	 * Check all of the IP addresses in the rdataset.
3619 	 */
3620 	for (result = dns_rdataset_first(*ip_rdatasetp);
3621 	     result == ISC_R_SUCCESS; result = dns_rdataset_next(*ip_rdatasetp))
3622 	{
3623 		dns_rdata_t rdata = DNS_RDATA_INIT;
3624 		dns_rdataset_current(*ip_rdatasetp, &rdata);
3625 		switch (rdata.type) {
3626 		case dns_rdatatype_a:
3627 			INSIST(rdata.length == 4);
3628 			memmove(&ina.s_addr, rdata.data, 4);
3629 			isc_netaddr_fromin(&netaddr, &ina);
3630 			break;
3631 		case dns_rdatatype_aaaa:
3632 			INSIST(rdata.length == 16);
3633 			memmove(in6a.s6_addr, rdata.data, 16);
3634 			isc_netaddr_fromin6(&netaddr, &in6a);
3635 			break;
3636 		default:
3637 			continue;
3638 		}
3639 
3640 		result = rpz_rewrite_ip(client, &netaddr, qtype, rpz_type,
3641 					zbits, p_rdatasetp);
3642 		if (result != ISC_R_SUCCESS) {
3643 			return (result);
3644 		}
3645 	}
3646 
3647 	return (ISC_R_SUCCESS);
3648 }
3649 
3650 /*
3651  * Look for IP addresses in A and AAAA rdatasets
3652  * that trigger all eligible IP or NSIP policy rules.
3653  */
3654 static isc_result_t
3655 rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name,
3656 		      dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
3657 		      dns_rdataset_t **ip_rdatasetp, bool resuming) {
3658 	dns_rpz_st_t *st;
3659 	dns_dbversion_t *ip_version;
3660 	dns_db_t *ip_db;
3661 	dns_rdataset_t *p_rdataset;
3662 	isc_result_t result;
3663 
3664 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrsets");
3665 
3666 	st = client->query.rpz_st;
3667 	ip_version = NULL;
3668 	ip_db = NULL;
3669 	p_rdataset = NULL;
3670 	if ((st->state & DNS_RPZ_DONE_IPv4) == 0 &&
3671 	    (qtype == dns_rdatatype_a || qtype == dns_rdatatype_any ||
3672 	     rpz_type == DNS_RPZ_TYPE_NSIP))
3673 	{
3674 		/*
3675 		 * Rewrite based on an IPv4 address that will appear
3676 		 * in the ANSWER section or if we are checking IP addresses.
3677 		 */
3678 		result = rpz_rewrite_ip_rrset(
3679 			client, name, qtype, rpz_type, dns_rdatatype_a, &ip_db,
3680 			ip_version, ip_rdatasetp, &p_rdataset, resuming);
3681 		if (result == ISC_R_SUCCESS) {
3682 			st->state |= DNS_RPZ_DONE_IPv4;
3683 		}
3684 	} else {
3685 		result = ISC_R_SUCCESS;
3686 	}
3687 	if (result == ISC_R_SUCCESS &&
3688 	    (qtype == dns_rdatatype_aaaa || qtype == dns_rdatatype_any ||
3689 	     rpz_type == DNS_RPZ_TYPE_NSIP))
3690 	{
3691 		/*
3692 		 * Rewrite based on IPv6 addresses that will appear
3693 		 * in the ANSWER section or if we are checking IP addresses.
3694 		 */
3695 		result = rpz_rewrite_ip_rrset(client, name, qtype, rpz_type,
3696 					      dns_rdatatype_aaaa, &ip_db,
3697 					      ip_version, ip_rdatasetp,
3698 					      &p_rdataset, resuming);
3699 	}
3700 	if (ip_db != NULL) {
3701 		dns_db_detach(&ip_db);
3702 	}
3703 	ns_client_putrdataset(client, &p_rdataset);
3704 	return (result);
3705 }
3706 
3707 /*
3708  * Try to rewrite a request for a qtype rdataset based on the trigger name
3709  * trig_name and rpz_type (DNS_RPZ_TYPE_QNAME or DNS_RPZ_TYPE_NSDNAME).
3710  * Record the results including the replacement rdataset if any
3711  * in client->query.rpz_st.
3712  * *rdatasetp is a scratch rdataset.
3713  */
3714 static isc_result_t
3715 rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name,
3716 		 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type,
3717 		 dns_rpz_zbits_t allowed_zbits, bool recursed,
3718 		 dns_rdataset_t **rdatasetp) {
3719 	dns_rpz_zones_t *rpzs;
3720 	dns_rpz_zone_t *rpz;
3721 	dns_rpz_st_t *st;
3722 	dns_fixedname_t p_namef;
3723 	dns_name_t *p_name;
3724 	dns_rpz_zbits_t zbits;
3725 	dns_rpz_num_t rpz_num;
3726 	dns_zone_t *p_zone;
3727 	dns_db_t *p_db;
3728 	dns_dbversion_t *p_version;
3729 	dns_dbnode_t *p_node;
3730 	dns_rpz_policy_t policy;
3731 	isc_result_t result;
3732 
3733 #ifndef USE_DNSRPS
3734 	UNUSED(recursed);
3735 #endif /* ifndef USE_DNSRPS */
3736 
3737 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_name");
3738 
3739 	rpzs = client->view->rpzs;
3740 	st = client->query.rpz_st;
3741 
3742 #ifdef USE_DNSRPS
3743 	if (st->popt.dnsrps_enabled) {
3744 		return (dnsrps_rewrite_name(client, trig_name, recursed,
3745 					    rpz_type, rdatasetp));
3746 	}
3747 #endif /* ifdef USE_DNSRPS */
3748 
3749 	zbits = rpz_get_zbits(client, qtype, rpz_type);
3750 	zbits &= allowed_zbits;
3751 	if (zbits == 0) {
3752 		return (ISC_R_SUCCESS);
3753 	}
3754 
3755 	/*
3756 	 * Use the summary database to find the bit mask of policy zones
3757 	 * with policies for this trigger name. We do this even if there
3758 	 * is only one eligible policy zone so that wildcard triggers
3759 	 * are matched correctly, and not into their parent.
3760 	 */
3761 	zbits = dns_rpz_find_name(rpzs, rpz_type, zbits, trig_name);
3762 	if (zbits == 0) {
3763 		return (ISC_R_SUCCESS);
3764 	}
3765 
3766 	p_name = dns_fixedname_initname(&p_namef);
3767 
3768 	p_zone = NULL;
3769 	p_db = NULL;
3770 	p_node = NULL;
3771 
3772 	/*
3773 	 * Check the trigger name in every policy zone that the summary data
3774 	 * says has a hit for the trigger name.
3775 	 * Most of the time there are no eligible zones and the summary data
3776 	 * keeps us from getting this far.
3777 	 * We check the most eligible zone first and so usually check only
3778 	 * one policy zone.
3779 	 */
3780 	for (rpz_num = 0; zbits != 0; ++rpz_num, zbits >>= 1) {
3781 		if ((zbits & 1) == 0) {
3782 			continue;
3783 		}
3784 
3785 		/*
3786 		 * Do not check policy zones that cannot replace a previously
3787 		 * found policy.
3788 		 */
3789 		rpz = rpzs->zones[rpz_num];
3790 		if (st->m.policy != DNS_RPZ_POLICY_MISS) {
3791 			if (st->m.rpz->num < rpz->num) {
3792 				break;
3793 			}
3794 			if (st->m.rpz->num == rpz->num && st->m.type < rpz_type)
3795 			{
3796 				break;
3797 			}
3798 		}
3799 
3800 		/*
3801 		 * Get the next policy zone's record for this trigger name.
3802 		 */
3803 		result = rpz_get_p_name(client, p_name, rpz, rpz_type,
3804 					trig_name);
3805 		if (result != ISC_R_SUCCESS) {
3806 			continue;
3807 		}
3808 		result = rpz_find_p(client, trig_name, qtype, p_name, rpz,
3809 				    rpz_type, &p_zone, &p_db, &p_version,
3810 				    &p_node, rdatasetp, &policy);
3811 		switch (result) {
3812 		case DNS_R_NXDOMAIN:
3813 			/*
3814 			 * Continue after a missing policy record
3815 			 * contrary to the summary data.  The summary
3816 			 * data can out of date during races with and among
3817 			 * policy zone updates.
3818 			 */
3819 			CTRACE(ISC_LOG_ERROR, "rpz_rewrite_name: mismatched "
3820 					      "summary data; "
3821 					      "continuing");
3822 			continue;
3823 		case DNS_R_SERVFAIL:
3824 			rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
3825 			st->m.policy = DNS_RPZ_POLICY_ERROR;
3826 			return (DNS_R_SERVFAIL);
3827 		default:
3828 			/*
3829 			 * With more than one applicable policy, prefer
3830 			 * the earliest configured policy,
3831 			 * client-IP over QNAME over IP over NSDNAME over NSIP,
3832 			 * and the smallest name.
3833 			 * We known st->m.rpz->num >= rpz->num  and either
3834 			 * st->m.rpz->num > rpz->num or st->m.type >= rpz_type
3835 			 */
3836 			if (st->m.policy != DNS_RPZ_POLICY_MISS &&
3837 			    rpz->num == st->m.rpz->num &&
3838 			    (st->m.type < rpz_type ||
3839 			     (st->m.type == rpz_type &&
3840 			      0 >= dns_name_compare(p_name, st->p_name))))
3841 			{
3842 				continue;
3843 			}
3844 
3845 			if (rpz->policy != DNS_RPZ_POLICY_DISABLED) {
3846 				CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_name: "
3847 							 "rpz_save_p");
3848 				rpz_save_p(st, rpz, rpz_type, policy, p_name, 0,
3849 					   result, &p_zone, &p_db, &p_node,
3850 					   rdatasetp, p_version);
3851 				/*
3852 				 * After a hit, higher numbered policy zones
3853 				 * are irrelevant
3854 				 */
3855 				rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
3856 				return (ISC_R_SUCCESS);
3857 			}
3858 			/*
3859 			 * Log DNS_RPZ_POLICY_DISABLED zones
3860 			 * and try the next eligible policy zone.
3861 			 */
3862 			rpz_log_rewrite(client, true, policy, rpz_type, p_zone,
3863 					p_name, NULL, rpz_num);
3864 			break;
3865 		}
3866 	}
3867 
3868 	rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
3869 	return (ISC_R_SUCCESS);
3870 }
3871 
3872 static void
3873 rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname,
3874 		    isc_result_t result, int level, const char *str) {
3875 	dns_rpz_st_t *st;
3876 
3877 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ns_skip");
3878 
3879 	st = client->query.rpz_st;
3880 
3881 	if (str != NULL) {
3882 		rpz_log_fail_helper(client, level, nsname, DNS_RPZ_TYPE_NSIP,
3883 				    DNS_RPZ_TYPE_NSDNAME, str, result);
3884 	}
3885 	if (st->r.ns_rdataset != NULL &&
3886 	    dns_rdataset_isassociated(st->r.ns_rdataset)) {
3887 		dns_rdataset_disassociate(st->r.ns_rdataset);
3888 	}
3889 
3890 	st->r.label--;
3891 }
3892 
3893 /*
3894  * RPZ query result types
3895  */
3896 typedef enum {
3897 	qresult_type_done = 0,
3898 	qresult_type_restart = 1,
3899 	qresult_type_recurse = 2
3900 } qresult_type_t;
3901 
3902 /*
3903  * Look for response policy zone QNAME, NSIP, and NSDNAME rewriting.
3904  */
3905 static isc_result_t
3906 rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult,
3907 	    bool resuming, dns_rdataset_t *ordataset, dns_rdataset_t *osigset) {
3908 	dns_rpz_zones_t *rpzs;
3909 	dns_rpz_st_t *st;
3910 	dns_rdataset_t *rdataset;
3911 	dns_fixedname_t nsnamef;
3912 	dns_name_t *nsname;
3913 	qresult_type_t qresult_type;
3914 	dns_rpz_zbits_t zbits;
3915 	isc_result_t result = ISC_R_SUCCESS;
3916 	dns_rpz_have_t have;
3917 	dns_rpz_popt_t popt;
3918 	int rpz_ver;
3919 #ifdef USE_DNSRPS
3920 	librpz_emsg_t emsg;
3921 #endif /* ifdef USE_DNSRPS */
3922 
3923 	CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite");
3924 
3925 	rpzs = client->view->rpzs;
3926 	st = client->query.rpz_st;
3927 
3928 	if (rpzs == NULL ||
3929 	    (st != NULL && (st->state & DNS_RPZ_REWRITTEN) != 0)) {
3930 		return (DNS_R_DISALLOWED);
3931 	}
3932 
3933 	RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
3934 	if ((rpzs->p.num_zones == 0 && !rpzs->p.dnsrps_enabled) ||
3935 	    (!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) ||
3936 	    !rpz_ck_dnssec(client, qresult, ordataset, osigset))
3937 	{
3938 		RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
3939 		return (DNS_R_DISALLOWED);
3940 	}
3941 	have = rpzs->have;
3942 	popt = rpzs->p;
3943 	rpz_ver = rpzs->rpz_ver;
3944 	RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
3945 
3946 #ifndef USE_DNSRPS
3947 	INSIST(!popt.dnsrps_enabled);
3948 #endif /* ifndef USE_DNSRPS */
3949 
3950 	if (st == NULL) {
3951 		st = isc_mem_get(client->mctx, sizeof(*st));
3952 		st->state = 0;
3953 		st->rpsdb = NULL;
3954 	}
3955 	if (st->state == 0) {
3956 		st->state |= DNS_RPZ_ACTIVE;
3957 		memset(&st->m, 0, sizeof(st->m));
3958 		st->m.type = DNS_RPZ_TYPE_BAD;
3959 		st->m.policy = DNS_RPZ_POLICY_MISS;
3960 		st->m.ttl = ~0;
3961 		memset(&st->r, 0, sizeof(st->r));
3962 		memset(&st->q, 0, sizeof(st->q));
3963 		st->p_name = dns_fixedname_initname(&st->_p_namef);
3964 		st->r_name = dns_fixedname_initname(&st->_r_namef);
3965 		st->fname = dns_fixedname_initname(&st->_fnamef);
3966 		st->have = have;
3967 		st->popt = popt;
3968 		st->rpz_ver = rpz_ver;
3969 		client->query.rpz_st = st;
3970 #ifdef USE_DNSRPS
3971 		if (popt.dnsrps_enabled) {
3972 			if (st->rpsdb != NULL) {
3973 				dns_db_detach(&st->rpsdb);
3974 			}
3975 			result = dns_dnsrps_rewrite_init(
3976 				&emsg, st, rpzs, client->query.qname,
3977 				client->mctx, RECURSIONOK(client));
3978 			if (result != ISC_R_SUCCESS) {
3979 				rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
3980 					     DNS_RPZ_TYPE_QNAME, emsg.c,
3981 					     result);
3982 				st->m.policy = DNS_RPZ_POLICY_ERROR;
3983 				return (ISC_R_SUCCESS);
3984 			}
3985 		}
3986 #endif /* ifdef USE_DNSRPS */
3987 	}
3988 
3989 	/*
3990 	 * There is nothing to rewrite if the main query failed.
3991 	 */
3992 	switch (qresult) {
3993 	case ISC_R_SUCCESS:
3994 	case DNS_R_GLUE:
3995 	case DNS_R_ZONECUT:
3996 		qresult_type = qresult_type_done;
3997 		break;
3998 	case DNS_R_EMPTYNAME:
3999 	case DNS_R_NXRRSET:
4000 	case DNS_R_NXDOMAIN:
4001 	case DNS_R_EMPTYWILD:
4002 	case DNS_R_NCACHENXDOMAIN:
4003 	case DNS_R_NCACHENXRRSET:
4004 	case DNS_R_COVERINGNSEC:
4005 	case DNS_R_CNAME:
4006 	case DNS_R_DNAME:
4007 		qresult_type = qresult_type_restart;
4008 		break;
4009 	case DNS_R_DELEGATION:
4010 	case ISC_R_NOTFOUND:
4011 		/*
4012 		 * If recursion is on, do only tentative rewriting.
4013 		 * If recursion is off, this the normal and only time we
4014 		 * can rewrite.
4015 		 */
4016 		if (RECURSIONOK(client)) {
4017 			qresult_type = qresult_type_recurse;
4018 		} else {
4019 			qresult_type = qresult_type_restart;
4020 		}
4021 		break;
4022 	case ISC_R_FAILURE:
4023 	case ISC_R_TIMEDOUT:
4024 	case DNS_R_BROKENCHAIN:
4025 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, NULL,
4026 			     DNS_RPZ_TYPE_QNAME,
4027 			     "stop on qresult in rpz_rewrite()", qresult);
4028 		return (ISC_R_SUCCESS);
4029 	default:
4030 		rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, NULL,
4031 			     DNS_RPZ_TYPE_QNAME,
4032 			     "stop on unrecognized qresult in rpz_rewrite()",
4033 			     qresult);
4034 		return (ISC_R_SUCCESS);
4035 	}
4036 
4037 	rdataset = NULL;
4038 
4039 	if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) !=
4040 	    (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME))
4041 	{
4042 		isc_netaddr_t netaddr;
4043 		dns_rpz_zbits_t allowed;
4044 
4045 		if (!st->popt.dnsrps_enabled &&
4046 		    qresult_type == qresult_type_recurse) {
4047 			/*
4048 			 * This request needs recursion that has not been done.
4049 			 * Get bits for the policy zones that do not need
4050 			 * to wait for the results of recursion.
4051 			 */
4052 			allowed = st->have.qname_skip_recurse;
4053 			if (allowed == 0) {
4054 				return (ISC_R_SUCCESS);
4055 			}
4056 		} else {
4057 			allowed = DNS_RPZ_ALL_ZBITS;
4058 		}
4059 
4060 		/*
4061 		 * Check once for triggers for the client IP address.
4062 		 */
4063 		if ((st->state & DNS_RPZ_DONE_CLIENT_IP) == 0) {
4064 			zbits = rpz_get_zbits(client, dns_rdatatype_none,
4065 					      DNS_RPZ_TYPE_CLIENT_IP);
4066 			zbits &= allowed;
4067 			if (zbits != 0) {
4068 				isc_netaddr_fromsockaddr(&netaddr,
4069 							 &client->peeraddr);
4070 				result = rpz_rewrite_ip(client, &netaddr, qtype,
4071 							DNS_RPZ_TYPE_CLIENT_IP,
4072 							zbits, &rdataset);
4073 				if (result != ISC_R_SUCCESS) {
4074 					goto cleanup;
4075 				}
4076 			}
4077 		}
4078 
4079 		/*
4080 		 * Check triggers for the query name if this is the first time
4081 		 * for the current qname.
4082 		 * There is a first time for each name in a CNAME chain
4083 		 */
4084 		if ((st->state & DNS_RPZ_DONE_QNAME) == 0) {
4085 			bool norec = (qresult_type != qresult_type_recurse);
4086 			result = rpz_rewrite_name(client, client->query.qname,
4087 						  qtype, DNS_RPZ_TYPE_QNAME,
4088 						  allowed, norec, &rdataset);
4089 			if (result != ISC_R_SUCCESS) {
4090 				goto cleanup;
4091 			}
4092 
4093 			/*
4094 			 * Check IPv4 addresses in A RRs next.
4095 			 * Reset to the start of the NS names.
4096 			 */
4097 			st->r.label = dns_name_countlabels(client->query.qname);
4098 			st->state &= ~(DNS_RPZ_DONE_QNAME_IP |
4099 				       DNS_RPZ_DONE_IPv4);
4100 		}
4101 
4102 		/*
4103 		 * Quit if this was an attempt to find a qname or
4104 		 * client-IP trigger before recursion.
4105 		 * We will be back if no pre-recursion triggers hit.
4106 		 * For example, consider 2 policy zones, both with qname and
4107 		 * IP address triggers.  If the qname misses the 1st zone,
4108 		 * then we cannot know whether a hit for the qname in the
4109 		 * 2nd zone matters until after recursing to get the A RRs and
4110 		 * testing them in the first zone.
4111 		 * Do not bother saving the work from this attempt,
4112 		 * because recursion is so slow.
4113 		 */
4114 		if (qresult_type == qresult_type_recurse) {
4115 			goto cleanup;
4116 		}
4117 
4118 		/*
4119 		 * DNS_RPZ_DONE_QNAME but not DNS_RPZ_DONE_CLIENT_IP
4120 		 * is reset at the end of dealing with each CNAME.
4121 		 */
4122 		st->state |= (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME);
4123 	}
4124 
4125 	/*
4126 	 * Check known IP addresses for the query name if the database lookup
4127 	 * resulted in some addresses (qresult_type == qresult_type_done)
4128 	 * and if we have not already checked them.
4129 	 * Any recursion required for the query has already happened.
4130 	 * Do not check addresses that will not be in the ANSWER section.
4131 	 */
4132 	if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 &&
4133 	    qresult_type == qresult_type_done &&
4134 	    rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0)
4135 	{
4136 		result = rpz_rewrite_ip_rrsets(client, client->query.qname,
4137 					       qtype, DNS_RPZ_TYPE_IP,
4138 					       &rdataset, resuming);
4139 		if (result != ISC_R_SUCCESS) {
4140 			goto cleanup;
4141 		}
4142 		/*
4143 		 * We are finished checking the IP addresses for the qname.
4144 		 * Start with IPv4 if we will check NS IP addresses.
4145 		 */
4146 		st->state |= DNS_RPZ_DONE_QNAME_IP;
4147 		st->state &= ~DNS_RPZ_DONE_IPv4;
4148 	}
4149 
4150 	/*
4151 	 * Stop looking for rules if there are none of the other kinds
4152 	 * that could override what we already have.
4153 	 */
4154 	if (rpz_get_zbits(client, dns_rdatatype_any, DNS_RPZ_TYPE_NSDNAME) ==
4155 		    0 &&
4156 	    rpz_get_zbits(client, dns_rdatatype_any, DNS_RPZ_TYPE_NSIP) == 0)
4157 	{
4158 		result = ISC_R_SUCCESS;
4159 		goto cleanup;
4160 	}
4161 
4162 	dns_fixedname_init(&nsnamef);
4163 	dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef));
4164 	while (st->r.label > st->popt.min_ns_labels) {
4165 		/*
4166 		 * Get NS rrset for each domain in the current qname.
4167 		 */
4168 		if (st->r.label == dns_name_countlabels(client->query.qname)) {
4169 			nsname = client->query.qname;
4170 		} else {
4171 			nsname = dns_fixedname_name(&nsnamef);
4172 			dns_name_split(client->query.qname, st->r.label, NULL,
4173 				       nsname);
4174 		}
4175 		if (st->r.ns_rdataset == NULL ||
4176 		    !dns_rdataset_isassociated(st->r.ns_rdataset)) {
4177 			dns_db_t *db = NULL;
4178 			result = rpz_rrset_find(client, nsname,
4179 						dns_rdatatype_ns,
4180 						DNS_RPZ_TYPE_NSDNAME, &db, NULL,
4181 						&st->r.ns_rdataset, resuming);
4182 			if (db != NULL) {
4183 				dns_db_detach(&db);
4184 			}
4185 			if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
4186 				goto cleanup;
4187 			}
4188 			switch (result) {
4189 			case ISC_R_SUCCESS:
4190 				result = dns_rdataset_first(st->r.ns_rdataset);
4191 				if (result != ISC_R_SUCCESS) {
4192 					goto cleanup;
4193 				}
4194 				st->state &= ~(DNS_RPZ_DONE_NSDNAME |
4195 					       DNS_RPZ_DONE_IPv4);
4196 				break;
4197 			case DNS_R_DELEGATION:
4198 			case DNS_R_DUPLICATE:
4199 			case DNS_R_DROP:
4200 				goto cleanup;
4201 			case DNS_R_EMPTYNAME:
4202 			case DNS_R_NXRRSET:
4203 			case DNS_R_EMPTYWILD:
4204 			case DNS_R_NXDOMAIN:
4205 			case DNS_R_NCACHENXDOMAIN:
4206 			case DNS_R_NCACHENXRRSET:
4207 			case ISC_R_NOTFOUND:
4208 			case DNS_R_CNAME:
4209 			case DNS_R_DNAME:
4210 				rpz_rewrite_ns_skip(client, nsname, result, 0,
4211 						    NULL);
4212 				continue;
4213 			case ISC_R_TIMEDOUT:
4214 			case DNS_R_BROKENCHAIN:
4215 			case ISC_R_FAILURE:
4216 				rpz_rewrite_ns_skip(client, nsname, result,
4217 						    DNS_RPZ_DEBUG_LEVEL3,
4218 						    " NS rpz_rrset_find()");
4219 				continue;
4220 			default:
4221 				rpz_rewrite_ns_skip(client, nsname, result,
4222 						    DNS_RPZ_INFO_LEVEL,
4223 						    " unrecognized NS"
4224 						    " rpz_rrset_find()");
4225 				continue;
4226 			}
4227 		}
4228 		/*
4229 		 * Check all NS names.
4230 		 */
4231 		do {
4232 			dns_rdata_ns_t ns;
4233 			dns_rdata_t nsrdata = DNS_RDATA_INIT;
4234 
4235 			dns_rdataset_current(st->r.ns_rdataset, &nsrdata);
4236 			result = dns_rdata_tostruct(&nsrdata, &ns, NULL);
4237 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
4238 			dns_rdata_reset(&nsrdata);
4239 
4240 			/*
4241 			 * Do nothing about "NS ."
4242 			 */
4243 			if (dns_name_equal(&ns.name, dns_rootname)) {
4244 				dns_rdata_freestruct(&ns);
4245 				result = dns_rdataset_next(st->r.ns_rdataset);
4246 				continue;
4247 			}
4248 			/*
4249 			 * Check this NS name if we did not handle it
4250 			 * during a previous recursion.
4251 			 */
4252 			if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0) {
4253 				result = rpz_rewrite_name(
4254 					client, &ns.name, qtype,
4255 					DNS_RPZ_TYPE_NSDNAME, DNS_RPZ_ALL_ZBITS,
4256 					true, &rdataset);
4257 				if (result != ISC_R_SUCCESS) {
4258 					dns_rdata_freestruct(&ns);
4259 					goto cleanup;
4260 				}
4261 				st->state |= DNS_RPZ_DONE_NSDNAME;
4262 			}
4263 			/*
4264 			 * Check all IP addresses for this NS name.
4265 			 */
4266 			result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype,
4267 						       DNS_RPZ_TYPE_NSIP,
4268 						       &rdataset, resuming);
4269 			dns_rdata_freestruct(&ns);
4270 			if (result != ISC_R_SUCCESS) {
4271 				goto cleanup;
4272 			}
4273 			st->state &= ~(DNS_RPZ_DONE_NSDNAME |
4274 				       DNS_RPZ_DONE_IPv4);
4275 			result = dns_rdataset_next(st->r.ns_rdataset);
4276 		} while (result == ISC_R_SUCCESS);
4277 		dns_rdataset_disassociate(st->r.ns_rdataset);
4278 		st->r.label--;
4279 
4280 		if (rpz_get_zbits(client, dns_rdatatype_any,
4281 				  DNS_RPZ_TYPE_NSDNAME) == 0 &&
4282 		    rpz_get_zbits(client, dns_rdatatype_any,
4283 				  DNS_RPZ_TYPE_NSIP) == 0)
4284 		{
4285 			break;
4286 		}
4287 	}
4288 
4289 	/*
4290 	 * Use the best hit, if any.
4291 	 */
4292 	result = ISC_R_SUCCESS;
4293 
4294 cleanup:
4295 #ifdef USE_DNSRPS
4296 	if (st->popt.dnsrps_enabled && st->m.policy != DNS_RPZ_POLICY_ERROR &&
4297 	    !dnsrps_set_p(&emsg, client, st, qtype, &rdataset,
4298 			  (qresult_type != qresult_type_recurse)))
4299 	{
4300 		rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
4301 			     DNS_RPZ_TYPE_BAD, emsg.c, DNS_R_SERVFAIL);
4302 		st->m.policy = DNS_RPZ_POLICY_ERROR;
4303 	}
4304 #endif /* ifdef USE_DNSRPS */
4305 	if (st->m.policy != DNS_RPZ_POLICY_MISS &&
4306 	    st->m.policy != DNS_RPZ_POLICY_ERROR &&
4307 	    st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN)
4308 	{
4309 		st->m.policy = st->m.rpz->policy;
4310 	}
4311 	if (st->m.policy == DNS_RPZ_POLICY_MISS ||
4312 	    st->m.policy == DNS_RPZ_POLICY_PASSTHRU ||
4313 	    st->m.policy == DNS_RPZ_POLICY_ERROR)
4314 	{
4315 		if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU &&
4316 		    result != DNS_R_DELEGATION) {
4317 			rpz_log_rewrite(client, false, st->m.policy, st->m.type,
4318 					st->m.zone, st->p_name, NULL,
4319 					st->m.rpz->num);
4320 		}
4321 		rpz_match_clear(st);
4322 	}
4323 	if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
4324 		CTRACE(ISC_LOG_ERROR, "SERVFAIL due to RPZ policy");
4325 		st->m.type = DNS_RPZ_TYPE_BAD;
4326 		result = DNS_R_SERVFAIL;
4327 	}
4328 	ns_client_putrdataset(client, &rdataset);
4329 	if ((st->state & DNS_RPZ_RECURSING) == 0) {
4330 		rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset);
4331 	}
4332 
4333 	return (result);
4334 }
4335 
4336 /*
4337  * See if response policy zone rewriting is allowed by a lack of interest
4338  * by the client in DNSSEC or a lack of signatures.
4339  */
4340 static bool
4341 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
4342 	      dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
4343 	dns_fixedname_t fixed;
4344 	dns_name_t *found;
4345 	dns_rdataset_t trdataset;
4346 	dns_rdatatype_t type;
4347 	isc_result_t result;
4348 
4349 	CTRACE(ISC_LOG_DEBUG(3), "rpz_ck_dnssec");
4350 
4351 	if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client)) {
4352 		return (true);
4353 	}
4354 
4355 	/*
4356 	 * We do not know if there are signatures if we have not recursed
4357 	 * for them.
4358 	 */
4359 	if (qresult == DNS_R_DELEGATION || qresult == ISC_R_NOTFOUND) {
4360 		return (false);
4361 	}
4362 
4363 	if (sigrdataset == NULL) {
4364 		return (true);
4365 	}
4366 	if (dns_rdataset_isassociated(sigrdataset)) {
4367 		return (false);
4368 	}
4369 
4370 	/*
4371 	 * We are happy to rewrite nothing.
4372 	 */
4373 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
4374 		return (true);
4375 	}
4376 	/*
4377 	 * Do not rewrite if there is any sign of signatures.
4378 	 */
4379 	if (rdataset->type == dns_rdatatype_nsec ||
4380 	    rdataset->type == dns_rdatatype_nsec3 ||
4381 	    rdataset->type == dns_rdatatype_rrsig)
4382 	{
4383 		return (false);
4384 	}
4385 
4386 	/*
4387 	 * Look for a signature in a negative cache rdataset.
4388 	 */
4389 	if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0) {
4390 		return (true);
4391 	}
4392 	found = dns_fixedname_initname(&fixed);
4393 	dns_rdataset_init(&trdataset);
4394 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
4395 	     result = dns_rdataset_next(rdataset))
4396 	{
4397 		dns_ncache_current(rdataset, found, &trdataset);
4398 		type = trdataset.type;
4399 		dns_rdataset_disassociate(&trdataset);
4400 		if (type == dns_rdatatype_nsec || type == dns_rdatatype_nsec3 ||
4401 		    type == dns_rdatatype_rrsig)
4402 		{
4403 			return (false);
4404 		}
4405 	}
4406 	return (true);
4407 }
4408 
4409 /*
4410  * Extract a network address from the RDATA of an A or AAAA
4411  * record.
4412  *
4413  * Returns:
4414  *	ISC_R_SUCCESS
4415  *	ISC_R_NOTIMPLEMENTED	The rdata is not a known address type.
4416  */
4417 static isc_result_t
4418 rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) {
4419 	struct in_addr ina;
4420 	struct in6_addr in6a;
4421 
4422 	switch (rdata->type) {
4423 	case dns_rdatatype_a:
4424 		INSIST(rdata->length == 4);
4425 		memmove(&ina.s_addr, rdata->data, 4);
4426 		isc_netaddr_fromin(netaddr, &ina);
4427 		return (ISC_R_SUCCESS);
4428 	case dns_rdatatype_aaaa:
4429 		INSIST(rdata->length == 16);
4430 		memmove(in6a.s6_addr, rdata->data, 16);
4431 		isc_netaddr_fromin6(netaddr, &in6a);
4432 		return (ISC_R_SUCCESS);
4433 	default:
4434 		return (ISC_R_NOTIMPLEMENTED);
4435 	}
4436 }
4437 
4438 static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 };
4439 static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 };
4440 static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 };
4441 
4442 static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA";
4443 
4444 static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA";
4445 static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA";
4446 static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA";
4447 static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA";
4448 static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA";
4449 static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA";
4450 static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA";
4451 static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA";
4452 static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA";
4453 static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA";
4454 static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA";
4455 static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA";
4456 static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA";
4457 static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA";
4458 static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA";
4459 static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA";
4460 
4461 static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA";
4462 
4463 static dns_name_t rfc1918names[] = {
4464 	DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets),
4465 	DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets),
4466 	DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets),
4467 	DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets),
4468 	DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets),
4469 	DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets),
4470 	DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets),
4471 	DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets),
4472 	DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets),
4473 	DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets),
4474 	DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets),
4475 	DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets),
4476 	DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets),
4477 	DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets),
4478 	DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets),
4479 	DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets),
4480 	DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets),
4481 	DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets)
4482 };
4483 
4484 static unsigned char prisoner_data[] = "\010prisoner\004iana\003org";
4485 static unsigned char hostmaster_data[] = "\012hostmaster\014root-"
4486 					 "servers\003org";
4487 
4488 static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 };
4489 static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 };
4490 
4491 static dns_name_t const prisoner = DNS_NAME_INITABSOLUTE(prisoner_data,
4492 							 prisoner_offsets);
4493 static dns_name_t const hostmaster = DNS_NAME_INITABSOLUTE(hostmaster_data,
4494 							   hostmaster_offsets);
4495 
4496 static void
4497 warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) {
4498 	unsigned int i;
4499 	dns_rdata_t rdata = DNS_RDATA_INIT;
4500 	dns_rdata_soa_t soa;
4501 	dns_rdataset_t found;
4502 	isc_result_t result;
4503 
4504 	for (i = 0; i < (sizeof(rfc1918names) / sizeof(*rfc1918names)); i++) {
4505 		if (dns_name_issubdomain(fname, &rfc1918names[i])) {
4506 			dns_rdataset_init(&found);
4507 			result = dns_ncache_getrdataset(
4508 				rdataset, &rfc1918names[i], dns_rdatatype_soa,
4509 				&found);
4510 			if (result != ISC_R_SUCCESS) {
4511 				return;
4512 			}
4513 
4514 			result = dns_rdataset_first(&found);
4515 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
4516 			dns_rdataset_current(&found, &rdata);
4517 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
4518 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
4519 			if (dns_name_equal(&soa.origin, &prisoner) &&
4520 			    dns_name_equal(&soa.contact, &hostmaster))
4521 			{
4522 				char buf[DNS_NAME_FORMATSIZE];
4523 				dns_name_format(fname, buf, sizeof(buf));
4524 				ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
4525 					      NS_LOGMODULE_QUERY,
4526 					      ISC_LOG_WARNING,
4527 					      "RFC 1918 response from "
4528 					      "Internet for %s",
4529 					      buf);
4530 			}
4531 			dns_rdataset_disassociate(&found);
4532 			return;
4533 		}
4534 	}
4535 }
4536 
4537 static void
4538 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
4539 		       dns_dbversion_t *version, ns_client_t *client,
4540 		       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
4541 		       dns_name_t *fname, bool exact, dns_name_t *found) {
4542 	unsigned char salt[256];
4543 	size_t salt_length;
4544 	uint16_t iterations;
4545 	isc_result_t result;
4546 	unsigned int dboptions;
4547 	dns_fixedname_t fixed;
4548 	dns_hash_t hash;
4549 	dns_name_t name;
4550 	unsigned int skip = 0, labels;
4551 	dns_rdata_nsec3_t nsec3;
4552 	dns_rdata_t rdata = DNS_RDATA_INIT;
4553 	bool optout;
4554 	dns_clientinfomethods_t cm;
4555 	dns_clientinfo_t ci;
4556 
4557 	salt_length = sizeof(salt);
4558 	result = dns_db_getnsec3parameters(db, version, &hash, NULL,
4559 					   &iterations, salt, &salt_length);
4560 	if (result != ISC_R_SUCCESS) {
4561 		return;
4562 	}
4563 
4564 	dns_name_init(&name, NULL);
4565 	dns_name_clone(qname, &name);
4566 	labels = dns_name_countlabels(&name);
4567 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
4568 	dns_clientinfo_init(&ci, client, NULL);
4569 
4570 	/*
4571 	 * Map unknown algorithm to known value.
4572 	 */
4573 	if (hash == DNS_NSEC3_UNKNOWNALG) {
4574 		hash = 1;
4575 	}
4576 
4577 again:
4578 	dns_fixedname_init(&fixed);
4579 	result = dns_nsec3_hashname(&fixed, NULL, NULL, &name,
4580 				    dns_db_origin(db), hash, iterations, salt,
4581 				    salt_length);
4582 	if (result != ISC_R_SUCCESS) {
4583 		return;
4584 	}
4585 
4586 	dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3;
4587 	result = dns_db_findext(db, dns_fixedname_name(&fixed), version,
4588 				dns_rdatatype_nsec3, dboptions, client->now,
4589 				NULL, fname, &cm, &ci, rdataset, sigrdataset);
4590 
4591 	if (result == DNS_R_NXDOMAIN) {
4592 		if (!dns_rdataset_isassociated(rdataset)) {
4593 			return;
4594 		}
4595 		result = dns_rdataset_first(rdataset);
4596 		INSIST(result == ISC_R_SUCCESS);
4597 		dns_rdataset_current(rdataset, &rdata);
4598 		result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
4599 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
4600 		dns_rdata_reset(&rdata);
4601 		optout = ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0);
4602 		if (found != NULL && optout &&
4603 		    dns_name_issubdomain(&name, dns_db_origin(db))) {
4604 			dns_rdataset_disassociate(rdataset);
4605 			if (dns_rdataset_isassociated(sigrdataset)) {
4606 				dns_rdataset_disassociate(sigrdataset);
4607 			}
4608 			skip++;
4609 			dns_name_getlabelsequence(qname, skip, labels - skip,
4610 						  &name);
4611 			ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
4612 				      NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3),
4613 				      "looking for closest provable encloser");
4614 			goto again;
4615 		}
4616 		if (exact) {
4617 			ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
4618 				      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
4619 				      "expected a exact match NSEC3, got "
4620 				      "a covering record");
4621 		}
4622 	} else if (result != ISC_R_SUCCESS) {
4623 		return;
4624 	} else if (!exact) {
4625 		ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
4626 			      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
4627 			      "expected covering NSEC3, got an exact match");
4628 	}
4629 	if (found == qname) {
4630 		if (skip != 0U) {
4631 			dns_name_getlabelsequence(qname, skip, labels - skip,
4632 						  found);
4633 		}
4634 	} else if (found != NULL) {
4635 		dns_name_copynf(&name, found);
4636 	}
4637 	return;
4638 }
4639 
4640 static uint32_t
4641 dns64_ttl(dns_db_t *db, dns_dbversion_t *version) {
4642 	dns_dbnode_t *node = NULL;
4643 	dns_rdata_soa_t soa;
4644 	dns_rdata_t rdata = DNS_RDATA_INIT;
4645 	dns_rdataset_t rdataset;
4646 	isc_result_t result;
4647 	uint32_t ttl = UINT32_MAX;
4648 
4649 	dns_rdataset_init(&rdataset);
4650 
4651 	result = dns_db_getoriginnode(db, &node);
4652 	if (result != ISC_R_SUCCESS) {
4653 		goto cleanup;
4654 	}
4655 
4656 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 0, 0,
4657 				     &rdataset, NULL);
4658 	if (result != ISC_R_SUCCESS) {
4659 		goto cleanup;
4660 	}
4661 	result = dns_rdataset_first(&rdataset);
4662 	if (result != ISC_R_SUCCESS) {
4663 		goto cleanup;
4664 	}
4665 
4666 	dns_rdataset_current(&rdataset, &rdata);
4667 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
4668 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
4669 	ttl = ISC_MIN(rdataset.ttl, soa.minimum);
4670 
4671 cleanup:
4672 	if (dns_rdataset_isassociated(&rdataset)) {
4673 		dns_rdataset_disassociate(&rdataset);
4674 	}
4675 	if (node != NULL) {
4676 		dns_db_detachnode(db, &node);
4677 	}
4678 	return (ttl);
4679 }
4680 
4681 static bool
4682 dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
4683 	     dns_rdataset_t *sigrdataset) {
4684 	isc_netaddr_t netaddr;
4685 	dns_aclenv_t *env =
4686 		ns_interfacemgr_getaclenv(client->manager->interface->mgr);
4687 	dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64);
4688 	unsigned int flags = 0;
4689 	unsigned int i, count;
4690 	bool *aaaaok;
4691 
4692 	INSIST(client->query.dns64_aaaaok == NULL);
4693 	INSIST(client->query.dns64_aaaaoklen == 0);
4694 	INSIST(client->query.dns64_aaaa == NULL);
4695 	INSIST(client->query.dns64_sigaaaa == NULL);
4696 
4697 	if (dns64 == NULL) {
4698 		return (true);
4699 	}
4700 
4701 	if (RECURSIONOK(client)) {
4702 		flags |= DNS_DNS64_RECURSIVE;
4703 	}
4704 
4705 	if (WANTDNSSEC(client) && sigrdataset != NULL &&
4706 	    dns_rdataset_isassociated(sigrdataset))
4707 	{
4708 		flags |= DNS_DNS64_DNSSEC;
4709 	}
4710 
4711 	count = dns_rdataset_count(rdataset);
4712 	aaaaok = isc_mem_get(client->mctx, sizeof(bool) * count);
4713 
4714 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
4715 	if (dns_dns64_aaaaok(dns64, &netaddr, client->signer, env, flags,
4716 			     rdataset, aaaaok, count))
4717 	{
4718 		for (i = 0; i < count; i++) {
4719 			if (aaaaok != NULL && !aaaaok[i]) {
4720 				SAVE(client->query.dns64_aaaaok, aaaaok);
4721 				client->query.dns64_aaaaoklen = count;
4722 				break;
4723 			}
4724 		}
4725 		if (aaaaok != NULL) {
4726 			isc_mem_put(client->mctx, aaaaok, sizeof(bool) * count);
4727 		}
4728 		return (true);
4729 	}
4730 	if (aaaaok != NULL) {
4731 		isc_mem_put(client->mctx, aaaaok, sizeof(bool) * count);
4732 	}
4733 	return (false);
4734 }
4735 
4736 /*
4737  * Look for the name and type in the redirection zone.  If found update
4738  * the arguments as appropriate.  Return true if a update was
4739  * performed.
4740  *
4741  * Only perform the update if the client is in the allow query acl and
4742  * returning the update would not cause a DNSSEC validation failure.
4743  */
4744 static isc_result_t
4745 redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
4746 	 dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
4747 	 dns_rdatatype_t qtype) {
4748 	dns_db_t *db = NULL;
4749 	dns_dbnode_t *node = NULL;
4750 	dns_fixedname_t fixed;
4751 	dns_name_t *found;
4752 	dns_rdataset_t trdataset;
4753 	isc_result_t result;
4754 	dns_rdatatype_t type;
4755 	dns_clientinfomethods_t cm;
4756 	dns_clientinfo_t ci;
4757 	ns_dbversion_t *dbversion;
4758 
4759 	CTRACE(ISC_LOG_DEBUG(3), "redirect");
4760 
4761 	if (client->view->redirect == NULL) {
4762 		return (ISC_R_NOTFOUND);
4763 	}
4764 
4765 	found = dns_fixedname_initname(&fixed);
4766 	dns_rdataset_init(&trdataset);
4767 
4768 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
4769 	dns_clientinfo_init(&ci, client, NULL);
4770 
4771 	if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
4772 	{
4773 		return (ISC_R_NOTFOUND);
4774 	}
4775 
4776 	if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
4777 		if (rdataset->trust == dns_trust_secure) {
4778 			return (ISC_R_NOTFOUND);
4779 		}
4780 		if (rdataset->trust == dns_trust_ultimate &&
4781 		    (rdataset->type == dns_rdatatype_nsec ||
4782 		     rdataset->type == dns_rdatatype_nsec3))
4783 		{
4784 			return (ISC_R_NOTFOUND);
4785 		}
4786 		if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
4787 			for (result = dns_rdataset_first(rdataset);
4788 			     result == ISC_R_SUCCESS;
4789 			     result = dns_rdataset_next(rdataset))
4790 			{
4791 				dns_ncache_current(rdataset, found, &trdataset);
4792 				type = trdataset.type;
4793 				dns_rdataset_disassociate(&trdataset);
4794 				if (type == dns_rdatatype_nsec ||
4795 				    type == dns_rdatatype_nsec3 ||
4796 				    type == dns_rdatatype_rrsig)
4797 				{
4798 					return (ISC_R_NOTFOUND);
4799 				}
4800 			}
4801 		}
4802 	}
4803 
4804 	result = ns_client_checkaclsilent(
4805 		client, NULL, dns_zone_getqueryacl(client->view->redirect),
4806 		true);
4807 	if (result != ISC_R_SUCCESS) {
4808 		return (ISC_R_NOTFOUND);
4809 	}
4810 
4811 	result = dns_zone_getdb(client->view->redirect, &db);
4812 	if (result != ISC_R_SUCCESS) {
4813 		return (ISC_R_NOTFOUND);
4814 	}
4815 
4816 	dbversion = ns_client_findversion(client, db);
4817 	if (dbversion == NULL) {
4818 		dns_db_detach(&db);
4819 		return (ISC_R_NOTFOUND);
4820 	}
4821 
4822 	/*
4823 	 * Lookup the requested data in the redirect zone.
4824 	 */
4825 	result = dns_db_findext(db, client->query.qname, dbversion->version,
4826 				qtype, DNS_DBFIND_NOZONECUT, client->now, &node,
4827 				found, &cm, &ci, &trdataset, NULL);
4828 	if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
4829 		if (dns_rdataset_isassociated(rdataset)) {
4830 			dns_rdataset_disassociate(rdataset);
4831 		}
4832 		if (dns_rdataset_isassociated(&trdataset)) {
4833 			dns_rdataset_disassociate(&trdataset);
4834 		}
4835 		goto nxrrset;
4836 	} else if (result != ISC_R_SUCCESS) {
4837 		if (dns_rdataset_isassociated(&trdataset)) {
4838 			dns_rdataset_disassociate(&trdataset);
4839 		}
4840 		if (node != NULL) {
4841 			dns_db_detachnode(db, &node);
4842 		}
4843 		dns_db_detach(&db);
4844 		return (ISC_R_NOTFOUND);
4845 	}
4846 
4847 	CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done");
4848 	dns_name_copynf(found, name);
4849 	if (dns_rdataset_isassociated(rdataset)) {
4850 		dns_rdataset_disassociate(rdataset);
4851 	}
4852 	if (dns_rdataset_isassociated(&trdataset)) {
4853 		dns_rdataset_clone(&trdataset, rdataset);
4854 		dns_rdataset_disassociate(&trdataset);
4855 	}
4856 nxrrset:
4857 	if (*nodep != NULL) {
4858 		dns_db_detachnode(*dbp, nodep);
4859 	}
4860 	dns_db_detach(dbp);
4861 	dns_db_attachnode(db, node, nodep);
4862 	dns_db_attach(db, dbp);
4863 	dns_db_detachnode(db, &node);
4864 	dns_db_detach(&db);
4865 	*versionp = dbversion->version;
4866 
4867 	client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
4868 				     NS_QUERYATTR_NOADDITIONAL);
4869 
4870 	return (result);
4871 }
4872 
4873 static isc_result_t
4874 redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
4875 	  dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
4876 	  dns_rdatatype_t qtype, bool *is_zonep) {
4877 	dns_db_t *db = NULL;
4878 	dns_dbnode_t *node = NULL;
4879 	dns_fixedname_t fixed;
4880 	dns_fixedname_t fixedredirect;
4881 	dns_name_t *found, *redirectname;
4882 	dns_rdataset_t trdataset;
4883 	isc_result_t result;
4884 	dns_rdatatype_t type;
4885 	dns_clientinfomethods_t cm;
4886 	dns_clientinfo_t ci;
4887 	dns_dbversion_t *version = NULL;
4888 	dns_zone_t *zone = NULL;
4889 	bool is_zone;
4890 	unsigned int labels;
4891 	unsigned int options;
4892 
4893 	CTRACE(ISC_LOG_DEBUG(3), "redirect2");
4894 
4895 	if (client->view->redirectzone == NULL) {
4896 		return (ISC_R_NOTFOUND);
4897 	}
4898 
4899 	if (dns_name_issubdomain(name, client->view->redirectzone)) {
4900 		return (ISC_R_NOTFOUND);
4901 	}
4902 
4903 	found = dns_fixedname_initname(&fixed);
4904 	dns_rdataset_init(&trdataset);
4905 
4906 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
4907 	dns_clientinfo_init(&ci, client, NULL);
4908 
4909 	if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
4910 	{
4911 		return (ISC_R_NOTFOUND);
4912 	}
4913 
4914 	if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
4915 		if (rdataset->trust == dns_trust_secure) {
4916 			return (ISC_R_NOTFOUND);
4917 		}
4918 		if (rdataset->trust == dns_trust_ultimate &&
4919 		    (rdataset->type == dns_rdatatype_nsec ||
4920 		     rdataset->type == dns_rdatatype_nsec3))
4921 		{
4922 			return (ISC_R_NOTFOUND);
4923 		}
4924 		if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
4925 			for (result = dns_rdataset_first(rdataset);
4926 			     result == ISC_R_SUCCESS;
4927 			     result = dns_rdataset_next(rdataset))
4928 			{
4929 				dns_ncache_current(rdataset, found, &trdataset);
4930 				type = trdataset.type;
4931 				dns_rdataset_disassociate(&trdataset);
4932 				if (type == dns_rdatatype_nsec ||
4933 				    type == dns_rdatatype_nsec3 ||
4934 				    type == dns_rdatatype_rrsig)
4935 				{
4936 					return (ISC_R_NOTFOUND);
4937 				}
4938 			}
4939 		}
4940 	}
4941 
4942 	redirectname = dns_fixedname_initname(&fixedredirect);
4943 	labels = dns_name_countlabels(client->query.qname);
4944 	if (labels > 1U) {
4945 		dns_name_t prefix;
4946 
4947 		dns_name_init(&prefix, NULL);
4948 		dns_name_getlabelsequence(client->query.qname, 0, labels - 1,
4949 					  &prefix);
4950 		result = dns_name_concatenate(&prefix,
4951 					      client->view->redirectzone,
4952 					      redirectname, NULL);
4953 		if (result != ISC_R_SUCCESS) {
4954 			return (ISC_R_NOTFOUND);
4955 		}
4956 	} else {
4957 		dns_name_copynf(redirectname, client->view->redirectzone);
4958 	}
4959 
4960 	options = 0;
4961 	result = query_getdb(client, redirectname, qtype, options, &zone, &db,
4962 			     &version, &is_zone);
4963 	if (result != ISC_R_SUCCESS) {
4964 		return (ISC_R_NOTFOUND);
4965 	}
4966 	if (zone != NULL) {
4967 		dns_zone_detach(&zone);
4968 	}
4969 
4970 	/*
4971 	 * Lookup the requested data in the redirect zone.
4972 	 */
4973 	result = dns_db_findext(db, redirectname, version, qtype, 0,
4974 				client->now, &node, found, &cm, &ci, &trdataset,
4975 				NULL);
4976 	if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
4977 		if (dns_rdataset_isassociated(rdataset)) {
4978 			dns_rdataset_disassociate(rdataset);
4979 		}
4980 		if (dns_rdataset_isassociated(&trdataset)) {
4981 			dns_rdataset_disassociate(&trdataset);
4982 		}
4983 		goto nxrrset;
4984 	} else if (result == ISC_R_NOTFOUND || result == DNS_R_DELEGATION) {
4985 		/*
4986 		 * Cleanup.
4987 		 */
4988 		if (dns_rdataset_isassociated(&trdataset)) {
4989 			dns_rdataset_disassociate(&trdataset);
4990 		}
4991 		if (node != NULL) {
4992 			dns_db_detachnode(db, &node);
4993 		}
4994 		dns_db_detach(&db);
4995 		/*
4996 		 * Don't loop forever if the lookup failed last time.
4997 		 */
4998 		if (!REDIRECT(client)) {
4999 			result = ns_query_recurse(client, qtype, redirectname,
5000 						  NULL, NULL, true);
5001 			if (result == ISC_R_SUCCESS) {
5002 				client->query.attributes |=
5003 					NS_QUERYATTR_RECURSING;
5004 				client->query.attributes |=
5005 					NS_QUERYATTR_REDIRECT;
5006 				return (DNS_R_CONTINUE);
5007 			}
5008 		}
5009 		return (ISC_R_NOTFOUND);
5010 	} else if (result != ISC_R_SUCCESS) {
5011 		if (dns_rdataset_isassociated(&trdataset)) {
5012 			dns_rdataset_disassociate(&trdataset);
5013 		}
5014 		if (node != NULL) {
5015 			dns_db_detachnode(db, &node);
5016 		}
5017 		dns_db_detach(&db);
5018 		return (ISC_R_NOTFOUND);
5019 	}
5020 
5021 	CTRACE(ISC_LOG_DEBUG(3), "redirect2: found data: done");
5022 	/*
5023 	 * Adjust the found name to not include the redirectzone suffix.
5024 	 */
5025 	dns_name_split(found, dns_name_countlabels(client->view->redirectzone),
5026 		       found, NULL);
5027 	/*
5028 	 * Make the name absolute.
5029 	 */
5030 	result = dns_name_concatenate(found, dns_rootname, found, NULL);
5031 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
5032 
5033 	dns_name_copynf(found, name);
5034 	if (dns_rdataset_isassociated(rdataset)) {
5035 		dns_rdataset_disassociate(rdataset);
5036 	}
5037 	if (dns_rdataset_isassociated(&trdataset)) {
5038 		dns_rdataset_clone(&trdataset, rdataset);
5039 		dns_rdataset_disassociate(&trdataset);
5040 	}
5041 nxrrset:
5042 	if (*nodep != NULL) {
5043 		dns_db_detachnode(*dbp, nodep);
5044 	}
5045 	dns_db_detach(dbp);
5046 	dns_db_attachnode(db, node, nodep);
5047 	dns_db_attach(db, dbp);
5048 	dns_db_detachnode(db, &node);
5049 	dns_db_detach(&db);
5050 	*is_zonep = is_zone;
5051 	*versionp = version;
5052 
5053 	client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
5054 				     NS_QUERYATTR_NOADDITIONAL);
5055 
5056 	return (result);
5057 }
5058 
5059 /*%
5060  * Initialize query context 'qctx'. Run by query_setup() when
5061  * first handling a client query, and by query_resume() when
5062  * returning from recursion.
5063  *
5064  * Whenever this function is called, qctx_destroy() must be called
5065  * when leaving the scope or freeing the qctx.
5066  */
5067 static void
5068 qctx_init(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype,
5069 	  query_ctx_t *qctx) {
5070 	REQUIRE(qctx != NULL);
5071 	REQUIRE(client != NULL);
5072 
5073 	memset(qctx, 0, sizeof(*qctx));
5074 
5075 	/* Set this first so CCTRACE will work */
5076 	qctx->client = client;
5077 
5078 	dns_view_attach(client->view, &qctx->view);
5079 
5080 	CCTRACE(ISC_LOG_DEBUG(3), "qctx_init");
5081 
5082 	qctx->event = event;
5083 	qctx->qtype = qctx->type = qtype;
5084 	qctx->result = ISC_R_SUCCESS;
5085 	qctx->findcoveringnsec = qctx->view->synthfromdnssec;
5086 
5087 	CALL_HOOK_NORETURN(NS_QUERY_QCTX_INITIALIZED, qctx);
5088 }
5089 
5090 /*%
5091  * Clean up and disassociate the rdataset and node pointers in qctx.
5092  */
5093 static void
5094 qctx_clean(query_ctx_t *qctx) {
5095 	if (qctx->rdataset != NULL && dns_rdataset_isassociated(qctx->rdataset))
5096 	{
5097 		dns_rdataset_disassociate(qctx->rdataset);
5098 	}
5099 	if (qctx->sigrdataset != NULL &&
5100 	    dns_rdataset_isassociated(qctx->sigrdataset)) {
5101 		dns_rdataset_disassociate(qctx->sigrdataset);
5102 	}
5103 	if (qctx->db != NULL && qctx->node != NULL) {
5104 		dns_db_detachnode(qctx->db, &qctx->node);
5105 	}
5106 }
5107 
5108 /*%
5109  * Free any allocated memory associated with qctx.
5110  */
5111 static void
5112 qctx_freedata(query_ctx_t *qctx) {
5113 	if (qctx->rdataset != NULL) {
5114 		ns_client_putrdataset(qctx->client, &qctx->rdataset);
5115 	}
5116 
5117 	if (qctx->sigrdataset != NULL) {
5118 		ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
5119 	}
5120 
5121 	if (qctx->fname != NULL) {
5122 		ns_client_releasename(qctx->client, &qctx->fname);
5123 	}
5124 
5125 	if (qctx->db != NULL) {
5126 		INSIST(qctx->node == NULL);
5127 		dns_db_detach(&qctx->db);
5128 	}
5129 
5130 	if (qctx->zone != NULL) {
5131 		dns_zone_detach(&qctx->zone);
5132 	}
5133 
5134 	if (qctx->zdb != NULL) {
5135 		ns_client_putrdataset(qctx->client, &qctx->zsigrdataset);
5136 		ns_client_putrdataset(qctx->client, &qctx->zrdataset);
5137 		ns_client_releasename(qctx->client, &qctx->zfname);
5138 		dns_db_detachnode(qctx->zdb, &qctx->znode);
5139 		dns_db_detach(&qctx->zdb);
5140 	}
5141 
5142 	if (qctx->event != NULL) {
5143 		free_devent(qctx->client, ISC_EVENT_PTR(&qctx->event),
5144 			    &qctx->event);
5145 	}
5146 }
5147 
5148 static void
5149 qctx_destroy(query_ctx_t *qctx) {
5150 	CALL_HOOK_NORETURN(NS_QUERY_QCTX_DESTROYED, qctx);
5151 
5152 	dns_view_detach(&qctx->view);
5153 }
5154 
5155 /*%
5156  * Log detailed information about the query immediately after
5157  * the client request or a return from recursion.
5158  */
5159 static void
5160 query_trace(query_ctx_t *qctx) {
5161 #ifdef WANT_QUERYTRACE
5162 	char mbuf[2 * DNS_NAME_FORMATSIZE];
5163 	char qbuf[DNS_NAME_FORMATSIZE];
5164 
5165 	if (qctx->client->query.origqname != NULL) {
5166 		dns_name_format(qctx->client->query.origqname, qbuf,
5167 				sizeof(qbuf));
5168 	} else {
5169 		snprintf(qbuf, sizeof(qbuf), "<unset>");
5170 	}
5171 
5172 	snprintf(mbuf, sizeof(mbuf) - 1,
5173 		 "client attr:0x%x, query attr:0x%X, restarts:%u, "
5174 		 "origqname:%s, timer:%d, authdb:%d, referral:%d",
5175 		 qctx->client->attributes, qctx->client->query.attributes,
5176 		 qctx->client->query.restarts, qbuf,
5177 		 (int)qctx->client->query.timerset,
5178 		 (int)qctx->client->query.authdbset,
5179 		 (int)qctx->client->query.isreferral);
5180 	CCTRACE(ISC_LOG_DEBUG(3), mbuf);
5181 #else  /* ifdef WANT_QUERYTRACE */
5182 	UNUSED(qctx);
5183 #endif /* ifdef WANT_QUERYTRACE */
5184 }
5185 
5186 /*
5187  * Set up query processing for the current query of 'client'.
5188  * Calls qctx_init() to initialize a query context, checks
5189  * the SERVFAIL cache, then hands off processing to ns__query_start().
5190  *
5191  * This is called only from ns_query_start(), to begin a query
5192  * for the first time.  Restarting an existing query (for
5193  * instance, to handle CNAME lookups), is done by calling
5194  * ns__query_start() again with the same query context. Resuming from
5195  * recursion is handled by query_resume().
5196  */
5197 static isc_result_t
5198 query_setup(ns_client_t *client, dns_rdatatype_t qtype) {
5199 	isc_result_t result;
5200 	query_ctx_t qctx;
5201 
5202 	qctx_init(client, NULL, qtype, &qctx);
5203 	query_trace(&qctx);
5204 
5205 	CALL_HOOK(NS_QUERY_SETUP, &qctx);
5206 
5207 	/*
5208 	 * If it's a SIG query, we'll iterate the node.
5209 	 */
5210 	if (qctx.qtype == dns_rdatatype_rrsig ||
5211 	    qctx.qtype == dns_rdatatype_sig) {
5212 		qctx.type = dns_rdatatype_any;
5213 	}
5214 
5215 	/*
5216 	 * Check SERVFAIL cache
5217 	 */
5218 	result = ns__query_sfcache(&qctx);
5219 	if (result != ISC_R_COMPLETE) {
5220 		qctx_destroy(&qctx);
5221 		return (result);
5222 	}
5223 
5224 	result = ns__query_start(&qctx);
5225 
5226 cleanup:
5227 	qctx_destroy(&qctx);
5228 	return (result);
5229 }
5230 
5231 static bool
5232 get_root_key_sentinel_id(query_ctx_t *qctx, const char *ndata) {
5233 	unsigned int v = 0;
5234 	int i;
5235 
5236 	for (i = 0; i < 5; i++) {
5237 		if (ndata[i] < '0' || ndata[i] > '9') {
5238 			return (false);
5239 		}
5240 		v *= 10;
5241 		v += ndata[i] - '0';
5242 	}
5243 	if (v > 65535U) {
5244 		return (false);
5245 	}
5246 	qctx->client->query.root_key_sentinel_keyid = v;
5247 	return (true);
5248 }
5249 
5250 /*%
5251  * Find out if the query is for a root key sentinel and if so, record the type
5252  * of root key sentinel query and the key id that is being checked for.
5253  *
5254  * The code is assuming a zero padded decimal field of width 5.
5255  */
5256 static void
5257 root_key_sentinel_detect(query_ctx_t *qctx) {
5258 	const char *ndata = (const char *)qctx->client->query.qname->ndata;
5259 
5260 	if (qctx->client->query.qname->length > 30 && ndata[0] == 29 &&
5261 	    strncasecmp(ndata + 1, "root-key-sentinel-is-ta-", 24) == 0)
5262 	{
5263 		if (!get_root_key_sentinel_id(qctx, ndata + 25)) {
5264 			return;
5265 		}
5266 		qctx->client->query.root_key_sentinel_is_ta = true;
5267 		/*
5268 		 * Simplify processing by disabling aggressive
5269 		 * negative caching.
5270 		 */
5271 		qctx->findcoveringnsec = false;
5272 		ns_client_log(qctx->client, NS_LOGCATEGORY_TAT,
5273 			      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
5274 			      "root-key-sentinel-is-ta query label found");
5275 	} else if (qctx->client->query.qname->length > 31 && ndata[0] == 30 &&
5276 		   strncasecmp(ndata + 1, "root-key-sentinel-not-ta-", 25) == 0)
5277 	{
5278 		if (!get_root_key_sentinel_id(qctx, ndata + 26)) {
5279 			return;
5280 		}
5281 		qctx->client->query.root_key_sentinel_not_ta = true;
5282 		/*
5283 		 * Simplify processing by disabling aggressive
5284 		 * negative caching.
5285 		 */
5286 		qctx->findcoveringnsec = false;
5287 		ns_client_log(qctx->client, NS_LOGCATEGORY_TAT,
5288 			      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
5289 			      "root-key-sentinel-not-ta query label found");
5290 	}
5291 }
5292 
5293 /*%
5294  * Starting point for a client query or a chaining query.
5295  *
5296  * Called first by query_setup(), and then again as often as needed to
5297  * follow a CNAME chain.  Determines which authoritative database to
5298  * search, then hands off processing to query_lookup().
5299  */
5300 isc_result_t
5301 ns__query_start(query_ctx_t *qctx) {
5302 	isc_result_t result;
5303 	CCTRACE(ISC_LOG_DEBUG(3), "ns__query_start");
5304 	qctx->want_restart = false;
5305 	qctx->authoritative = false;
5306 	qctx->version = NULL;
5307 	qctx->zversion = NULL;
5308 	qctx->need_wildcardproof = false;
5309 	qctx->rpz = false;
5310 
5311 	CALL_HOOK(NS_QUERY_START_BEGIN, qctx);
5312 
5313 	/*
5314 	 * If we require a server cookie then send back BADCOOKIE
5315 	 * before we have done too much work.
5316 	 */
5317 	if (!TCP(qctx->client) && qctx->view->requireservercookie &&
5318 	    WANTCOOKIE(qctx->client) && !HAVECOOKIE(qctx->client))
5319 	{
5320 		qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
5321 		qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
5322 		qctx->client->message->rcode = dns_rcode_badcookie;
5323 		return (ns_query_done(qctx));
5324 	}
5325 
5326 	if (qctx->view->checknames &&
5327 	    !dns_rdata_checkowner(qctx->client->query.qname,
5328 				  qctx->client->message->rdclass, qctx->qtype,
5329 				  false))
5330 	{
5331 		char namebuf[DNS_NAME_FORMATSIZE];
5332 		char typebuf[DNS_RDATATYPE_FORMATSIZE];
5333 		char classbuf[DNS_RDATACLASS_FORMATSIZE];
5334 
5335 		dns_name_format(qctx->client->query.qname, namebuf,
5336 				sizeof(namebuf));
5337 		dns_rdatatype_format(qctx->qtype, typebuf, sizeof(typebuf));
5338 		dns_rdataclass_format(qctx->client->message->rdclass, classbuf,
5339 				      sizeof(classbuf));
5340 		ns_client_log(qctx->client, DNS_LOGCATEGORY_SECURITY,
5341 			      NS_LOGMODULE_QUERY, ISC_LOG_ERROR,
5342 			      "check-names failure %s/%s/%s", namebuf, typebuf,
5343 			      classbuf);
5344 		QUERY_ERROR(qctx, DNS_R_REFUSED);
5345 		return (ns_query_done(qctx));
5346 	}
5347 
5348 	/*
5349 	 * Setup for root key sentinel processing.
5350 	 */
5351 	if (qctx->view->root_key_sentinel &&
5352 	    qctx->client->query.restarts == 0 &&
5353 	    (qctx->qtype == dns_rdatatype_a ||
5354 	     qctx->qtype == dns_rdatatype_aaaa) &&
5355 	    (qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0)
5356 	{
5357 		root_key_sentinel_detect(qctx);
5358 	}
5359 
5360 	/*
5361 	 * First we must find the right database.
5362 	 */
5363 	qctx->options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */
5364 	if (dns_rdatatype_atparent(qctx->qtype) &&
5365 	    !dns_name_equal(qctx->client->query.qname, dns_rootname))
5366 	{
5367 		/*
5368 		 * If authoritative data for this QTYPE is supposed to live in
5369 		 * the parent zone, do not look for an exact match for QNAME,
5370 		 * but rather for its containing zone (unless the QNAME is
5371 		 * root).
5372 		 */
5373 		qctx->options |= DNS_GETDB_NOEXACT;
5374 	}
5375 
5376 	result = query_getdb(qctx->client, qctx->client->query.qname,
5377 			     qctx->qtype, qctx->options, &qctx->zone, &qctx->db,
5378 			     &qctx->version, &qctx->is_zone);
5379 	if (ISC_UNLIKELY((result != ISC_R_SUCCESS || !qctx->is_zone) &&
5380 			 qctx->qtype == dns_rdatatype_ds &&
5381 			 !RECURSIONOK(qctx->client) &&
5382 			 (qctx->options & DNS_GETDB_NOEXACT) != 0))
5383 	{
5384 		/*
5385 		 * This is a non-recursive QTYPE=DS query with QNAME whose
5386 		 * parent we are not authoritative for.  Check whether we are
5387 		 * authoritative for QNAME, because if so, we need to send a
5388 		 * "no data" response as required by RFC 4035, section 3.1.4.1.
5389 		 */
5390 		dns_db_t *tdb = NULL;
5391 		dns_zone_t *tzone = NULL;
5392 		dns_dbversion_t *tversion = NULL;
5393 		isc_result_t tresult;
5394 
5395 		tresult = query_getzonedb(
5396 			qctx->client, qctx->client->query.qname, qctx->qtype,
5397 			DNS_GETDB_PARTIAL, &tzone, &tdb, &tversion);
5398 		if (tresult == ISC_R_SUCCESS) {
5399 			/*
5400 			 * We are authoritative for QNAME.  Attach the relevant
5401 			 * zone to query context, set result to ISC_R_SUCCESS.
5402 			 */
5403 			qctx->options &= ~DNS_GETDB_NOEXACT;
5404 			ns_client_putrdataset(qctx->client, &qctx->rdataset);
5405 			if (qctx->db != NULL) {
5406 				dns_db_detach(&qctx->db);
5407 			}
5408 			if (qctx->zone != NULL) {
5409 				dns_zone_detach(&qctx->zone);
5410 			}
5411 			qctx->version = NULL;
5412 			RESTORE(qctx->version, tversion);
5413 			RESTORE(qctx->db, tdb);
5414 			RESTORE(qctx->zone, tzone);
5415 			qctx->is_zone = true;
5416 			result = ISC_R_SUCCESS;
5417 		} else {
5418 			/*
5419 			 * We are not authoritative for QNAME.  Clean up and
5420 			 * leave result as it was.
5421 			 */
5422 			if (tdb != NULL) {
5423 				dns_db_detach(&tdb);
5424 			}
5425 			if (tzone != NULL) {
5426 				dns_zone_detach(&tzone);
5427 			}
5428 		}
5429 	}
5430 	/*
5431 	 * If we did not find a database from which we can answer the query,
5432 	 * respond with either REFUSED or SERVFAIL, depending on what the
5433 	 * result of query_getdb() was.
5434 	 */
5435 	if (result != ISC_R_SUCCESS) {
5436 		if (result == DNS_R_REFUSED) {
5437 			if (WANTRECURSION(qctx->client)) {
5438 				inc_stats(qctx->client,
5439 					  ns_statscounter_recurserej);
5440 			} else {
5441 				inc_stats(qctx->client,
5442 					  ns_statscounter_authrej);
5443 			}
5444 			if (!PARTIALANSWER(qctx->client)) {
5445 				QUERY_ERROR(qctx, DNS_R_REFUSED);
5446 			}
5447 		} else {
5448 			CCTRACE(ISC_LOG_ERROR, "ns__query_start: query_getdb "
5449 					       "failed");
5450 			QUERY_ERROR(qctx, result);
5451 		}
5452 		return (ns_query_done(qctx));
5453 	}
5454 
5455 	/*
5456 	 * We found a database from which we can answer the query.  Update
5457 	 * relevant query context flags if the answer is to be prepared using
5458 	 * authoritative data.
5459 	 */
5460 	qctx->is_staticstub_zone = false;
5461 	if (qctx->is_zone) {
5462 		qctx->authoritative = true;
5463 		if (qctx->zone != NULL) {
5464 			if (dns_zone_gettype(qctx->zone) == dns_zone_mirror) {
5465 				qctx->authoritative = false;
5466 			}
5467 			if (dns_zone_gettype(qctx->zone) == dns_zone_staticstub)
5468 			{
5469 				qctx->is_staticstub_zone = true;
5470 			}
5471 		}
5472 	}
5473 
5474 	/*
5475 	 * Attach to the database which will be used to prepare the answer.
5476 	 * Update query statistics.
5477 	 */
5478 	if (qctx->event == NULL && qctx->client->query.restarts == 0) {
5479 		if (qctx->is_zone) {
5480 			if (qctx->zone != NULL) {
5481 				/*
5482 				 * if is_zone = true, zone = NULL then this is
5483 				 * a DLZ zone.  Don't attempt to attach zone.
5484 				 */
5485 				dns_zone_attach(qctx->zone,
5486 						&qctx->client->query.authzone);
5487 			}
5488 			dns_db_attach(qctx->db, &qctx->client->query.authdb);
5489 		}
5490 		qctx->client->query.authdbset = true;
5491 
5492 		/* Track TCP vs UDP stats per zone */
5493 		if (TCP(qctx->client)) {
5494 			inc_stats(qctx->client, ns_statscounter_tcp);
5495 		} else {
5496 			inc_stats(qctx->client, ns_statscounter_udp);
5497 		}
5498 	}
5499 
5500 	return (query_lookup(qctx));
5501 
5502 cleanup:
5503 	return (result);
5504 }
5505 
5506 /*%
5507  * Perform a local database lookup, in either an authoritative or
5508  * cache database. If unable to answer, call ns_query_done(); otherwise
5509  * hand off processing to query_gotanswer().
5510  */
5511 static isc_result_t
5512 query_lookup(query_ctx_t *qctx) {
5513 	isc_buffer_t b;
5514 	isc_result_t result;
5515 	dns_clientinfomethods_t cm;
5516 	dns_clientinfo_t ci;
5517 	dns_name_t *rpzqname = NULL;
5518 	unsigned int dboptions;
5519 
5520 	CCTRACE(ISC_LOG_DEBUG(3), "query_lookup");
5521 
5522 	CALL_HOOK(NS_QUERY_LOOKUP_BEGIN, qctx);
5523 
5524 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
5525 	dns_clientinfo_init(&ci, qctx->client, NULL);
5526 
5527 	/*
5528 	 * We'll need some resources...
5529 	 */
5530 	qctx->dbuf = ns_client_getnamebuf(qctx->client);
5531 	if (ISC_UNLIKELY(qctx->dbuf == NULL)) {
5532 		CCTRACE(ISC_LOG_ERROR, "query_lookup: ns_client_getnamebuf "
5533 				       "failed (2)");
5534 		QUERY_ERROR(qctx, ISC_R_NOMEMORY);
5535 		return (ns_query_done(qctx));
5536 	}
5537 
5538 	qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
5539 	qctx->rdataset = ns_client_newrdataset(qctx->client);
5540 
5541 	if (ISC_UNLIKELY(qctx->fname == NULL || qctx->rdataset == NULL)) {
5542 		CCTRACE(ISC_LOG_ERROR, "query_lookup: ns_client_newname failed "
5543 				       "(2)");
5544 		QUERY_ERROR(qctx, ISC_R_NOMEMORY);
5545 		return (ns_query_done(qctx));
5546 	}
5547 
5548 	if ((WANTDNSSEC(qctx->client) || qctx->findcoveringnsec) &&
5549 	    (!qctx->is_zone || dns_db_issecure(qctx->db)))
5550 	{
5551 		qctx->sigrdataset = ns_client_newrdataset(qctx->client);
5552 		if (qctx->sigrdataset == NULL) {
5553 			CCTRACE(ISC_LOG_ERROR, "query_lookup: "
5554 					       "ns_client_newrdataset failed "
5555 					       "(2)");
5556 			QUERY_ERROR(qctx, ISC_R_NOMEMORY);
5557 			return (ns_query_done(qctx));
5558 		}
5559 	}
5560 
5561 	/*
5562 	 * Now look for an answer in the database.
5563 	 */
5564 	if (qctx->dns64 && qctx->rpz) {
5565 		rpzqname = qctx->client->query.rpz_st->p_name;
5566 	} else {
5567 		rpzqname = qctx->client->query.qname;
5568 	}
5569 
5570 	dboptions = qctx->client->query.dboptions;
5571 	if (!qctx->is_zone && qctx->findcoveringnsec &&
5572 	    (qctx->type != dns_rdatatype_null || !dns_name_istat(rpzqname)))
5573 	{
5574 		dboptions |= DNS_DBFIND_COVERINGNSEC;
5575 	}
5576 
5577 	result = dns_db_findext(qctx->db, rpzqname, qctx->version, qctx->type,
5578 				dboptions, qctx->client->now, &qctx->node,
5579 				qctx->fname, &cm, &ci, qctx->rdataset,
5580 				qctx->sigrdataset);
5581 
5582 	/*
5583 	 * Fixup fname and sigrdataset.
5584 	 */
5585 	if (qctx->dns64 && qctx->rpz) {
5586 		dns_name_copynf(qctx->client->query.qname, qctx->fname);
5587 		if (qctx->sigrdataset != NULL &&
5588 		    dns_rdataset_isassociated(qctx->sigrdataset)) {
5589 			dns_rdataset_disassociate(qctx->sigrdataset);
5590 		}
5591 	}
5592 
5593 	if (!qctx->is_zone) {
5594 		dns_cache_updatestats(qctx->view->cache, result);
5595 	}
5596 
5597 	if ((qctx->client->query.dboptions & DNS_DBFIND_STALEOK) != 0) {
5598 		char namebuf[DNS_NAME_FORMATSIZE];
5599 		bool success;
5600 
5601 		qctx->client->query.dboptions &= ~DNS_DBFIND_STALEOK;
5602 		if (dns_rdataset_isassociated(qctx->rdataset) &&
5603 		    dns_rdataset_count(qctx->rdataset) > 0 &&
5604 		    STALE(qctx->rdataset))
5605 		{
5606 			qctx->rdataset->ttl = qctx->view->staleanswerttl;
5607 			success = true;
5608 		} else {
5609 			success = false;
5610 		}
5611 
5612 		dns_name_format(qctx->client->query.qname, namebuf,
5613 				sizeof(namebuf));
5614 		isc_log_write(ns_lctx, NS_LOGCATEGORY_SERVE_STALE,
5615 			      NS_LOGMODULE_QUERY, ISC_LOG_INFO,
5616 			      "%s resolver failure, stale answer %s", namebuf,
5617 			      success ? "used" : "unavailable");
5618 
5619 		if (!success) {
5620 			QUERY_ERROR(qctx, DNS_R_SERVFAIL);
5621 			return (ns_query_done(qctx));
5622 		}
5623 	}
5624 	return (query_gotanswer(qctx, result));
5625 
5626 cleanup:
5627 	return (result);
5628 }
5629 
5630 /*
5631  * Event handler to resume processing a query after recursion.
5632  * If the query has timed out or been canceled or the system
5633  * is shutting down, clean up and exit; otherwise, call
5634  * query_resume() to continue the ongoing work.
5635  */
5636 static void
5637 fetch_callback(isc_task_t *task, isc_event_t *event) {
5638 	dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
5639 	dns_fetch_t *fetch = NULL;
5640 	ns_client_t *client;
5641 	bool fetch_canceled, client_shuttingdown;
5642 	isc_result_t result;
5643 	isc_logcategory_t *logcategory = NS_LOGCATEGORY_QUERY_ERRORS;
5644 	int errorloglevel;
5645 
5646 	UNUSED(task);
5647 
5648 	REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
5649 	client = devent->ev_arg;
5650 	REQUIRE(NS_CLIENT_VALID(client));
5651 	REQUIRE(task == client->task);
5652 	REQUIRE(RECURSING(client));
5653 
5654 	CTRACE(ISC_LOG_DEBUG(3), "fetch_callback");
5655 
5656 	LOCK(&client->query.fetchlock);
5657 	if (client->query.fetch != NULL) {
5658 		/*
5659 		 * This is the fetch we've been waiting for.
5660 		 */
5661 		INSIST(devent->fetch == client->query.fetch);
5662 		client->query.fetch = NULL;
5663 		fetch_canceled = false;
5664 		/*
5665 		 * Update client->now.
5666 		 */
5667 		isc_stdtime_get(&client->now);
5668 	} else {
5669 		/*
5670 		 * This is a fetch completion event for a canceled fetch.
5671 		 * Clean up and don't resume the find.
5672 		 */
5673 		fetch_canceled = true;
5674 	}
5675 	UNLOCK(&client->query.fetchlock);
5676 	INSIST(client->query.fetch == NULL);
5677 
5678 	SAVE(fetch, devent->fetch);
5679 
5680 	/*
5681 	 * We're done recursing, detach from quota and unlink from
5682 	 * the manager's recursing-clients list.
5683 	 */
5684 
5685 	if (client->recursionquota != NULL) {
5686 		isc_quota_detach(&client->recursionquota);
5687 		ns_stats_decrement(client->sctx->nsstats,
5688 				   ns_statscounter_recursclients);
5689 	}
5690 
5691 	LOCK(&client->manager->reclock);
5692 	if (ISC_LINK_LINKED(client, rlink)) {
5693 		ISC_LIST_UNLINK(client->manager->recursing, client, rlink);
5694 	}
5695 	UNLOCK(&client->manager->reclock);
5696 
5697 	client->query.attributes &= ~NS_QUERYATTR_RECURSING;
5698 	client->state = NS_CLIENTSTATE_WORKING;
5699 
5700 	/*
5701 	 * If this client is shutting down, or this transaction
5702 	 * has timed out, do not resume the find.
5703 	 */
5704 	client_shuttingdown = ns_client_shuttingdown(client);
5705 	if (fetch_canceled || client_shuttingdown) {
5706 		free_devent(client, &event, &devent);
5707 		if (fetch_canceled) {
5708 			CTRACE(ISC_LOG_ERROR, "fetch cancelled");
5709 			query_error(client, DNS_R_SERVFAIL, __LINE__);
5710 		} else {
5711 			query_next(client, ISC_R_CANCELED);
5712 		}
5713 	} else {
5714 		query_ctx_t qctx;
5715 
5716 		/*
5717 		 * Initialize a new qctx and use it to resume
5718 		 * from recursion.
5719 		 */
5720 		qctx_init(client, devent, 0, &qctx);
5721 		query_trace(&qctx);
5722 
5723 		result = query_resume(&qctx);
5724 		if (result != ISC_R_SUCCESS) {
5725 			if (result == DNS_R_SERVFAIL) {
5726 				errorloglevel = ISC_LOG_DEBUG(2);
5727 			} else {
5728 				errorloglevel = ISC_LOG_DEBUG(4);
5729 			}
5730 			if (isc_log_wouldlog(ns_lctx, errorloglevel)) {
5731 				dns_resolver_logfetch(fetch, ns_lctx,
5732 						      logcategory,
5733 						      NS_LOGMODULE_QUERY,
5734 						      errorloglevel, false);
5735 			}
5736 		}
5737 
5738 		qctx_destroy(&qctx);
5739 	}
5740 
5741 	dns_resolver_destroyfetch(&fetch);
5742 	isc_nmhandle_unref(client->handle);
5743 }
5744 
5745 /*%
5746  * Check whether the recursion parameters in 'param' match the current query's
5747  * recursion parameters provided in 'qtype', 'qname', and 'qdomain'.
5748  */
5749 static bool
5750 recparam_match(const ns_query_recparam_t *param, dns_rdatatype_t qtype,
5751 	       const dns_name_t *qname, const dns_name_t *qdomain) {
5752 	REQUIRE(param != NULL);
5753 
5754 	return (param->qtype == qtype && param->qname != NULL &&
5755 		qname != NULL && param->qdomain != NULL && qdomain != NULL &&
5756 		dns_name_equal(param->qname, qname) &&
5757 		dns_name_equal(param->qdomain, qdomain));
5758 }
5759 
5760 /*%
5761  * Update 'param' with current query's recursion parameters provided in
5762  * 'qtype', 'qname', and 'qdomain'.
5763  */
5764 static void
5765 recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype,
5766 		const dns_name_t *qname, const dns_name_t *qdomain) {
5767 	REQUIRE(param != NULL);
5768 
5769 	param->qtype = qtype;
5770 
5771 	if (qname == NULL) {
5772 		param->qname = NULL;
5773 	} else {
5774 		param->qname = dns_fixedname_initname(&param->fqname);
5775 		dns_name_copynf(qname, param->qname);
5776 	}
5777 
5778 	if (qdomain == NULL) {
5779 		param->qdomain = NULL;
5780 	} else {
5781 		param->qdomain = dns_fixedname_initname(&param->fqdomain);
5782 		dns_name_copynf(qdomain, param->qdomain);
5783 	}
5784 }
5785 static atomic_uint_fast32_t last_soft, last_hard;
5786 #ifdef ISC_MUTEX_ATOMICS
5787 static isc_once_t last_once = ISC_ONCE_INIT;
5788 static void
5789 last_init() {
5790 	atomic_init(&last_soft, 0);
5791 	atomic_init(&last_hard, 0);
5792 }
5793 #endif /* ifdef ISC_MUTEX_ATOMICS */
5794 
5795 isc_result_t
5796 ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
5797 		 dns_name_t *qdomain, dns_rdataset_t *nameservers,
5798 		 bool resuming) {
5799 	isc_result_t result;
5800 	dns_rdataset_t *rdataset, *sigrdataset;
5801 	isc_sockaddr_t *peeraddr = NULL;
5802 
5803 	CTRACE(ISC_LOG_DEBUG(3), "ns_query_recurse");
5804 
5805 	/*
5806 	 * Check recursion parameters from the previous query to see if they
5807 	 * match.  If not, update recursion parameters and proceed.
5808 	 */
5809 	if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) {
5810 		ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY,
5811 			      ISC_LOG_INFO, "recursion loop detected");
5812 		return (ISC_R_FAILURE);
5813 	}
5814 
5815 	recparam_update(&client->query.recparam, qtype, qname, qdomain);
5816 
5817 	if (!resuming) {
5818 		inc_stats(client, ns_statscounter_recursion);
5819 	}
5820 
5821 	/*
5822 	 * We are about to recurse, which means that this client will
5823 	 * be unavailable for serving new requests for an indeterminate
5824 	 * amount of time.  If this client is currently responsible
5825 	 * for handling incoming queries, set up a new client
5826 	 * object to handle them while we are waiting for a
5827 	 * response.  There is no need to replace TCP clients
5828 	 * because those have already been replaced when the
5829 	 * connection was accepted (if allowed by the TCP quota).
5830 	 */
5831 	if (client->recursionquota == NULL) {
5832 		result = isc_quota_attach(&client->sctx->recursionquota,
5833 					  &client->recursionquota);
5834 		if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) {
5835 			ns_stats_increment(client->sctx->nsstats,
5836 					   ns_statscounter_recursclients);
5837 		}
5838 
5839 		if (result == ISC_R_SOFTQUOTA) {
5840 #ifdef ISC_MUTEX_ATOMICS
5841 			isc_once_do(&last_once, last_init);
5842 #endif /* ifdef ISC_MUTEX_ATOMICS */
5843 			isc_stdtime_t now;
5844 			isc_stdtime_get(&now);
5845 			if (now != atomic_load_relaxed(&last_soft)) {
5846 				atomic_store_relaxed(&last_soft, now);
5847 				ns_client_log(client, NS_LOGCATEGORY_CLIENT,
5848 					      NS_LOGMODULE_QUERY,
5849 					      ISC_LOG_WARNING,
5850 					      "recursive-clients soft limit "
5851 					      "exceeded (%u/%u/%u), "
5852 					      "aborting oldest query",
5853 					      isc_quota_getused(
5854 						      client->recursionquota),
5855 					      isc_quota_getsoft(
5856 						      client->recursionquota),
5857 					      isc_quota_getmax(
5858 						      client->recursionquota));
5859 			}
5860 			ns_client_killoldestquery(client);
5861 			result = ISC_R_SUCCESS;
5862 		} else if (result == ISC_R_QUOTA) {
5863 #ifdef ISC_MUTEX_ATOMICS
5864 			isc_once_do(&last_once, last_init);
5865 #endif /* ifdef ISC_MUTEX_ATOMICS */
5866 			isc_stdtime_t now;
5867 			isc_stdtime_get(&now);
5868 			if (now != atomic_load_relaxed(&last_hard)) {
5869 				ns_server_t *sctx = client->sctx;
5870 				atomic_store_relaxed(&last_hard, now);
5871 				ns_client_log(
5872 					client, NS_LOGCATEGORY_CLIENT,
5873 					NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
5874 					"no more recursive clients "
5875 					"(%u/%u/%u): %s",
5876 					isc_quota_getused(
5877 						&sctx->recursionquota),
5878 					isc_quota_getsoft(
5879 						&sctx->recursionquota),
5880 					isc_quota_getmax(&sctx->recursionquota),
5881 					isc_result_totext(result));
5882 			}
5883 			ns_client_killoldestquery(client);
5884 		}
5885 		if (result != ISC_R_SUCCESS) {
5886 			return (result);
5887 		}
5888 
5889 		ns_client_recursing(client);
5890 	}
5891 
5892 	/*
5893 	 * Invoke the resolver.
5894 	 */
5895 	REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns);
5896 	REQUIRE(client->query.fetch == NULL);
5897 
5898 	rdataset = ns_client_newrdataset(client);
5899 	if (rdataset == NULL) {
5900 		return (ISC_R_NOMEMORY);
5901 	}
5902 
5903 	if (WANTDNSSEC(client)) {
5904 		sigrdataset = ns_client_newrdataset(client);
5905 		if (sigrdataset == NULL) {
5906 			ns_client_putrdataset(client, &rdataset);
5907 			return (ISC_R_NOMEMORY);
5908 		}
5909 	} else {
5910 		sigrdataset = NULL;
5911 	}
5912 
5913 	if (!client->query.timerset) {
5914 		ns_client_settimeout(client, 60);
5915 	}
5916 
5917 	if (!TCP(client)) {
5918 		peeraddr = &client->peeraddr;
5919 	}
5920 
5921 	isc_nmhandle_ref(client->handle);
5922 	result = dns_resolver_createfetch(
5923 		client->view->resolver, qname, qtype, qdomain, nameservers,
5924 		NULL, peeraddr, client->message->id, client->query.fetchoptions,
5925 		0, NULL, client->task, fetch_callback, client, rdataset,
5926 		sigrdataset, &client->query.fetch);
5927 	if (result != ISC_R_SUCCESS) {
5928 		isc_nmhandle_unref(client->handle);
5929 		ns_client_putrdataset(client, &rdataset);
5930 		if (sigrdataset != NULL) {
5931 			ns_client_putrdataset(client, &sigrdataset);
5932 		}
5933 	}
5934 
5935 	/*
5936 	 * We're now waiting for a fetch event. A client which is
5937 	 * shutting down will not be destroyed until all the events
5938 	 * have been received.
5939 	 */
5940 
5941 	return (result);
5942 }
5943 
5944 /*%
5945  * Restores the query context after resuming from recursion, and
5946  * continues the query processing if needed.
5947  */
5948 static isc_result_t
5949 query_resume(query_ctx_t *qctx) {
5950 	isc_result_t result;
5951 	dns_name_t *tname;
5952 	isc_buffer_t b;
5953 #ifdef WANT_QUERYTRACE
5954 	char mbuf[4 * DNS_NAME_FORMATSIZE];
5955 	char qbuf[DNS_NAME_FORMATSIZE];
5956 	char tbuf[DNS_RDATATYPE_FORMATSIZE];
5957 #endif /* ifdef WANT_QUERYTRACE */
5958 
5959 	CCTRACE(ISC_LOG_DEBUG(3), "query_resume");
5960 
5961 	CALL_HOOK(NS_QUERY_RESUME_BEGIN, qctx);
5962 
5963 	qctx->want_restart = false;
5964 
5965 	qctx->rpz_st = qctx->client->query.rpz_st;
5966 	if (qctx->rpz_st != NULL &&
5967 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) {
5968 		CCTRACE(ISC_LOG_DEBUG(3), "resume from RPZ recursion");
5969 #ifdef WANT_QUERYTRACE
5970 		{
5971 			char pbuf[DNS_NAME_FORMATSIZE] = "<unset>";
5972 			char fbuf[DNS_NAME_FORMATSIZE] = "<unset>";
5973 			if (qctx->rpz_st->r_name != NULL) {
5974 				dns_name_format(qctx->rpz_st->r_name, qbuf,
5975 						sizeof(qbuf));
5976 			} else {
5977 				snprintf(qbuf, sizeof(qbuf), "<unset>");
5978 			}
5979 			if (qctx->rpz_st->p_name != NULL) {
5980 				dns_name_format(qctx->rpz_st->p_name, pbuf,
5981 						sizeof(pbuf));
5982 			}
5983 			if (qctx->rpz_st->fname != NULL) {
5984 				dns_name_format(qctx->rpz_st->fname, fbuf,
5985 						sizeof(fbuf));
5986 			}
5987 
5988 			snprintf(mbuf, sizeof(mbuf) - 1,
5989 				 "rpz rname:%s, pname:%s, qctx->fname:%s", qbuf,
5990 				 pbuf, fbuf);
5991 			CCTRACE(ISC_LOG_DEBUG(3), mbuf);
5992 		}
5993 #endif /* ifdef WANT_QUERYTRACE */
5994 
5995 		qctx->is_zone = qctx->rpz_st->q.is_zone;
5996 		qctx->authoritative = qctx->rpz_st->q.authoritative;
5997 		RESTORE(qctx->zone, qctx->rpz_st->q.zone);
5998 		RESTORE(qctx->node, qctx->rpz_st->q.node);
5999 		RESTORE(qctx->db, qctx->rpz_st->q.db);
6000 		RESTORE(qctx->rdataset, qctx->rpz_st->q.rdataset);
6001 		RESTORE(qctx->sigrdataset, qctx->rpz_st->q.sigrdataset);
6002 		qctx->qtype = qctx->rpz_st->q.qtype;
6003 
6004 		if (qctx->event->node != NULL) {
6005 			dns_db_detachnode(qctx->event->db, &qctx->event->node);
6006 		}
6007 		SAVE(qctx->rpz_st->r.db, qctx->event->db);
6008 		qctx->rpz_st->r.r_type = qctx->event->qtype;
6009 		SAVE(qctx->rpz_st->r.r_rdataset, qctx->event->rdataset);
6010 		ns_client_putrdataset(qctx->client, &qctx->event->sigrdataset);
6011 	} else if (REDIRECT(qctx->client)) {
6012 		/*
6013 		 * Restore saved state.
6014 		 */
6015 		CCTRACE(ISC_LOG_DEBUG(3), "resume from redirect recursion");
6016 #ifdef WANT_QUERYTRACE
6017 		dns_name_format(qctx->client->query.redirect.fname, qbuf,
6018 				sizeof(qbuf));
6019 		dns_rdatatype_format(qctx->client->query.redirect.qtype, tbuf,
6020 				     sizeof(tbuf));
6021 		snprintf(mbuf, sizeof(mbuf) - 1,
6022 			 "redirect qctx->fname:%s, qtype:%s, auth:%d", qbuf,
6023 			 tbuf, qctx->client->query.redirect.authoritative);
6024 		CCTRACE(ISC_LOG_DEBUG(3), mbuf);
6025 #endif /* ifdef WANT_QUERYTRACE */
6026 		qctx->qtype = qctx->client->query.redirect.qtype;
6027 		INSIST(qctx->client->query.redirect.rdataset != NULL);
6028 		RESTORE(qctx->rdataset, qctx->client->query.redirect.rdataset);
6029 		RESTORE(qctx->sigrdataset,
6030 			qctx->client->query.redirect.sigrdataset);
6031 		RESTORE(qctx->db, qctx->client->query.redirect.db);
6032 		RESTORE(qctx->node, qctx->client->query.redirect.node);
6033 		RESTORE(qctx->zone, qctx->client->query.redirect.zone);
6034 		qctx->authoritative =
6035 			qctx->client->query.redirect.authoritative;
6036 
6037 		/*
6038 		 * Free resources used while recursing.
6039 		 */
6040 		ns_client_putrdataset(qctx->client, &qctx->event->rdataset);
6041 		ns_client_putrdataset(qctx->client, &qctx->event->sigrdataset);
6042 		if (qctx->event->node != NULL) {
6043 			dns_db_detachnode(qctx->event->db, &qctx->event->node);
6044 		}
6045 		if (qctx->event->db != NULL) {
6046 			dns_db_detach(&qctx->event->db);
6047 		}
6048 	} else {
6049 		CCTRACE(ISC_LOG_DEBUG(3), "resume from normal recursion");
6050 		qctx->authoritative = false;
6051 
6052 		qctx->qtype = qctx->event->qtype;
6053 		SAVE(qctx->db, qctx->event->db);
6054 		SAVE(qctx->node, qctx->event->node);
6055 		SAVE(qctx->rdataset, qctx->event->rdataset);
6056 		SAVE(qctx->sigrdataset, qctx->event->sigrdataset);
6057 	}
6058 	INSIST(qctx->rdataset != NULL);
6059 
6060 	if (qctx->qtype == dns_rdatatype_rrsig ||
6061 	    qctx->qtype == dns_rdatatype_sig) {
6062 		qctx->type = dns_rdatatype_any;
6063 	} else {
6064 		qctx->type = qctx->qtype;
6065 	}
6066 
6067 	CALL_HOOK(NS_QUERY_RESUME_RESTORED, qctx);
6068 
6069 	if (DNS64(qctx->client)) {
6070 		qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64;
6071 		qctx->dns64 = true;
6072 	}
6073 
6074 	if (DNS64EXCLUDE(qctx->client)) {
6075 		qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
6076 		qctx->dns64_exclude = true;
6077 	}
6078 
6079 	if (qctx->rpz_st != NULL &&
6080 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) {
6081 		/*
6082 		 * Has response policy changed out from under us?
6083 		 */
6084 		if (qctx->rpz_st->rpz_ver != qctx->view->rpzs->rpz_ver) {
6085 			ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
6086 				      NS_LOGMODULE_QUERY, DNS_RPZ_INFO_LEVEL,
6087 				      "query_resume: RPZ settings "
6088 				      "out of date "
6089 				      "(rpz_ver %d, expected %d)",
6090 				      qctx->view->rpzs->rpz_ver,
6091 				      qctx->rpz_st->rpz_ver);
6092 			QUERY_ERROR(qctx, DNS_R_SERVFAIL);
6093 			return (ns_query_done(qctx));
6094 		}
6095 	}
6096 
6097 	/*
6098 	 * We'll need some resources...
6099 	 */
6100 	qctx->dbuf = ns_client_getnamebuf(qctx->client);
6101 	if (qctx->dbuf == NULL) {
6102 		CCTRACE(ISC_LOG_ERROR, "query_resume: ns_client_getnamebuf "
6103 				       "failed (1)");
6104 		QUERY_ERROR(qctx, ISC_R_NOMEMORY);
6105 		return (ns_query_done(qctx));
6106 	}
6107 
6108 	qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
6109 	if (qctx->fname == NULL) {
6110 		CCTRACE(ISC_LOG_ERROR, "query_resume: ns_client_newname failed "
6111 				       "(1)");
6112 		QUERY_ERROR(qctx, ISC_R_NOMEMORY);
6113 		return (ns_query_done(qctx));
6114 	}
6115 
6116 	if (qctx->rpz_st != NULL &&
6117 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) {
6118 		tname = qctx->rpz_st->fname;
6119 	} else if (REDIRECT(qctx->client)) {
6120 		tname = qctx->client->query.redirect.fname;
6121 	} else {
6122 		tname = dns_fixedname_name(&qctx->event->foundname);
6123 	}
6124 
6125 	dns_name_copynf(tname, qctx->fname);
6126 
6127 	if (qctx->rpz_st != NULL &&
6128 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) {
6129 		qctx->rpz_st->r.r_result = qctx->event->result;
6130 		result = qctx->rpz_st->q.result;
6131 		free_devent(qctx->client, ISC_EVENT_PTR(&qctx->event),
6132 			    &qctx->event);
6133 	} else if (REDIRECT(qctx->client)) {
6134 		result = qctx->client->query.redirect.result;
6135 	} else {
6136 		result = qctx->event->result;
6137 	}
6138 
6139 	qctx->resuming = true;
6140 
6141 	return (query_gotanswer(qctx, result));
6142 
6143 cleanup:
6144 	return (result);
6145 }
6146 
6147 /*%
6148  * If the query is recursive, check the SERVFAIL cache to see whether
6149  * identical queries have failed recently.  If we find a match, and it was
6150  * from a query with CD=1, *or* if the current query has CD=0, then we just
6151  * return SERVFAIL again.  This prevents a validation failure from eliciting a
6152  * SERVFAIL response to a CD=1 query.
6153  */
6154 isc_result_t
6155 ns__query_sfcache(query_ctx_t *qctx) {
6156 	bool failcache;
6157 	uint32_t flags;
6158 
6159 	/*
6160 	 * The SERVFAIL cache doesn't apply to authoritative queries.
6161 	 */
6162 	if (!RECURSIONOK(qctx->client)) {
6163 		return (ISC_R_COMPLETE);
6164 	}
6165 
6166 	flags = 0;
6167 #ifdef ENABLE_AFL
6168 	if (qctx->client->sctx->fuzztype == isc_fuzz_resolver) {
6169 		failcache = false;
6170 	} else {
6171 		failcache = dns_badcache_find(
6172 			qctx->view->failcache, qctx->client->query.qname,
6173 			qctx->qtype, &flags, &qctx->client->tnow);
6174 	}
6175 #else  /* ifdef ENABLE_AFL */
6176 	failcache = dns_badcache_find(qctx->view->failcache,
6177 				      qctx->client->query.qname, qctx->qtype,
6178 				      &flags, &qctx->client->tnow);
6179 #endif /* ifdef ENABLE_AFL */
6180 	if (failcache &&
6181 	    (((flags & NS_FAILCACHE_CD) != 0) ||
6182 	     ((qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0)))
6183 	{
6184 		if (isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(1))) {
6185 			char namebuf[DNS_NAME_FORMATSIZE];
6186 			char typebuf[DNS_RDATATYPE_FORMATSIZE];
6187 
6188 			dns_name_format(qctx->client->query.qname, namebuf,
6189 					sizeof(namebuf));
6190 			dns_rdatatype_format(qctx->qtype, typebuf,
6191 					     sizeof(typebuf));
6192 			ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
6193 				      NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(1),
6194 				      "servfail cache hit %s/%s (%s)", namebuf,
6195 				      typebuf,
6196 				      ((flags & NS_FAILCACHE_CD) != 0) ? "CD=1"
6197 								       : "CD="
6198 									 "0");
6199 		}
6200 
6201 		qctx->client->attributes |= NS_CLIENTATTR_NOSETFC;
6202 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
6203 		return (ns_query_done(qctx));
6204 	}
6205 
6206 	return (ISC_R_COMPLETE);
6207 }
6208 
6209 /*%
6210  * Handle response rate limiting (RRL).
6211  */
6212 static isc_result_t
6213 query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
6214 	/*
6215 	 * Rate limit these responses to this client.
6216 	 * Do not delay counting and handling obvious referrals,
6217 	 *	since those won't come here again.
6218 	 * Delay handling delegations for which we are certain to recurse and
6219 	 *	return here (DNS_R_DELEGATION, not a child of one of our
6220 	 *	own zones, and recursion enabled)
6221 	 * Don't mess with responses rewritten by RPZ
6222 	 * Count each response at most once.
6223 	 */
6224 
6225 	/*
6226 	 * XXXMPA the rrl system tests fails sometimes and RRL_CHECKED
6227 	 * is set when we are called the second time preventing the
6228 	 * response being dropped.
6229 	 */
6230 	ns_client_log(
6231 		qctx->client, DNS_LOGCATEGORY_RRL, NS_LOGMODULE_QUERY,
6232 		ISC_LOG_DEBUG(99),
6233 		"rrl=%p, HAVECOOKIE=%u, result=%s, "
6234 		"fname=%p(%u), is_zone=%u, RECURSIONOK=%u, "
6235 		"query.rpz_st=%p(%u), RRL_CHECKED=%u\n",
6236 		qctx->client->view->rrl, HAVECOOKIE(qctx->client),
6237 		isc_result_toid(result), qctx->fname,
6238 		qctx->fname != NULL ? dns_name_isabsolute(qctx->fname) : 0,
6239 		qctx->is_zone, RECURSIONOK(qctx->client),
6240 		qctx->client->query.rpz_st,
6241 		qctx->client->query.rpz_st != NULL
6242 			? ((qctx->client->query.rpz_st->state &
6243 			    DNS_RPZ_REWRITTEN) != 0)
6244 			: 0,
6245 		(qctx->client->query.attributes & NS_QUERYATTR_RRL_CHECKED) !=
6246 			0);
6247 
6248 	if (qctx->view->rrl != NULL && !HAVECOOKIE(qctx->client) &&
6249 	    ((qctx->fname != NULL && dns_name_isabsolute(qctx->fname)) ||
6250 	     (result == ISC_R_NOTFOUND && !RECURSIONOK(qctx->client))) &&
6251 	    !(result == DNS_R_DELEGATION && !qctx->is_zone &&
6252 	      RECURSIONOK(qctx->client)) &&
6253 	    (qctx->client->query.rpz_st == NULL ||
6254 	     (qctx->client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
6255 	    (qctx->client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0)
6256 	{
6257 		dns_rdataset_t nc_rdataset;
6258 		bool wouldlog;
6259 		dns_fixedname_t fixed;
6260 		const dns_name_t *constname;
6261 		char log_buf[DNS_RRL_LOG_BUF_LEN];
6262 		isc_result_t nc_result, resp_result;
6263 		dns_rrl_result_t rrl_result;
6264 
6265 		qctx->client->query.attributes |= NS_QUERYATTR_RRL_CHECKED;
6266 
6267 		wouldlog = isc_log_wouldlog(ns_lctx, DNS_RRL_LOG_DROP);
6268 		constname = qctx->fname;
6269 		if (result == DNS_R_NXDOMAIN) {
6270 			/*
6271 			 * Use the database origin name to rate limit NXDOMAIN
6272 			 */
6273 			if (qctx->db != NULL) {
6274 				constname = dns_db_origin(qctx->db);
6275 			}
6276 			resp_result = result;
6277 		} else if (result == DNS_R_NCACHENXDOMAIN &&
6278 			   qctx->rdataset != NULL &&
6279 			   dns_rdataset_isassociated(qctx->rdataset) &&
6280 			   (qctx->rdataset->attributes &
6281 			    DNS_RDATASETATTR_NEGATIVE) != 0)
6282 		{
6283 			/*
6284 			 * Try to use owner name in the negative cache SOA.
6285 			 */
6286 			dns_fixedname_init(&fixed);
6287 			dns_rdataset_init(&nc_rdataset);
6288 			for (nc_result = dns_rdataset_first(qctx->rdataset);
6289 			     nc_result == ISC_R_SUCCESS;
6290 			     nc_result = dns_rdataset_next(qctx->rdataset))
6291 			{
6292 				dns_ncache_current(qctx->rdataset,
6293 						   dns_fixedname_name(&fixed),
6294 						   &nc_rdataset);
6295 				if (nc_rdataset.type == dns_rdatatype_soa) {
6296 					dns_rdataset_disassociate(&nc_rdataset);
6297 					constname = dns_fixedname_name(&fixed);
6298 					break;
6299 				}
6300 				dns_rdataset_disassociate(&nc_rdataset);
6301 			}
6302 			resp_result = DNS_R_NXDOMAIN;
6303 		} else if (result == DNS_R_NXRRSET || result == DNS_R_EMPTYNAME)
6304 		{
6305 			resp_result = DNS_R_NXRRSET;
6306 		} else if (result == DNS_R_DELEGATION) {
6307 			resp_result = result;
6308 		} else if (result == ISC_R_NOTFOUND) {
6309 			/*
6310 			 * Handle referral to ".", including when recursion
6311 			 * is off or not requested and the hints have not
6312 			 * been loaded or we have "additional-from-cache no".
6313 			 */
6314 			constname = dns_rootname;
6315 			resp_result = DNS_R_DELEGATION;
6316 		} else {
6317 			resp_result = ISC_R_SUCCESS;
6318 		}
6319 
6320 		rrl_result = dns_rrl(
6321 			qctx->view, &qctx->client->peeraddr, TCP(qctx->client),
6322 			qctx->client->message->rdclass, qctx->qtype, constname,
6323 			resp_result, qctx->client->now, wouldlog, log_buf,
6324 			sizeof(log_buf));
6325 		if (rrl_result != DNS_RRL_RESULT_OK) {
6326 			/*
6327 			 * Log dropped or slipped responses in the query
6328 			 * category so that requests are not silently lost.
6329 			 * Starts of rate-limited bursts are logged in
6330 			 * DNS_LOGCATEGORY_RRL.
6331 			 *
6332 			 * Dropped responses are counted with dropped queries
6333 			 * in QryDropped while slipped responses are counted
6334 			 * with other truncated responses in RespTruncated.
6335 			 */
6336 			if (wouldlog) {
6337 				ns_client_log(qctx->client, DNS_LOGCATEGORY_RRL,
6338 					      NS_LOGMODULE_QUERY,
6339 					      DNS_RRL_LOG_DROP, "%s", log_buf);
6340 			}
6341 
6342 			if (!qctx->view->rrl->log_only) {
6343 				if (rrl_result == DNS_RRL_RESULT_DROP) {
6344 					/*
6345 					 * These will also be counted in
6346 					 * ns_statscounter_dropped
6347 					 */
6348 					inc_stats(qctx->client,
6349 						  ns_statscounter_ratedropped);
6350 					QUERY_ERROR(qctx, DNS_R_DROP);
6351 				} else {
6352 					/*
6353 					 * These will also be counted in
6354 					 * ns_statscounter_truncatedresp
6355 					 */
6356 					inc_stats(qctx->client,
6357 						  ns_statscounter_rateslipped);
6358 					if (WANTCOOKIE(qctx->client)) {
6359 						qctx->client->message->flags &=
6360 							~DNS_MESSAGEFLAG_AA;
6361 						qctx->client->message->flags &=
6362 							~DNS_MESSAGEFLAG_AD;
6363 						qctx->client->message->rcode =
6364 							dns_rcode_badcookie;
6365 					} else {
6366 						qctx->client->message->flags |=
6367 							DNS_MESSAGEFLAG_TC;
6368 						if (resp_result ==
6369 						    DNS_R_NXDOMAIN) {
6370 							qctx->client->message
6371 								->rcode =
6372 								dns_rcode_nxdomain;
6373 						}
6374 					}
6375 				}
6376 				return (DNS_R_DROP);
6377 			}
6378 		}
6379 	}
6380 
6381 	return (ISC_R_SUCCESS);
6382 }
6383 
6384 /*%
6385  * Do any RPZ rewriting that may be needed for this query.
6386  */
6387 static isc_result_t
6388 query_checkrpz(query_ctx_t *qctx, isc_result_t result) {
6389 	isc_result_t rresult;
6390 
6391 	CCTRACE(ISC_LOG_DEBUG(3), "query_checkrpz");
6392 
6393 	rresult = rpz_rewrite(qctx->client, qctx->qtype, result, qctx->resuming,
6394 			      qctx->rdataset, qctx->sigrdataset);
6395 	qctx->rpz_st = qctx->client->query.rpz_st;
6396 	switch (rresult) {
6397 	case ISC_R_SUCCESS:
6398 		break;
6399 	case DNS_R_DISALLOWED:
6400 		return (result);
6401 	case DNS_R_DELEGATION:
6402 		/*
6403 		 * recursing for NS names or addresses,
6404 		 * so save the main query state
6405 		 */
6406 		qctx->rpz_st->q.qtype = qctx->qtype;
6407 		qctx->rpz_st->q.is_zone = qctx->is_zone;
6408 		qctx->rpz_st->q.authoritative = qctx->authoritative;
6409 		SAVE(qctx->rpz_st->q.zone, qctx->zone);
6410 		SAVE(qctx->rpz_st->q.db, qctx->db);
6411 		SAVE(qctx->rpz_st->q.node, qctx->node);
6412 		SAVE(qctx->rpz_st->q.rdataset, qctx->rdataset);
6413 		SAVE(qctx->rpz_st->q.sigrdataset, qctx->sigrdataset);
6414 		dns_name_copynf(qctx->fname, qctx->rpz_st->fname);
6415 		qctx->rpz_st->q.result = result;
6416 		qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
6417 		return (ISC_R_COMPLETE);
6418 	default:
6419 		QUERY_ERROR(qctx, rresult);
6420 		return (ISC_R_COMPLETE);
6421 	}
6422 
6423 	if (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_MISS) {
6424 		qctx->rpz_st->state |= DNS_RPZ_REWRITTEN;
6425 	}
6426 
6427 	if (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_MISS &&
6428 	    qctx->rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU &&
6429 	    (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY ||
6430 	     !TCP(qctx->client)) &&
6431 	    qctx->rpz_st->m.policy != DNS_RPZ_POLICY_ERROR)
6432 	{
6433 		/*
6434 		 * We got a hit and are going to answer with our
6435 		 * fiction. Ensure that we answer with the name
6436 		 * we looked up even if we were stopped short
6437 		 * in recursion or for a deferral.
6438 		 */
6439 		dns_name_copynf(qctx->client->query.qname, qctx->fname);
6440 		rpz_clean(&qctx->zone, &qctx->db, &qctx->node, NULL);
6441 		if (qctx->rpz_st->m.rdataset != NULL) {
6442 			ns_client_putrdataset(qctx->client, &qctx->rdataset);
6443 			RESTORE(qctx->rdataset, qctx->rpz_st->m.rdataset);
6444 		} else {
6445 			qctx_clean(qctx);
6446 		}
6447 		qctx->version = NULL;
6448 
6449 		RESTORE(qctx->node, qctx->rpz_st->m.node);
6450 		RESTORE(qctx->db, qctx->rpz_st->m.db);
6451 		RESTORE(qctx->version, qctx->rpz_st->m.version);
6452 		RESTORE(qctx->zone, qctx->rpz_st->m.zone);
6453 
6454 		/*
6455 		 * Add SOA record to additional section
6456 		 */
6457 		if (qctx->rpz_st->m.rpz->addsoa) {
6458 			bool override_ttl =
6459 				dns_rdataset_isassociated(qctx->rdataset);
6460 			rresult = query_addsoa(qctx, override_ttl,
6461 					       DNS_SECTION_ADDITIONAL);
6462 			if (rresult != ISC_R_SUCCESS) {
6463 				QUERY_ERROR(qctx, result);
6464 				return (ISC_R_COMPLETE);
6465 			}
6466 		}
6467 
6468 		switch (qctx->rpz_st->m.policy) {
6469 		case DNS_RPZ_POLICY_TCP_ONLY:
6470 			qctx->client->message->flags |= DNS_MESSAGEFLAG_TC;
6471 			if (result == DNS_R_NXDOMAIN ||
6472 			    result == DNS_R_NCACHENXDOMAIN) {
6473 				qctx->client->message->rcode =
6474 					dns_rcode_nxdomain;
6475 			}
6476 			rpz_log_rewrite(qctx->client, false,
6477 					qctx->rpz_st->m.policy,
6478 					qctx->rpz_st->m.type, qctx->zone,
6479 					qctx->rpz_st->p_name, NULL,
6480 					qctx->rpz_st->m.rpz->num);
6481 			return (ISC_R_COMPLETE);
6482 		case DNS_RPZ_POLICY_DROP:
6483 			QUERY_ERROR(qctx, DNS_R_DROP);
6484 			rpz_log_rewrite(qctx->client, false,
6485 					qctx->rpz_st->m.policy,
6486 					qctx->rpz_st->m.type, qctx->zone,
6487 					qctx->rpz_st->p_name, NULL,
6488 					qctx->rpz_st->m.rpz->num);
6489 			return (ISC_R_COMPLETE);
6490 		case DNS_RPZ_POLICY_NXDOMAIN:
6491 			result = DNS_R_NXDOMAIN;
6492 			qctx->nxrewrite = true;
6493 			qctx->rpz = true;
6494 			break;
6495 		case DNS_RPZ_POLICY_NODATA:
6496 			qctx->nxrewrite = true;
6497 		/* FALLTHROUGH */
6498 		case DNS_RPZ_POLICY_DNS64:
6499 			result = DNS_R_NXRRSET;
6500 			qctx->rpz = true;
6501 			break;
6502 		case DNS_RPZ_POLICY_RECORD:
6503 			result = qctx->rpz_st->m.result;
6504 			if (qctx->qtype == dns_rdatatype_any &&
6505 			    result != DNS_R_CNAME) {
6506 				/*
6507 				 * We will add all of the rdatasets of
6508 				 * the node by iterating later,
6509 				 * and set the TTL then.
6510 				 */
6511 				if (dns_rdataset_isassociated(qctx->rdataset)) {
6512 					dns_rdataset_disassociate(
6513 						qctx->rdataset);
6514 				}
6515 			} else {
6516 				/*
6517 				 * We will add this rdataset.
6518 				 */
6519 				qctx->rdataset->ttl =
6520 					ISC_MIN(qctx->rdataset->ttl,
6521 						qctx->rpz_st->m.ttl);
6522 			}
6523 			qctx->rpz = true;
6524 			break;
6525 		case DNS_RPZ_POLICY_WILDCNAME: {
6526 			dns_rdata_t rdata = DNS_RDATA_INIT;
6527 			dns_rdata_cname_t cname;
6528 			result = dns_rdataset_first(qctx->rdataset);
6529 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
6530 			dns_rdataset_current(qctx->rdataset, &rdata);
6531 			result = dns_rdata_tostruct(&rdata, &cname, NULL);
6532 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
6533 			dns_rdata_reset(&rdata);
6534 			result = query_rpzcname(qctx, &cname.cname);
6535 			if (result != ISC_R_SUCCESS) {
6536 				return (ISC_R_COMPLETE);
6537 			}
6538 			qctx->fname = NULL;
6539 			qctx->want_restart = true;
6540 			return (ISC_R_COMPLETE);
6541 		}
6542 		case DNS_RPZ_POLICY_CNAME:
6543 			/*
6544 			 * Add overriding CNAME from a named.conf
6545 			 * response-policy statement
6546 			 */
6547 			result = query_rpzcname(qctx,
6548 						&qctx->rpz_st->m.rpz->cname);
6549 			if (result != ISC_R_SUCCESS) {
6550 				return (ISC_R_COMPLETE);
6551 			}
6552 			qctx->fname = NULL;
6553 			qctx->want_restart = true;
6554 			return (ISC_R_COMPLETE);
6555 		default:
6556 			INSIST(0);
6557 			ISC_UNREACHABLE();
6558 		}
6559 
6560 		/*
6561 		 * Turn off DNSSEC because the results of a
6562 		 * response policy zone cannot verify.
6563 		 */
6564 		qctx->client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
6565 					      NS_CLIENTATTR_WANTAD);
6566 		qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
6567 		ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
6568 		qctx->rpz_st->q.is_zone = qctx->is_zone;
6569 		qctx->is_zone = true;
6570 		rpz_log_rewrite(qctx->client, false, qctx->rpz_st->m.policy,
6571 				qctx->rpz_st->m.type, qctx->zone,
6572 				qctx->rpz_st->p_name, NULL,
6573 				qctx->rpz_st->m.rpz->num);
6574 	}
6575 
6576 	return (result);
6577 }
6578 
6579 /*%
6580  * Add a CNAME to a query response, including translating foo.evil.com and
6581  *	*.evil.com CNAME *.example.com
6582  * to
6583  *	foo.evil.com CNAME foo.evil.com.example.com
6584  */
6585 static isc_result_t
6586 query_rpzcname(query_ctx_t *qctx, dns_name_t *cname) {
6587 	ns_client_t *client;
6588 	dns_fixedname_t prefix, suffix;
6589 	unsigned int labels;
6590 	isc_result_t result;
6591 
6592 	REQUIRE(qctx != NULL && qctx->client != NULL);
6593 
6594 	client = qctx->client;
6595 
6596 	CTRACE(ISC_LOG_DEBUG(3), "query_rpzcname");
6597 
6598 	labels = dns_name_countlabels(cname);
6599 	if (labels > 2 && dns_name_iswildcard(cname)) {
6600 		dns_fixedname_init(&prefix);
6601 		dns_name_split(client->query.qname, 1,
6602 			       dns_fixedname_name(&prefix), NULL);
6603 		dns_fixedname_init(&suffix);
6604 		dns_name_split(cname, labels - 1, NULL,
6605 			       dns_fixedname_name(&suffix));
6606 		result = dns_name_concatenate(dns_fixedname_name(&prefix),
6607 					      dns_fixedname_name(&suffix),
6608 					      qctx->fname, NULL);
6609 		if (result == DNS_R_NAMETOOLONG) {
6610 			client->message->rcode = dns_rcode_yxdomain;
6611 		} else if (result != ISC_R_SUCCESS) {
6612 			return (result);
6613 		}
6614 	} else {
6615 		dns_name_copynf(cname, qctx->fname);
6616 	}
6617 
6618 	ns_client_keepname(client, qctx->fname, qctx->dbuf);
6619 	result = query_addcname(qctx, dns_trust_authanswer,
6620 				qctx->rpz_st->m.ttl);
6621 	if (result != ISC_R_SUCCESS) {
6622 		return (result);
6623 	}
6624 
6625 	rpz_log_rewrite(client, false, qctx->rpz_st->m.policy,
6626 			qctx->rpz_st->m.type, qctx->rpz_st->m.zone,
6627 			qctx->rpz_st->p_name, qctx->fname,
6628 			qctx->rpz_st->m.rpz->num);
6629 
6630 	ns_client_qnamereplace(client, qctx->fname);
6631 
6632 	/*
6633 	 * Turn off DNSSEC because the results of a
6634 	 * response policy zone cannot verify.
6635 	 */
6636 	client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
6637 				NS_CLIENTATTR_WANTAD);
6638 
6639 	return (ISC_R_SUCCESS);
6640 }
6641 
6642 /*%
6643  * Check the configured trust anchors for a root zone trust anchor
6644  * with a key id that matches qctx->client->query.root_key_sentinel_keyid.
6645  *
6646  * Return true when found, otherwise return false.
6647  */
6648 static bool
6649 has_ta(query_ctx_t *qctx) {
6650 	dns_keytable_t *keytable = NULL;
6651 	dns_keynode_t *keynode = NULL;
6652 	dns_rdataset_t dsset;
6653 	dns_keytag_t sentinel = qctx->client->query.root_key_sentinel_keyid;
6654 	isc_result_t result;
6655 
6656 	result = dns_view_getsecroots(qctx->view, &keytable);
6657 	if (result != ISC_R_SUCCESS) {
6658 		return (false);
6659 	}
6660 
6661 	result = dns_keytable_find(keytable, dns_rootname, &keynode);
6662 	if (result != ISC_R_SUCCESS) {
6663 		if (keynode != NULL) {
6664 			dns_keytable_detachkeynode(keytable, &keynode);
6665 		}
6666 		dns_keytable_detach(&keytable);
6667 		return (false);
6668 	}
6669 
6670 	dns_rdataset_init(&dsset);
6671 	if (dns_keynode_dsset(keynode, &dsset)) {
6672 		for (result = dns_rdataset_first(&dsset);
6673 		     result == ISC_R_SUCCESS;
6674 		     result = dns_rdataset_next(&dsset))
6675 		{
6676 			dns_rdata_t rdata = DNS_RDATA_INIT;
6677 			dns_rdata_ds_t ds;
6678 
6679 			dns_rdata_reset(&rdata);
6680 			dns_rdataset_current(&dsset, &rdata);
6681 			result = dns_rdata_tostruct(&rdata, &ds, NULL);
6682 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
6683 			if (ds.key_tag == sentinel) {
6684 				dns_keytable_detachkeynode(keytable, &keynode);
6685 				dns_keytable_detach(&keytable);
6686 				dns_rdataset_disassociate(&dsset);
6687 				return (true);
6688 			}
6689 		}
6690 		dns_rdataset_disassociate(&dsset);
6691 	}
6692 
6693 	if (keynode != NULL) {
6694 		dns_keytable_detachkeynode(keytable, &keynode);
6695 	}
6696 
6697 	dns_keytable_detach(&keytable);
6698 
6699 	return (false);
6700 }
6701 
6702 /*%
6703  * Check if a root key sentinel SERVFAIL should be returned.
6704  */
6705 static bool
6706 root_key_sentinel_return_servfail(query_ctx_t *qctx, isc_result_t result) {
6707 	/*
6708 	 * Are we looking at a "root-key-sentinel" query?
6709 	 */
6710 	if (!qctx->client->query.root_key_sentinel_is_ta &&
6711 	    !qctx->client->query.root_key_sentinel_not_ta)
6712 	{
6713 		return (false);
6714 	}
6715 
6716 	/*
6717 	 * We only care about the query if 'result' indicates we have a cached
6718 	 * answer.
6719 	 */
6720 	switch (result) {
6721 	case ISC_R_SUCCESS:
6722 	case DNS_R_CNAME:
6723 	case DNS_R_DNAME:
6724 	case DNS_R_NCACHENXDOMAIN:
6725 	case DNS_R_NCACHENXRRSET:
6726 		break;
6727 	default:
6728 		return (false);
6729 	}
6730 
6731 	/*
6732 	 * Do we meet the specified conditions to return SERVFAIL?
6733 	 */
6734 	if (!qctx->is_zone && qctx->rdataset->trust == dns_trust_secure &&
6735 	    ((qctx->client->query.root_key_sentinel_is_ta && !has_ta(qctx)) ||
6736 	     (qctx->client->query.root_key_sentinel_not_ta && has_ta(qctx))))
6737 	{
6738 		return (true);
6739 	}
6740 
6741 	/*
6742 	 * As special processing may only be triggered by the original QNAME,
6743 	 * disable it after following a CNAME/DNAME.
6744 	 */
6745 	qctx->client->query.root_key_sentinel_is_ta = false;
6746 	qctx->client->query.root_key_sentinel_not_ta = false;
6747 
6748 	return (false);
6749 }
6750 
6751 /*%
6752  * If serving stale answers is allowed, set up 'qctx' to look for one and
6753  * return true; otherwise, return false.
6754  */
6755 static bool
6756 query_usestale(query_ctx_t *qctx) {
6757 	bool staleanswersok = false;
6758 	dns_ttl_t stale_ttl = 0;
6759 	isc_result_t result;
6760 
6761 	qctx_clean(qctx);
6762 	qctx_freedata(qctx);
6763 
6764 	/*
6765 	 * Stale answers only make sense if stale_ttl > 0 but we want rndc to
6766 	 * be able to control returning stale answers if they are configured.
6767 	 */
6768 	dns_db_attach(qctx->client->view->cachedb, &qctx->db);
6769 	result = dns_db_getservestalettl(qctx->db, &stale_ttl);
6770 	if (result == ISC_R_SUCCESS && stale_ttl > 0) {
6771 		switch (qctx->client->view->staleanswersok) {
6772 		case dns_stale_answer_yes:
6773 			staleanswersok = true;
6774 			break;
6775 		case dns_stale_answer_conf:
6776 			staleanswersok = qctx->client->view->staleanswersenable;
6777 			break;
6778 		case dns_stale_answer_no:
6779 			staleanswersok = false;
6780 			break;
6781 		}
6782 	} else {
6783 		staleanswersok = false;
6784 	}
6785 
6786 	if (staleanswersok) {
6787 		qctx->client->query.dboptions |= DNS_DBFIND_STALEOK;
6788 		inc_stats(qctx->client, ns_statscounter_trystale);
6789 		if (qctx->client->query.fetch != NULL) {
6790 			dns_resolver_destroyfetch(&qctx->client->query.fetch);
6791 		}
6792 	} else {
6793 		dns_db_detach(&qctx->db);
6794 	}
6795 
6796 	return (staleanswersok);
6797 }
6798 
6799 /*%
6800  * Continue after doing a database lookup or returning from
6801  * recursion, and call out to the next function depending on the
6802  * result from the search.
6803  */
6804 static isc_result_t
6805 query_gotanswer(query_ctx_t *qctx, isc_result_t res) {
6806 	isc_result_t result = res;
6807 	char errmsg[256];
6808 
6809 	CCTRACE(ISC_LOG_DEBUG(3), "query_gotanswer");
6810 
6811 	CALL_HOOK(NS_QUERY_GOT_ANSWER_BEGIN, qctx);
6812 
6813 	if (query_checkrrl(qctx, result) != ISC_R_SUCCESS) {
6814 		return (ns_query_done(qctx));
6815 	}
6816 
6817 	if (!RECURSING(qctx->client) &&
6818 	    !dns_name_equal(qctx->client->query.qname, dns_rootname))
6819 	{
6820 		result = query_checkrpz(qctx, result);
6821 		if (result == ISC_R_COMPLETE) {
6822 			return (ns_query_done(qctx));
6823 		}
6824 	}
6825 
6826 	/*
6827 	 * If required, handle special "root-key-sentinel-is-ta-<keyid>" and
6828 	 * "root-key-sentinel-not-ta-<keyid>" labels by returning SERVFAIL.
6829 	 */
6830 	if (root_key_sentinel_return_servfail(qctx, result)) {
6831 		/*
6832 		 * Don't record this response in the SERVFAIL cache.
6833 		 */
6834 		qctx->client->attributes |= NS_CLIENTATTR_NOSETFC;
6835 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
6836 		return (ns_query_done(qctx));
6837 	}
6838 
6839 	switch (result) {
6840 	case ISC_R_SUCCESS:
6841 		return (query_prepresponse(qctx));
6842 
6843 	case DNS_R_GLUE:
6844 	case DNS_R_ZONECUT:
6845 		INSIST(qctx->is_zone);
6846 		qctx->authoritative = false;
6847 		return (query_prepresponse(qctx));
6848 
6849 	case ISC_R_NOTFOUND:
6850 		return (query_notfound(qctx));
6851 
6852 	case DNS_R_DELEGATION:
6853 		return (query_delegation(qctx));
6854 
6855 	case DNS_R_EMPTYNAME:
6856 		return (query_nodata(qctx, DNS_R_EMPTYNAME));
6857 	case DNS_R_NXRRSET:
6858 		return (query_nodata(qctx, DNS_R_NXRRSET));
6859 
6860 	case DNS_R_EMPTYWILD:
6861 		return (query_nxdomain(qctx, true));
6862 
6863 	case DNS_R_NXDOMAIN:
6864 		return (query_nxdomain(qctx, false));
6865 
6866 	case DNS_R_COVERINGNSEC:
6867 		return (query_coveringnsec(qctx));
6868 
6869 	case DNS_R_NCACHENXDOMAIN:
6870 		result = query_redirect(qctx);
6871 		if (result != ISC_R_COMPLETE) {
6872 			return (result);
6873 		}
6874 		return (query_ncache(qctx, DNS_R_NCACHENXDOMAIN));
6875 
6876 	case DNS_R_NCACHENXRRSET:
6877 		return (query_ncache(qctx, DNS_R_NCACHENXRRSET));
6878 
6879 	case DNS_R_CNAME:
6880 		return (query_cname(qctx));
6881 
6882 	case DNS_R_DNAME:
6883 		return (query_dname(qctx));
6884 
6885 	default:
6886 		/*
6887 		 * Something has gone wrong.
6888 		 */
6889 		snprintf(errmsg, sizeof(errmsg) - 1,
6890 			 "query_gotanswer: unexpected error: %s",
6891 			 isc_result_totext(result));
6892 		CCTRACE(ISC_LOG_ERROR, errmsg);
6893 		if (qctx->resuming && query_usestale(qctx)) {
6894 			/*
6895 			 * If serve-stale is enabled, query_usestale() already
6896 			 * set up 'qctx' for looking up a stale response.
6897 			 */
6898 			return (query_lookup(qctx));
6899 		}
6900 
6901 		/*
6902 		 * Regardless of the triggering result, we definitely
6903 		 * want to return SERVFAIL from here.
6904 		 */
6905 		qctx->client->rcode_override = dns_rcode_servfail;
6906 
6907 		QUERY_ERROR(qctx, result);
6908 		return (ns_query_done(qctx));
6909 	}
6910 
6911 cleanup:
6912 	return (result);
6913 }
6914 
6915 static void
6916 query_addnoqnameproof(query_ctx_t *qctx) {
6917 	ns_client_t *client = qctx->client;
6918 	isc_buffer_t *dbuf, b;
6919 	dns_name_t *fname = NULL;
6920 	dns_rdataset_t *neg = NULL, *negsig = NULL;
6921 	isc_result_t result = ISC_R_NOMEMORY;
6922 
6923 	CTRACE(ISC_LOG_DEBUG(3), "query_addnoqnameproof");
6924 
6925 	if (qctx->noqname == NULL) {
6926 		return;
6927 	}
6928 
6929 	dbuf = ns_client_getnamebuf(client);
6930 	if (dbuf == NULL) {
6931 		goto cleanup;
6932 	}
6933 
6934 	fname = ns_client_newname(client, dbuf, &b);
6935 	neg = ns_client_newrdataset(client);
6936 	negsig = ns_client_newrdataset(client);
6937 	if (fname == NULL || neg == NULL || negsig == NULL) {
6938 		goto cleanup;
6939 	}
6940 
6941 	result = dns_rdataset_getnoqname(qctx->noqname, fname, neg, negsig);
6942 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
6943 
6944 	query_addrrset(qctx, &fname, &neg, &negsig, dbuf,
6945 		       DNS_SECTION_AUTHORITY);
6946 
6947 	if ((qctx->noqname->attributes & DNS_RDATASETATTR_CLOSEST) == 0) {
6948 		goto cleanup;
6949 	}
6950 
6951 	if (fname == NULL) {
6952 		dbuf = ns_client_getnamebuf(client);
6953 		if (dbuf == NULL) {
6954 			goto cleanup;
6955 		}
6956 		fname = ns_client_newname(client, dbuf, &b);
6957 	}
6958 
6959 	if (neg == NULL) {
6960 		neg = ns_client_newrdataset(client);
6961 	} else if (dns_rdataset_isassociated(neg)) {
6962 		dns_rdataset_disassociate(neg);
6963 	}
6964 
6965 	if (negsig == NULL) {
6966 		negsig = ns_client_newrdataset(client);
6967 	} else if (dns_rdataset_isassociated(negsig)) {
6968 		dns_rdataset_disassociate(negsig);
6969 	}
6970 
6971 	if (fname == NULL || neg == NULL || negsig == NULL) {
6972 		goto cleanup;
6973 	}
6974 	result = dns_rdataset_getclosest(qctx->noqname, fname, neg, negsig);
6975 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
6976 
6977 	query_addrrset(qctx, &fname, &neg, &negsig, dbuf,
6978 		       DNS_SECTION_AUTHORITY);
6979 
6980 cleanup:
6981 	if (neg != NULL) {
6982 		ns_client_putrdataset(client, &neg);
6983 	}
6984 	if (negsig != NULL) {
6985 		ns_client_putrdataset(client, &negsig);
6986 	}
6987 	if (fname != NULL) {
6988 		ns_client_releasename(client, &fname);
6989 	}
6990 }
6991 
6992 /*%
6993  * Build the response for a query for type ANY.
6994  */
6995 static isc_result_t
6996 query_respond_any(query_ctx_t *qctx) {
6997 	bool found = false, hidden = false;
6998 	dns_rdatasetiter_t *rdsiter = NULL;
6999 	isc_result_t result;
7000 	dns_rdatatype_t onetype = 0; /* type to use for minimal-any */
7001 	isc_buffer_t b;
7002 
7003 	CCTRACE(ISC_LOG_DEBUG(3), "query_respond_any");
7004 
7005 	CALL_HOOK(NS_QUERY_RESPOND_ANY_BEGIN, qctx);
7006 
7007 	result = dns_db_allrdatasets(qctx->db, qctx->node, qctx->version, 0,
7008 				     &rdsiter);
7009 	if (result != ISC_R_SUCCESS) {
7010 		CCTRACE(ISC_LOG_ERROR, "query_respond_any: allrdatasets "
7011 				       "failed");
7012 		QUERY_ERROR(qctx, result);
7013 		return (ns_query_done(qctx));
7014 	}
7015 
7016 	/*
7017 	 * Calling query_addrrset() with a non-NULL dbuf is going
7018 	 * to either keep or release the name.  We don't want it to
7019 	 * release fname, since we may have to call query_addrrset()
7020 	 * more than once.  That means we have to call ns_client_keepname()
7021 	 * now, and pass a NULL dbuf to query_addrrset().
7022 	 *
7023 	 * If we do a query_addrrset() below, we must set qctx->fname to
7024 	 * NULL before leaving this block, otherwise we might try to
7025 	 * cleanup qctx->fname even though we're using it!
7026 	 */
7027 	ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
7028 	qctx->tname = qctx->fname;
7029 
7030 	result = dns_rdatasetiter_first(rdsiter);
7031 	while (result == ISC_R_SUCCESS) {
7032 		dns_rdatasetiter_current(rdsiter, qctx->rdataset);
7033 
7034 		/*
7035 		 * We found an NS RRset; no need to add one later.
7036 		 */
7037 		if (qctx->qtype == dns_rdatatype_any &&
7038 		    qctx->rdataset->type == dns_rdatatype_ns)
7039 		{
7040 			qctx->answer_has_ns = true;
7041 		}
7042 
7043 		/*
7044 		 * Note: if we're in this function, then qctx->type
7045 		 * is guaranteed to be ANY, but qctx->qtype (i.e. the
7046 		 * original type requested) might have been RRSIG or
7047 		 * SIG; we need to check for that.
7048 		 */
7049 		if (qctx->is_zone && qctx->qtype == dns_rdatatype_any &&
7050 		    !dns_db_issecure(qctx->db) &&
7051 		    dns_rdatatype_isdnssec(qctx->rdataset->type))
7052 		{
7053 			/*
7054 			 * The zone may be transitioning from insecure
7055 			 * to secure. Hide DNSSEC records from ANY queries.
7056 			 */
7057 			dns_rdataset_disassociate(qctx->rdataset);
7058 			hidden = true;
7059 		} else if (qctx->view->minimal_any && !TCP(qctx->client) &&
7060 			   !WANTDNSSEC(qctx->client) &&
7061 			   qctx->qtype == dns_rdatatype_any &&
7062 			   (qctx->rdataset->type == dns_rdatatype_sig ||
7063 			    qctx->rdataset->type == dns_rdatatype_rrsig))
7064 		{
7065 			CCTRACE(ISC_LOG_DEBUG(5), "query_respond_any: "
7066 						  "minimal-any skip signature");
7067 			dns_rdataset_disassociate(qctx->rdataset);
7068 		} else if (qctx->view->minimal_any && !TCP(qctx->client) &&
7069 			   onetype != 0 && qctx->rdataset->type != onetype &&
7070 			   qctx->rdataset->covers != onetype)
7071 		{
7072 			CCTRACE(ISC_LOG_DEBUG(5), "query_respond_any: "
7073 						  "minimal-any skip rdataset");
7074 			dns_rdataset_disassociate(qctx->rdataset);
7075 		} else if ((qctx->qtype == dns_rdatatype_any ||
7076 			    qctx->rdataset->type == qctx->qtype) &&
7077 			   qctx->rdataset->type != 0)
7078 		{
7079 			if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client))
7080 			{
7081 				qctx->noqname = qctx->rdataset;
7082 			} else {
7083 				qctx->noqname = NULL;
7084 			}
7085 
7086 			qctx->rpz_st = qctx->client->query.rpz_st;
7087 			if (qctx->rpz_st != NULL) {
7088 				qctx->rdataset->ttl =
7089 					ISC_MIN(qctx->rdataset->ttl,
7090 						qctx->rpz_st->m.ttl);
7091 			}
7092 
7093 			if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
7094 				dns_name_t *name;
7095 				name = (qctx->fname != NULL) ? qctx->fname
7096 							     : qctx->tname;
7097 				query_prefetch(qctx->client, name,
7098 					       qctx->rdataset);
7099 			}
7100 
7101 			/*
7102 			 * Remember the first RRtype we find so we
7103 			 * can skip others with minimal-any.
7104 			 */
7105 			if (qctx->rdataset->type == dns_rdatatype_sig ||
7106 			    qctx->rdataset->type == dns_rdatatype_rrsig)
7107 			{
7108 				onetype = qctx->rdataset->covers;
7109 			} else {
7110 				onetype = qctx->rdataset->type;
7111 			}
7112 
7113 			query_addrrset(qctx,
7114 				       (qctx->fname != NULL) ? &qctx->fname
7115 							     : &qctx->tname,
7116 				       &qctx->rdataset, NULL, NULL,
7117 				       DNS_SECTION_ANSWER);
7118 
7119 			query_addnoqnameproof(qctx);
7120 
7121 			found = true;
7122 			INSIST(qctx->tname != NULL);
7123 
7124 			/*
7125 			 * rdataset is non-NULL only in certain
7126 			 * pathological cases involving DNAMEs.
7127 			 */
7128 			if (qctx->rdataset != NULL) {
7129 				ns_client_putrdataset(qctx->client,
7130 						      &qctx->rdataset);
7131 			}
7132 
7133 			qctx->rdataset = ns_client_newrdataset(qctx->client);
7134 			if (qctx->rdataset == NULL) {
7135 				break;
7136 			}
7137 		} else {
7138 			/*
7139 			 * We're not interested in this rdataset.
7140 			 */
7141 			dns_rdataset_disassociate(qctx->rdataset);
7142 		}
7143 
7144 		result = dns_rdatasetiter_next(rdsiter);
7145 	}
7146 
7147 	dns_rdatasetiter_destroy(&rdsiter);
7148 
7149 	if (result != ISC_R_NOMORE) {
7150 		CCTRACE(ISC_LOG_ERROR, "query_respond_any: rdataset iterator "
7151 				       "failed");
7152 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
7153 		return (ns_query_done(qctx));
7154 	}
7155 
7156 	if (found) {
7157 		/*
7158 		 * Call hook if any answers were found.
7159 		 * Do this before releasing qctx->fname, in case
7160 		 * the hook function needs it.
7161 		 */
7162 		CALL_HOOK(NS_QUERY_RESPOND_ANY_FOUND, qctx);
7163 	}
7164 
7165 	if (qctx->fname != NULL) {
7166 		dns_message_puttempname(qctx->client->message, &qctx->fname);
7167 	}
7168 
7169 	if (found) {
7170 		/*
7171 		 * At least one matching rdataset was found
7172 		 */
7173 		query_addauth(qctx);
7174 	} else if (qctx->qtype == dns_rdatatype_rrsig ||
7175 		   qctx->qtype == dns_rdatatype_sig)
7176 	{
7177 		/*
7178 		 * No matching rdatasets were found, but we got
7179 		 * here on a search for RRSIG/SIG, so that's okay.
7180 		 */
7181 		if (!qctx->is_zone) {
7182 			qctx->authoritative = false;
7183 			qctx->client->attributes &= ~NS_CLIENTATTR_RA;
7184 			query_addauth(qctx);
7185 			return (ns_query_done(qctx));
7186 		}
7187 
7188 		if (qctx->qtype == dns_rdatatype_rrsig &&
7189 		    dns_db_issecure(qctx->db)) {
7190 			char namebuf[DNS_NAME_FORMATSIZE];
7191 			dns_name_format(qctx->client->query.qname, namebuf,
7192 					sizeof(namebuf));
7193 			ns_client_log(qctx->client, DNS_LOGCATEGORY_DNSSEC,
7194 				      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
7195 				      "missing signature for %s", namebuf);
7196 		}
7197 
7198 		qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
7199 		return (query_sign_nodata(qctx));
7200 	} else if (!hidden) {
7201 		/*
7202 		 * No matching rdatasets were found and nothing was
7203 		 * deliberately hidden: something must have gone wrong.
7204 		 */
7205 		QUERY_ERROR(qctx, DNS_R_SERVFAIL);
7206 	}
7207 
7208 	return (ns_query_done(qctx));
7209 
7210 cleanup:
7211 	return (result);
7212 }
7213 
7214 /*
7215  * Set the expire time, if requested, when answering from a slave, mirror, or
7216  * master zone.
7217  */
7218 static void
7219 query_getexpire(query_ctx_t *qctx) {
7220 	dns_zone_t *raw = NULL, *mayberaw;
7221 
7222 	CCTRACE(ISC_LOG_DEBUG(3), "query_getexpire");
7223 
7224 	if (qctx->zone == NULL || !qctx->is_zone ||
7225 	    qctx->qtype != dns_rdatatype_soa ||
7226 	    qctx->client->query.restarts != 0 ||
7227 	    (qctx->client->attributes & NS_CLIENTATTR_WANTEXPIRE) == 0)
7228 	{
7229 		return;
7230 	}
7231 
7232 	dns_zone_getraw(qctx->zone, &raw);
7233 	mayberaw = (raw != NULL) ? raw : qctx->zone;
7234 
7235 	if (dns_zone_gettype(mayberaw) == dns_zone_slave ||
7236 	    dns_zone_gettype(mayberaw) == dns_zone_mirror)
7237 	{
7238 		isc_time_t expiretime;
7239 		uint32_t secs;
7240 		dns_zone_getexpiretime(qctx->zone, &expiretime);
7241 		secs = isc_time_seconds(&expiretime);
7242 		if (secs >= qctx->client->now && qctx->result == ISC_R_SUCCESS)
7243 		{
7244 			qctx->client->attributes |= NS_CLIENTATTR_HAVEEXPIRE;
7245 			qctx->client->expire = secs - qctx->client->now;
7246 		}
7247 	} else if (dns_zone_gettype(mayberaw) == dns_zone_master) {
7248 		isc_result_t result;
7249 		dns_rdata_t rdata = DNS_RDATA_INIT;
7250 		dns_rdata_soa_t soa;
7251 
7252 		result = dns_rdataset_first(qctx->rdataset);
7253 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
7254 
7255 		dns_rdataset_current(qctx->rdataset, &rdata);
7256 		result = dns_rdata_tostruct(&rdata, &soa, NULL);
7257 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
7258 
7259 		qctx->client->expire = soa.expire;
7260 		qctx->client->attributes |= NS_CLIENTATTR_HAVEEXPIRE;
7261 	}
7262 
7263 	if (raw != NULL) {
7264 		dns_zone_detach(&raw);
7265 	}
7266 }
7267 
7268 /*%
7269  * Fill the ANSWER section of a positive response.
7270  */
7271 static isc_result_t
7272 query_addanswer(query_ctx_t *qctx) {
7273 	dns_rdataset_t **sigrdatasetp = NULL;
7274 	isc_result_t result;
7275 
7276 	CCTRACE(ISC_LOG_DEBUG(3), "query_addanswer");
7277 
7278 	CALL_HOOK(NS_QUERY_ADDANSWER_BEGIN, qctx);
7279 
7280 	if (qctx->dns64) {
7281 		result = query_dns64(qctx);
7282 		qctx->noqname = NULL;
7283 		dns_rdataset_disassociate(qctx->rdataset);
7284 		dns_message_puttemprdataset(qctx->client->message,
7285 					    &qctx->rdataset);
7286 		if (result == ISC_R_NOMORE) {
7287 #ifndef dns64_bis_return_excluded_addresses
7288 			if (qctx->dns64_exclude) {
7289 				if (!qctx->is_zone) {
7290 					return (ns_query_done(qctx));
7291 				}
7292 				/*
7293 				 * Add a fake SOA record.
7294 				 */
7295 				(void)query_addsoa(qctx, 600,
7296 						   DNS_SECTION_AUTHORITY);
7297 				return (ns_query_done(qctx));
7298 			}
7299 #endif /* ifndef dns64_bis_return_excluded_addresses */
7300 			if (qctx->is_zone) {
7301 				return (query_nodata(qctx, DNS_R_NXDOMAIN));
7302 			} else {
7303 				return (query_ncache(qctx, DNS_R_NXDOMAIN));
7304 			}
7305 		} else if (result != ISC_R_SUCCESS) {
7306 			qctx->result = result;
7307 			return (ns_query_done(qctx));
7308 		}
7309 	} else if (qctx->client->query.dns64_aaaaok != NULL) {
7310 		query_filter64(qctx);
7311 		ns_client_putrdataset(qctx->client, &qctx->rdataset);
7312 	} else {
7313 		if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
7314 			query_prefetch(qctx->client, qctx->fname,
7315 				       qctx->rdataset);
7316 		}
7317 		if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
7318 			sigrdatasetp = &qctx->sigrdataset;
7319 		}
7320 		query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
7321 			       sigrdatasetp, qctx->dbuf, DNS_SECTION_ANSWER);
7322 	}
7323 
7324 	return (ISC_R_COMPLETE);
7325 
7326 cleanup:
7327 	return (result);
7328 }
7329 
7330 /*%
7331  * Build a response for a "normal" query, for a type other than ANY,
7332  * for which we have an answer (either positive or negative).
7333  */
7334 static isc_result_t
7335 query_respond(query_ctx_t *qctx) {
7336 	isc_result_t result;
7337 
7338 	CCTRACE(ISC_LOG_DEBUG(3), "query_respond");
7339 
7340 	/*
7341 	 * Check to see if the AAAA RRset has non-excluded addresses
7342 	 * in it.  If not look for a A RRset.
7343 	 */
7344 	INSIST(qctx->client->query.dns64_aaaaok == NULL);
7345 
7346 	if (qctx->qtype == dns_rdatatype_aaaa && !qctx->dns64_exclude &&
7347 	    !ISC_LIST_EMPTY(qctx->view->dns64) &&
7348 	    qctx->client->message->rdclass == dns_rdataclass_in &&
7349 	    !dns64_aaaaok(qctx->client, qctx->rdataset, qctx->sigrdataset))
7350 	{
7351 		/*
7352 		 * Look to see if there are A records for this name.
7353 		 */
7354 		qctx->client->query.dns64_ttl = qctx->rdataset->ttl;
7355 		SAVE(qctx->client->query.dns64_aaaa, qctx->rdataset);
7356 		SAVE(qctx->client->query.dns64_sigaaaa, qctx->sigrdataset);
7357 		ns_client_releasename(qctx->client, &qctx->fname);
7358 		dns_db_detachnode(qctx->db, &qctx->node);
7359 		qctx->type = qctx->qtype = dns_rdatatype_a;
7360 		qctx->dns64_exclude = qctx->dns64 = true;
7361 
7362 		return (query_lookup(qctx));
7363 	}
7364 
7365 	/*
7366 	 * XXX: This hook is meant to be at the top of this function,
7367 	 * but is postponed until after DNS64 in order to avoid an
7368 	 * assertion if the hook causes recursion. (When DNS64 also
7369 	 * becomes a plugin, it will be necessary to find some
7370 	 * other way to prevent that assertion, since the order in
7371 	 * which plugins are configured can't be enforced.)
7372 	 */
7373 	CALL_HOOK(NS_QUERY_RESPOND_BEGIN, qctx);
7374 
7375 	if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) {
7376 		qctx->noqname = qctx->rdataset;
7377 	} else {
7378 		qctx->noqname = NULL;
7379 	}
7380 
7381 	/*
7382 	 * Special case NS handling
7383 	 */
7384 	if (qctx->is_zone && qctx->qtype == dns_rdatatype_ns) {
7385 		/*
7386 		 * We've already got an NS, no need to add one in
7387 		 * the authority section
7388 		 */
7389 		if (dns_name_equal(qctx->client->query.qname,
7390 				   dns_db_origin(qctx->db))) {
7391 			qctx->answer_has_ns = true;
7392 		}
7393 
7394 		/*
7395 		 * Always add glue for root priming queries, regardless
7396 		 * of "minimal-responses" setting.
7397 		 */
7398 		if (dns_name_equal(qctx->client->query.qname, dns_rootname)) {
7399 			qctx->client->query.attributes &=
7400 				~NS_QUERYATTR_NOADDITIONAL;
7401 			dns_db_attach(qctx->db, &qctx->client->query.gluedb);
7402 		}
7403 	}
7404 
7405 	/*
7406 	 * Set expire time
7407 	 */
7408 	query_getexpire(qctx);
7409 
7410 	result = query_addanswer(qctx);
7411 	if (result != ISC_R_COMPLETE) {
7412 		return (result);
7413 	}
7414 
7415 	query_addnoqnameproof(qctx);
7416 
7417 	/*
7418 	 * We shouldn't ever fail to add 'rdataset'
7419 	 * because it's already in the answer.
7420 	 */
7421 	INSIST(qctx->rdataset == NULL);
7422 
7423 	query_addauth(qctx);
7424 
7425 	return (ns_query_done(qctx));
7426 
7427 cleanup:
7428 	return (result);
7429 }
7430 
7431 static isc_result_t
7432 query_dns64(query_ctx_t *qctx) {
7433 	ns_client_t *client = qctx->client;
7434 	dns_aclenv_t *env =
7435 		ns_interfacemgr_getaclenv(client->manager->interface->mgr);
7436 	dns_name_t *name, *mname;
7437 	dns_rdata_t *dns64_rdata;
7438 	dns_rdata_t rdata = DNS_RDATA_INIT;
7439 	dns_rdatalist_t *dns64_rdatalist;
7440 	dns_rdataset_t *dns64_rdataset;
7441 	dns_rdataset_t *mrdataset;
7442 	isc_buffer_t *buffer;
7443 	isc_region_t r;
7444 	isc_result_t result;
7445 	dns_view_t *view = client->view;
7446 	isc_netaddr_t netaddr;
7447 	dns_dns64_t *dns64;
7448 	unsigned int flags = 0;
7449 	const dns_section_t section = DNS_SECTION_ANSWER;
7450 
7451 	/*%
7452 	 * To the current response for 'qctx->client', add the answer RRset
7453 	 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with
7454 	 * owner name '*namep', to the answer section, unless they are
7455 	 * already there.  Also add any pertinent additional data.
7456 	 *
7457 	 * If 'qctx->dbuf' is not NULL, then 'qctx->fname' is the name
7458 	 * whose data is stored 'qctx->dbuf'.  In this case,
7459 	 * query_addrrset() guarantees that when it returns the name
7460 	 * will either have been kept or released.
7461 	 */
7462 	CTRACE(ISC_LOG_DEBUG(3), "query_dns64");
7463 
7464 	qctx->qtype = qctx->type = dns_rdatatype_aaaa;
7465 
7466 	name = qctx->fname;
7467 	mname = NULL;
7468 	mrdataset = NULL;
7469 	buffer = NULL;
7470 	dns64_rdata = NULL;
7471 	dns64_rdataset = NULL;
7472 	dns64_rdatalist = NULL;
7473 	result = dns_message_findname(
7474 		client->message, section, name, dns_rdatatype_aaaa,
7475 		qctx->rdataset->covers, &mname, &mrdataset);
7476 	if (result == ISC_R_SUCCESS) {
7477 		/*
7478 		 * We've already got an RRset of the given name and type.
7479 		 * There's nothing else to do;
7480 		 */
7481 		CTRACE(ISC_LOG_DEBUG(3), "query_dns64: dns_message_findname "
7482 					 "succeeded: done");
7483 		if (qctx->dbuf != NULL) {
7484 			ns_client_releasename(client, &qctx->fname);
7485 		}
7486 		return (ISC_R_SUCCESS);
7487 	} else if (result == DNS_R_NXDOMAIN) {
7488 		/*
7489 		 * The name doesn't exist.
7490 		 */
7491 		if (qctx->dbuf != NULL) {
7492 			ns_client_keepname(client, name, qctx->dbuf);
7493 		}
7494 		dns_message_addname(client->message, name, section);
7495 		qctx->fname = NULL;
7496 		mname = name;
7497 	} else {
7498 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
7499 		if (qctx->dbuf != NULL) {
7500 			ns_client_releasename(client, &qctx->fname);
7501 		}
7502 	}
7503 
7504 	if (qctx->rdataset->trust != dns_trust_secure) {
7505 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
7506 	}
7507 
7508 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
7509 
7510 	isc_buffer_allocate(client->mctx, &buffer,
7511 			    view->dns64cnt * 16 *
7512 				    dns_rdataset_count(qctx->rdataset));
7513 	result = dns_message_gettemprdataset(client->message, &dns64_rdataset);
7514 	if (result != ISC_R_SUCCESS) {
7515 		goto cleanup;
7516 	}
7517 	result = dns_message_gettemprdatalist(client->message,
7518 					      &dns64_rdatalist);
7519 	if (result != ISC_R_SUCCESS) {
7520 		goto cleanup;
7521 	}
7522 
7523 	dns_rdatalist_init(dns64_rdatalist);
7524 	dns64_rdatalist->rdclass = dns_rdataclass_in;
7525 	dns64_rdatalist->type = dns_rdatatype_aaaa;
7526 	if (client->query.dns64_ttl != UINT32_MAX) {
7527 		dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl,
7528 					       client->query.dns64_ttl);
7529 	} else {
7530 		dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl, 600);
7531 	}
7532 
7533 	if (RECURSIONOK(client)) {
7534 		flags |= DNS_DNS64_RECURSIVE;
7535 	}
7536 
7537 	/*
7538 	 * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC
7539 	 * as this provides a easy way to see if the answer was signed.
7540 	 */
7541 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
7542 	    dns_rdataset_isassociated(qctx->sigrdataset))
7543 	{
7544 		flags |= DNS_DNS64_DNSSEC;
7545 	}
7546 
7547 	for (result = dns_rdataset_first(qctx->rdataset);
7548 	     result == ISC_R_SUCCESS;
7549 	     result = dns_rdataset_next(qctx->rdataset))
7550 	{
7551 		for (dns64 = ISC_LIST_HEAD(client->view->dns64); dns64 != NULL;
7552 		     dns64 = dns_dns64_next(dns64))
7553 		{
7554 			dns_rdataset_current(qctx->rdataset, &rdata);
7555 			isc_buffer_availableregion(buffer, &r);
7556 			INSIST(r.length >= 16);
7557 			result = dns_dns64_aaaafroma(dns64, &netaddr,
7558 						     client->signer, env, flags,
7559 						     rdata.data, r.base);
7560 			if (result != ISC_R_SUCCESS) {
7561 				dns_rdata_reset(&rdata);
7562 				continue;
7563 			}
7564 			isc_buffer_add(buffer, 16);
7565 			isc_buffer_remainingregion(buffer, &r);
7566 			isc_buffer_forward(buffer, 16);
7567 			result = dns_message_gettemprdata(client->message,
7568 							  &dns64_rdata);
7569 			if (result != ISC_R_SUCCESS) {
7570 				goto cleanup;
7571 			}
7572 			dns_rdata_init(dns64_rdata);
7573 			dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
7574 					     dns_rdatatype_aaaa, &r);
7575 			ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata,
7576 					link);
7577 			dns64_rdata = NULL;
7578 			dns_rdata_reset(&rdata);
7579 		}
7580 	}
7581 	if (result != ISC_R_NOMORE) {
7582 		goto cleanup;
7583 	}
7584 
7585 	if (ISC_LIST_EMPTY(dns64_rdatalist->rdata)) {
7586 		goto cleanup;
7587 	}
7588 
7589 	result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
7590 	if (result != ISC_R_SUCCESS) {
7591 		goto cleanup;
7592 	}
7593 	dns_rdataset_setownercase(dns64_rdataset, mname);
7594 	client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
7595 	dns64_rdataset->trust = qctx->rdataset->trust;
7596 
7597 	query_addtoname(mname, dns64_rdataset);
7598 	query_setorder(qctx, mname, dns64_rdataset);
7599 
7600 	dns64_rdataset = NULL;
7601 	dns64_rdatalist = NULL;
7602 	dns_message_takebuffer(client->message, &buffer);
7603 	inc_stats(client, ns_statscounter_dns64);
7604 	result = ISC_R_SUCCESS;
7605 
7606 cleanup:
7607 	if (buffer != NULL) {
7608 		isc_buffer_free(&buffer);
7609 	}
7610 
7611 	if (dns64_rdata != NULL) {
7612 		dns_message_puttemprdata(client->message, &dns64_rdata);
7613 	}
7614 
7615 	if (dns64_rdataset != NULL) {
7616 		dns_message_puttemprdataset(client->message, &dns64_rdataset);
7617 	}
7618 
7619 	if (dns64_rdatalist != NULL) {
7620 		for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata);
7621 		     dns64_rdata != NULL;
7622 		     dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata))
7623 		{
7624 			ISC_LIST_UNLINK(dns64_rdatalist->rdata, dns64_rdata,
7625 					link);
7626 			dns_message_puttemprdata(client->message, &dns64_rdata);
7627 		}
7628 		dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
7629 	}
7630 
7631 	CTRACE(ISC_LOG_DEBUG(3), "query_dns64: done");
7632 	return (result);
7633 }
7634 
7635 static void
7636 query_filter64(query_ctx_t *qctx) {
7637 	ns_client_t *client = qctx->client;
7638 	dns_name_t *name, *mname;
7639 	dns_rdata_t *myrdata;
7640 	dns_rdata_t rdata = DNS_RDATA_INIT;
7641 	dns_rdatalist_t *myrdatalist;
7642 	dns_rdataset_t *myrdataset;
7643 	isc_buffer_t *buffer;
7644 	isc_region_t r;
7645 	isc_result_t result;
7646 	unsigned int i;
7647 	const dns_section_t section = DNS_SECTION_ANSWER;
7648 
7649 	CTRACE(ISC_LOG_DEBUG(3), "query_filter64");
7650 
7651 	INSIST(client->query.dns64_aaaaok != NULL);
7652 	INSIST(client->query.dns64_aaaaoklen ==
7653 	       dns_rdataset_count(qctx->rdataset));
7654 
7655 	name = qctx->fname;
7656 	mname = NULL;
7657 	buffer = NULL;
7658 	myrdata = NULL;
7659 	myrdataset = NULL;
7660 	myrdatalist = NULL;
7661 	result = dns_message_findname(
7662 		client->message, section, name, dns_rdatatype_aaaa,
7663 		qctx->rdataset->covers, &mname, &myrdataset);
7664 	if (result == ISC_R_SUCCESS) {
7665 		/*
7666 		 * We've already got an RRset of the given name and type.
7667 		 * There's nothing else to do;
7668 		 */
7669 		CTRACE(ISC_LOG_DEBUG(3), "query_filter64: dns_message_findname "
7670 					 "succeeded: done");
7671 		if (qctx->dbuf != NULL) {
7672 			ns_client_releasename(client, &qctx->fname);
7673 		}
7674 		return;
7675 	} else if (result == DNS_R_NXDOMAIN) {
7676 		mname = name;
7677 		qctx->fname = NULL;
7678 	} else {
7679 		RUNTIME_CHECK(result == DNS_R_NXRRSET);
7680 		if (qctx->dbuf != NULL) {
7681 			ns_client_releasename(client, &qctx->fname);
7682 		}
7683 		qctx->dbuf = NULL;
7684 	}
7685 
7686 	if (qctx->rdataset->trust != dns_trust_secure) {
7687 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
7688 	}
7689 
7690 	isc_buffer_allocate(client->mctx, &buffer,
7691 			    16 * dns_rdataset_count(qctx->rdataset));
7692 	result = dns_message_gettemprdataset(client->message, &myrdataset);
7693 	if (result != ISC_R_SUCCESS) {
7694 		goto cleanup;
7695 	}
7696 	result = dns_message_gettemprdatalist(client->message, &myrdatalist);
7697 	if (result != ISC_R_SUCCESS) {
7698 		goto cleanup;
7699 	}
7700 
7701 	dns_rdatalist_init(myrdatalist);
7702 	myrdatalist->rdclass = dns_rdataclass_in;
7703 	myrdatalist->type = dns_rdatatype_aaaa;
7704 	myrdatalist->ttl = qctx->rdataset->ttl;
7705 
7706 	i = 0;
7707 	for (result = dns_rdataset_first(qctx->rdataset);
7708 	     result == ISC_R_SUCCESS;
7709 	     result = dns_rdataset_next(qctx->rdataset))
7710 	{
7711 		if (!client->query.dns64_aaaaok[i++]) {
7712 			continue;
7713 		}
7714 		dns_rdataset_current(qctx->rdataset, &rdata);
7715 		INSIST(rdata.length == 16);
7716 		isc_buffer_putmem(buffer, rdata.data, rdata.length);
7717 		isc_buffer_remainingregion(buffer, &r);
7718 		isc_buffer_forward(buffer, rdata.length);
7719 		result = dns_message_gettemprdata(client->message, &myrdata);
7720 		if (result != ISC_R_SUCCESS) {
7721 			goto cleanup;
7722 		}
7723 		dns_rdata_init(myrdata);
7724 		dns_rdata_fromregion(myrdata, dns_rdataclass_in,
7725 				     dns_rdatatype_aaaa, &r);
7726 		ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link);
7727 		myrdata = NULL;
7728 		dns_rdata_reset(&rdata);
7729 	}
7730 	if (result != ISC_R_NOMORE) {
7731 		goto cleanup;
7732 	}
7733 
7734 	result = dns_rdatalist_tordataset(myrdatalist, myrdataset);
7735 	if (result != ISC_R_SUCCESS) {
7736 		goto cleanup;
7737 	}
7738 	dns_rdataset_setownercase(myrdataset, name);
7739 	client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
7740 	if (mname == name) {
7741 		if (qctx->dbuf != NULL) {
7742 			ns_client_keepname(client, name, qctx->dbuf);
7743 		}
7744 		dns_message_addname(client->message, name, section);
7745 		qctx->dbuf = NULL;
7746 	}
7747 	myrdataset->trust = qctx->rdataset->trust;
7748 
7749 	query_addtoname(mname, myrdataset);
7750 	query_setorder(qctx, mname, myrdataset);
7751 
7752 	myrdataset = NULL;
7753 	myrdatalist = NULL;
7754 	dns_message_takebuffer(client->message, &buffer);
7755 
7756 cleanup:
7757 	if (buffer != NULL) {
7758 		isc_buffer_free(&buffer);
7759 	}
7760 
7761 	if (myrdata != NULL) {
7762 		dns_message_puttemprdata(client->message, &myrdata);
7763 	}
7764 
7765 	if (myrdataset != NULL) {
7766 		dns_message_puttemprdataset(client->message, &myrdataset);
7767 	}
7768 
7769 	if (myrdatalist != NULL) {
7770 		for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata);
7771 		     myrdata != NULL;
7772 		     myrdata = ISC_LIST_HEAD(myrdatalist->rdata))
7773 		{
7774 			ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link);
7775 			dns_message_puttemprdata(client->message, &myrdata);
7776 		}
7777 		dns_message_puttemprdatalist(client->message, &myrdatalist);
7778 	}
7779 	if (qctx->dbuf != NULL) {
7780 		ns_client_releasename(client, &name);
7781 	}
7782 
7783 	CTRACE(ISC_LOG_DEBUG(3), "query_filter64: done");
7784 }
7785 
7786 /*%
7787  * Handle the case of a name not being found in a database lookup.
7788  * Called from query_gotanswer(). Passes off processing to
7789  * query_delegation() for a root referral if appropriate.
7790  */
7791 static isc_result_t
7792 query_notfound(query_ctx_t *qctx) {
7793 	isc_result_t result;
7794 
7795 	CCTRACE(ISC_LOG_DEBUG(3), "query_notfound");
7796 
7797 	CALL_HOOK(NS_QUERY_NOTFOUND_BEGIN, qctx);
7798 
7799 	INSIST(!qctx->is_zone);
7800 
7801 	if (qctx->db != NULL) {
7802 		dns_db_detach(&qctx->db);
7803 	}
7804 
7805 	/*
7806 	 * If the cache doesn't even have the root NS,
7807 	 * try to get that from the hints DB.
7808 	 */
7809 	if (qctx->view->hints != NULL) {
7810 		dns_clientinfomethods_t cm;
7811 		dns_clientinfo_t ci;
7812 
7813 		dns_clientinfomethods_init(&cm, ns_client_sourceip);
7814 		dns_clientinfo_init(&ci, qctx->client, NULL);
7815 
7816 		dns_db_attach(qctx->view->hints, &qctx->db);
7817 		result = dns_db_findext(qctx->db, dns_rootname, NULL,
7818 					dns_rdatatype_ns, 0, qctx->client->now,
7819 					&qctx->node, qctx->fname, &cm, &ci,
7820 					qctx->rdataset, qctx->sigrdataset);
7821 	} else {
7822 		/* We have no hints. */
7823 		result = ISC_R_FAILURE;
7824 	}
7825 	if (result != ISC_R_SUCCESS) {
7826 		/*
7827 		 * Nonsensical root hints may require cleanup.
7828 		 */
7829 		qctx_clean(qctx);
7830 
7831 		/*
7832 		 * We don't have any root server hints, but
7833 		 * we may have working forwarders, so try to
7834 		 * recurse anyway.
7835 		 */
7836 		if (RECURSIONOK(qctx->client)) {
7837 			INSIST(!REDIRECT(qctx->client));
7838 			result = ns_query_recurse(qctx->client, qctx->qtype,
7839 						  qctx->client->query.qname,
7840 						  NULL, NULL, qctx->resuming);
7841 			if (result == ISC_R_SUCCESS) {
7842 				CALL_HOOK(NS_QUERY_NOTFOUND_RECURSE, qctx);
7843 				qctx->client->query.attributes |=
7844 					NS_QUERYATTR_RECURSING;
7845 
7846 				if (qctx->dns64) {
7847 					qctx->client->query.attributes |=
7848 						NS_QUERYATTR_DNS64;
7849 				}
7850 				if (qctx->dns64_exclude) {
7851 					qctx->client->query.attributes |=
7852 						NS_QUERYATTR_DNS64EXCLUDE;
7853 				}
7854 			} else {
7855 				QUERY_ERROR(qctx, result);
7856 			}
7857 			return (ns_query_done(qctx));
7858 		} else {
7859 			/* Unable to give root server referral. */
7860 			CCTRACE(ISC_LOG_ERROR, "unable to give root server "
7861 					       "referral");
7862 			QUERY_ERROR(qctx, result);
7863 			return (ns_query_done(qctx));
7864 		}
7865 	}
7866 
7867 	return (query_delegation(qctx));
7868 
7869 cleanup:
7870 	return (result);
7871 }
7872 
7873 /*%
7874  * We have a delegation but recursion is not allowed, so return the delegation
7875  * to the client.
7876  */
7877 static isc_result_t
7878 query_prepare_delegation_response(query_ctx_t *qctx) {
7879 	isc_result_t result;
7880 	dns_rdataset_t **sigrdatasetp = NULL;
7881 	bool detach = false;
7882 
7883 	CALL_HOOK(NS_QUERY_PREP_DELEGATION_BEGIN, qctx);
7884 
7885 	/*
7886 	 * qctx->fname could be released in query_addrrset(), so save a copy of
7887 	 * it here in case we need it.
7888 	 */
7889 	dns_fixedname_init(&qctx->dsname);
7890 	dns_name_copynf(qctx->fname, dns_fixedname_name(&qctx->dsname));
7891 
7892 	/*
7893 	 * This is the best answer.
7894 	 */
7895 	qctx->client->query.isreferral = true;
7896 
7897 	if (!dns_db_iscache(qctx->db) && qctx->client->query.gluedb == NULL) {
7898 		dns_db_attach(qctx->db, &qctx->client->query.gluedb);
7899 		detach = true;
7900 	}
7901 
7902 	/*
7903 	 * We must ensure NOADDITIONAL is off, because the generation of
7904 	 * additional data is required in delegations.
7905 	 */
7906 	qctx->client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL;
7907 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
7908 		sigrdatasetp = &qctx->sigrdataset;
7909 	}
7910 	query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp,
7911 		       qctx->dbuf, DNS_SECTION_AUTHORITY);
7912 	if (detach) {
7913 		dns_db_detach(&qctx->client->query.gluedb);
7914 	}
7915 
7916 	/*
7917 	 * Add a DS if needed.
7918 	 */
7919 	query_addds(qctx);
7920 
7921 	return (ns_query_done(qctx));
7922 
7923 cleanup:
7924 	return (result);
7925 }
7926 
7927 /*%
7928  * Handle a delegation response from an authoritative lookup. This
7929  * may trigger additional lookups, e.g. from the cache database to
7930  * see if we have a better answer; if that is not allowed, return the
7931  * delegation to the client and call ns_query_done().
7932  */
7933 static isc_result_t
7934 query_zone_delegation(query_ctx_t *qctx) {
7935 	isc_result_t result;
7936 
7937 	CALL_HOOK(NS_QUERY_ZONE_DELEGATION_BEGIN, qctx);
7938 
7939 	/*
7940 	 * If the query type is DS, look to see if we are
7941 	 * authoritative for the child zone
7942 	 */
7943 	if (!RECURSIONOK(qctx->client) &&
7944 	    (qctx->options & DNS_GETDB_NOEXACT) != 0 &&
7945 	    qctx->qtype == dns_rdatatype_ds)
7946 	{
7947 		dns_db_t *tdb = NULL;
7948 		dns_zone_t *tzone = NULL;
7949 		dns_dbversion_t *tversion = NULL;
7950 		result = query_getzonedb(
7951 			qctx->client, qctx->client->query.qname, qctx->qtype,
7952 			DNS_GETDB_PARTIAL, &tzone, &tdb, &tversion);
7953 		if (result != ISC_R_SUCCESS) {
7954 			if (tdb != NULL) {
7955 				dns_db_detach(&tdb);
7956 			}
7957 			if (tzone != NULL) {
7958 				dns_zone_detach(&tzone);
7959 			}
7960 		} else {
7961 			qctx->options &= ~DNS_GETDB_NOEXACT;
7962 			ns_client_putrdataset(qctx->client, &qctx->rdataset);
7963 			if (qctx->sigrdataset != NULL) {
7964 				ns_client_putrdataset(qctx->client,
7965 						      &qctx->sigrdataset);
7966 			}
7967 			if (qctx->fname != NULL) {
7968 				ns_client_releasename(qctx->client,
7969 						      &qctx->fname);
7970 			}
7971 			if (qctx->node != NULL) {
7972 				dns_db_detachnode(qctx->db, &qctx->node);
7973 			}
7974 			if (qctx->db != NULL) {
7975 				dns_db_detach(&qctx->db);
7976 			}
7977 			if (qctx->zone != NULL) {
7978 				dns_zone_detach(&qctx->zone);
7979 			}
7980 			qctx->version = NULL;
7981 			RESTORE(qctx->version, tversion);
7982 			RESTORE(qctx->db, tdb);
7983 			RESTORE(qctx->zone, tzone);
7984 			qctx->authoritative = true;
7985 
7986 			return (query_lookup(qctx));
7987 		}
7988 	}
7989 
7990 	if (USECACHE(qctx->client) &&
7991 	    (RECURSIONOK(qctx->client) ||
7992 	     (qctx->zone != NULL &&
7993 	      dns_zone_gettype(qctx->zone) == dns_zone_mirror)))
7994 	{
7995 		/*
7996 		 * We might have a better answer or delegation in the
7997 		 * cache.  We'll remember the current values of fname,
7998 		 * rdataset, and sigrdataset.  We'll then go looking for
7999 		 * QNAME in the cache.  If we find something better, we'll
8000 		 * use it instead. If not, then query_lookup() calls
8001 		 * query_notfound() which calls query_delegation(), and
8002 		 * we'll restore these values there.
8003 		 */
8004 		ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
8005 		SAVE(qctx->zdb, qctx->db);
8006 		SAVE(qctx->znode, qctx->node);
8007 		SAVE(qctx->zfname, qctx->fname);
8008 		SAVE(qctx->zversion, qctx->version);
8009 		SAVE(qctx->zrdataset, qctx->rdataset);
8010 		SAVE(qctx->zsigrdataset, qctx->sigrdataset);
8011 		dns_db_attach(qctx->view->cachedb, &qctx->db);
8012 		qctx->is_zone = false;
8013 
8014 		return (query_lookup(qctx));
8015 	}
8016 
8017 	return (query_prepare_delegation_response(qctx));
8018 
8019 cleanup:
8020 	return (result);
8021 }
8022 
8023 /*%
8024  * Handle delegation responses, including root referrals.
8025  *
8026  * If the delegation was returned from authoritative data,
8027  * call query_zone_delgation().  Otherwise, we can start
8028  * recursion if allowed; or else return the delegation to the
8029  * client and call ns_query_done().
8030  */
8031 static isc_result_t
8032 query_delegation(query_ctx_t *qctx) {
8033 	isc_result_t result;
8034 
8035 	CCTRACE(ISC_LOG_DEBUG(3), "query_delegation");
8036 
8037 	CALL_HOOK(NS_QUERY_DELEGATION_BEGIN, qctx);
8038 
8039 	qctx->authoritative = false;
8040 
8041 	if (qctx->is_zone) {
8042 		return (query_zone_delegation(qctx));
8043 	}
8044 
8045 	if (qctx->zfname != NULL &&
8046 	    (!dns_name_issubdomain(qctx->fname, qctx->zfname) ||
8047 	     (qctx->is_staticstub_zone &&
8048 	      dns_name_equal(qctx->fname, qctx->zfname))))
8049 	{
8050 		/*
8051 		 * In the following cases use "authoritative"
8052 		 * data instead of the cache delegation:
8053 		 * 1. We've already got a delegation from
8054 		 *    authoritative data, and it is better
8055 		 *    than what we found in the cache.
8056 		 *    (See the comment above.)
8057 		 * 2. The query name matches the origin name
8058 		 *    of a static-stub zone.  This needs to be
8059 		 *    considered for the case where the NS of
8060 		 *    the static-stub zone and the cached NS
8061 		 *    are different.  We still need to contact
8062 		 *    the nameservers configured in the
8063 		 *    static-stub zone.
8064 		 */
8065 		ns_client_releasename(qctx->client, &qctx->fname);
8066 
8067 		/*
8068 		 * We've already done ns_client_keepname() on
8069 		 * qctx->zfname, so we must set dbuf to NULL to
8070 		 * prevent query_addrrset() from trying to
8071 		 * call ns_client_keepname() again.
8072 		 */
8073 		qctx->dbuf = NULL;
8074 		ns_client_putrdataset(qctx->client, &qctx->rdataset);
8075 		if (qctx->sigrdataset != NULL) {
8076 			ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
8077 		}
8078 		qctx->version = NULL;
8079 
8080 		dns_db_detachnode(qctx->db, &qctx->node);
8081 		dns_db_detach(&qctx->db);
8082 		RESTORE(qctx->db, qctx->zdb);
8083 		RESTORE(qctx->node, qctx->znode);
8084 		RESTORE(qctx->fname, qctx->zfname);
8085 		RESTORE(qctx->version, qctx->zversion);
8086 		RESTORE(qctx->rdataset, qctx->zrdataset);
8087 		RESTORE(qctx->sigrdataset, qctx->zsigrdataset);
8088 	}
8089 
8090 	result = query_delegation_recurse(qctx);
8091 	if (result != ISC_R_COMPLETE) {
8092 		return (result);
8093 	}
8094 
8095 	return (query_prepare_delegation_response(qctx));
8096 
8097 cleanup:
8098 	return (result);
8099 }
8100 
8101 /*%
8102  * Handle recursive queries that are triggered as part of the
8103  * delegation process.
8104  */
8105 static isc_result_t
8106 query_delegation_recurse(query_ctx_t *qctx) {
8107 	isc_result_t result;
8108 	dns_name_t *qname = qctx->client->query.qname;
8109 
8110 	CCTRACE(ISC_LOG_DEBUG(3), "query_delegation_recurse");
8111 
8112 	if (!RECURSIONOK(qctx->client)) {
8113 		return (ISC_R_COMPLETE);
8114 	}
8115 
8116 	CALL_HOOK(NS_QUERY_DELEGATION_RECURSE_BEGIN, qctx);
8117 
8118 	/*
8119 	 * We have a delegation and recursion is allowed,
8120 	 * so we call ns_query_recurse() to follow it.
8121 	 * This phase of the query processing is done;
8122 	 * we'll resume via fetch_callback() and
8123 	 * query_resume() when the recursion is complete.
8124 	 */
8125 
8126 	INSIST(!REDIRECT(qctx->client));
8127 
8128 	if (dns_rdatatype_atparent(qctx->type)) {
8129 		/*
8130 		 * Parent is authoritative for this RDATA type (i.e. DS).
8131 		 */
8132 		result = ns_query_recurse(qctx->client, qctx->qtype, qname,
8133 					  NULL, NULL, qctx->resuming);
8134 	} else if (qctx->dns64) {
8135 		/*
8136 		 * Look up an A record so we can synthesize DNS64.
8137 		 */
8138 		result = ns_query_recurse(qctx->client, dns_rdatatype_a, qname,
8139 					  NULL, NULL, qctx->resuming);
8140 	} else {
8141 		/*
8142 		 * Any other recursion.
8143 		 */
8144 		result = ns_query_recurse(qctx->client, qctx->qtype, qname,
8145 					  qctx->fname, qctx->rdataset,
8146 					  qctx->resuming);
8147 	}
8148 
8149 	if (result == ISC_R_SUCCESS) {
8150 		qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
8151 		if (qctx->dns64) {
8152 			qctx->client->query.attributes |= NS_QUERYATTR_DNS64;
8153 		}
8154 		if (qctx->dns64_exclude) {
8155 			qctx->client->query.attributes |=
8156 				NS_QUERYATTR_DNS64EXCLUDE;
8157 		}
8158 	} else {
8159 		QUERY_ERROR(qctx, result);
8160 	}
8161 
8162 	return (ns_query_done(qctx));
8163 
8164 cleanup:
8165 	return (result);
8166 }
8167 
8168 /*%
8169  * Add a DS record if needed.
8170  */
8171 static void
8172 query_addds(query_ctx_t *qctx) {
8173 	ns_client_t *client = qctx->client;
8174 	dns_fixedname_t fixed;
8175 	dns_name_t *fname = NULL;
8176 	dns_name_t *rname = NULL;
8177 	dns_name_t *name;
8178 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
8179 	isc_buffer_t *dbuf, b;
8180 	isc_result_t result;
8181 	unsigned int count;
8182 
8183 	CTRACE(ISC_LOG_DEBUG(3), "query_addds");
8184 
8185 	/*
8186 	 * DS not needed.
8187 	 */
8188 	if (!WANTDNSSEC(client)) {
8189 		return;
8190 	}
8191 
8192 	/*
8193 	 * We'll need some resources...
8194 	 */
8195 	rdataset = ns_client_newrdataset(client);
8196 	sigrdataset = ns_client_newrdataset(client);
8197 	if (rdataset == NULL || sigrdataset == NULL) {
8198 		goto cleanup;
8199 	}
8200 
8201 	/*
8202 	 * Look for the DS record, which may or may not be present.
8203 	 */
8204 	result = dns_db_findrdataset(qctx->db, qctx->node, qctx->version,
8205 				     dns_rdatatype_ds, 0, client->now, rdataset,
8206 				     sigrdataset);
8207 	/*
8208 	 * If we didn't find it, look for an NSEC.
8209 	 */
8210 	if (result == ISC_R_NOTFOUND) {
8211 		result = dns_db_findrdataset(
8212 			qctx->db, qctx->node, qctx->version, dns_rdatatype_nsec,
8213 			0, client->now, rdataset, sigrdataset);
8214 	}
8215 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
8216 		goto addnsec3;
8217 	}
8218 	if (!dns_rdataset_isassociated(rdataset) ||
8219 	    !dns_rdataset_isassociated(sigrdataset))
8220 	{
8221 		goto addnsec3;
8222 	}
8223 
8224 	/*
8225 	 * We've already added the NS record, so if the name's not there,
8226 	 * we have other problems.  Use this name rather than calling
8227 	 * query_addrrset().
8228 	 */
8229 	result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY);
8230 	if (result != ISC_R_SUCCESS) {
8231 		goto cleanup;
8232 	}
8233 
8234 	rname = NULL;
8235 	dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, &rname);
8236 	result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL);
8237 	if (result != ISC_R_SUCCESS) {
8238 		goto cleanup;
8239 	}
8240 
8241 	ISC_LIST_APPEND(rname->list, rdataset, link);
8242 	ISC_LIST_APPEND(rname->list, sigrdataset, link);
8243 	rdataset = NULL;
8244 	sigrdataset = NULL;
8245 	return;
8246 
8247 addnsec3:
8248 	if (!dns_db_iszone(qctx->db)) {
8249 		goto cleanup;
8250 	}
8251 	/*
8252 	 * Add the NSEC3 which proves the DS does not exist.
8253 	 */
8254 	dbuf = ns_client_getnamebuf(client);
8255 	if (dbuf == NULL) {
8256 		goto cleanup;
8257 	}
8258 	fname = ns_client_newname(client, dbuf, &b);
8259 	dns_fixedname_init(&fixed);
8260 	if (dns_rdataset_isassociated(rdataset)) {
8261 		dns_rdataset_disassociate(rdataset);
8262 	}
8263 	if (dns_rdataset_isassociated(sigrdataset)) {
8264 		dns_rdataset_disassociate(sigrdataset);
8265 	}
8266 	name = dns_fixedname_name(&qctx->dsname);
8267 	query_findclosestnsec3(name, qctx->db, qctx->version, client, rdataset,
8268 			       sigrdataset, fname, true,
8269 			       dns_fixedname_name(&fixed));
8270 	if (!dns_rdataset_isassociated(rdataset)) {
8271 		goto cleanup;
8272 	}
8273 	query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
8274 		       DNS_SECTION_AUTHORITY);
8275 	/*
8276 	 * Did we find the closest provable encloser instead?
8277 	 * If so add the nearest to the closest provable encloser.
8278 	 */
8279 	if (!dns_name_equal(name, dns_fixedname_name(&fixed))) {
8280 		count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1;
8281 		dns_name_getlabelsequence(name,
8282 					  dns_name_countlabels(name) - count,
8283 					  count, dns_fixedname_name(&fixed));
8284 		fixfname(client, &fname, &dbuf, &b);
8285 		fixrdataset(client, &rdataset);
8286 		fixrdataset(client, &sigrdataset);
8287 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL) {
8288 			goto cleanup;
8289 		}
8290 		query_findclosestnsec3(dns_fixedname_name(&fixed), qctx->db,
8291 				       qctx->version, client, rdataset,
8292 				       sigrdataset, fname, false, NULL);
8293 		if (!dns_rdataset_isassociated(rdataset)) {
8294 			goto cleanup;
8295 		}
8296 		query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
8297 			       DNS_SECTION_AUTHORITY);
8298 	}
8299 
8300 cleanup:
8301 	if (rdataset != NULL) {
8302 		ns_client_putrdataset(client, &rdataset);
8303 	}
8304 	if (sigrdataset != NULL) {
8305 		ns_client_putrdataset(client, &sigrdataset);
8306 	}
8307 	if (fname != NULL) {
8308 		ns_client_releasename(client, &fname);
8309 	}
8310 }
8311 
8312 /*%
8313  * Handle authoritative NOERROR/NODATA responses.
8314  */
8315 static isc_result_t
8316 query_nodata(query_ctx_t *qctx, isc_result_t res) {
8317 	isc_result_t result = res;
8318 
8319 	CCTRACE(ISC_LOG_DEBUG(3), "query_nodata");
8320 
8321 	CALL_HOOK(NS_QUERY_NODATA_BEGIN, qctx);
8322 
8323 #ifdef dns64_bis_return_excluded_addresses
8324 	if (qctx->dns64)
8325 #else  /* ifdef dns64_bis_return_excluded_addresses */
8326 	if (qctx->dns64 && !qctx->dns64_exclude)
8327 #endif /* ifdef dns64_bis_return_excluded_addresses */
8328 	{
8329 		isc_buffer_t b;
8330 		/*
8331 		 * Restore the answers from the previous AAAA lookup.
8332 		 */
8333 		if (qctx->rdataset != NULL) {
8334 			ns_client_putrdataset(qctx->client, &qctx->rdataset);
8335 		}
8336 		if (qctx->sigrdataset != NULL) {
8337 			ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
8338 		}
8339 		RESTORE(qctx->rdataset, qctx->client->query.dns64_aaaa);
8340 		RESTORE(qctx->sigrdataset, qctx->client->query.dns64_sigaaaa);
8341 		if (qctx->fname == NULL) {
8342 			qctx->dbuf = ns_client_getnamebuf(qctx->client);
8343 			if (qctx->dbuf == NULL) {
8344 				CCTRACE(ISC_LOG_ERROR, "query_nodata: "
8345 						       "ns_client_getnamebuf "
8346 						       "failed (3)");
8347 				QUERY_ERROR(qctx, ISC_R_NOMEMORY);
8348 				return (ns_query_done(qctx));
8349 			}
8350 			qctx->fname = ns_client_newname(qctx->client,
8351 							qctx->dbuf, &b);
8352 			if (qctx->fname == NULL) {
8353 				CCTRACE(ISC_LOG_ERROR, "query_nodata: "
8354 						       "ns_client_newname "
8355 						       "failed (3)");
8356 				QUERY_ERROR(qctx, ISC_R_NOMEMORY);
8357 				return (ns_query_done(qctx));
8358 			}
8359 		}
8360 		dns_name_copynf(qctx->client->query.qname, qctx->fname);
8361 		qctx->dns64 = false;
8362 #ifdef dns64_bis_return_excluded_addresses
8363 		/*
8364 		 * Resume the diverted processing of the AAAA response?
8365 		 */
8366 		if (qctx->dns64_exclude) {
8367 			return (query_prepresponse(qctx));
8368 		}
8369 #endif /* ifdef dns64_bis_return_excluded_addresses */
8370 	} else if ((result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) &&
8371 		   !ISC_LIST_EMPTY(qctx->view->dns64) && !qctx->nxrewrite &&
8372 		   qctx->client->message->rdclass == dns_rdataclass_in &&
8373 		   qctx->qtype == dns_rdatatype_aaaa)
8374 	{
8375 		/*
8376 		 * Look to see if there are A records for this name.
8377 		 */
8378 		switch (result) {
8379 		case DNS_R_NCACHENXRRSET:
8380 			/*
8381 			 * This is from the negative cache; if the ttl is
8382 			 * zero, we need to work out whether we have just
8383 			 * decremented to zero or there was no negative
8384 			 * cache ttl in the answer.
8385 			 */
8386 			if (qctx->rdataset->ttl != 0) {
8387 				qctx->client->query.dns64_ttl =
8388 					qctx->rdataset->ttl;
8389 				break;
8390 			}
8391 			if (dns_rdataset_first(qctx->rdataset) == ISC_R_SUCCESS)
8392 			{
8393 				qctx->client->query.dns64_ttl = 0;
8394 			}
8395 			break;
8396 		case DNS_R_NXRRSET:
8397 			qctx->client->query.dns64_ttl =
8398 				dns64_ttl(qctx->db, qctx->version);
8399 			break;
8400 		default:
8401 			INSIST(0);
8402 			ISC_UNREACHABLE();
8403 		}
8404 
8405 		SAVE(qctx->client->query.dns64_aaaa, qctx->rdataset);
8406 		SAVE(qctx->client->query.dns64_sigaaaa, qctx->sigrdataset);
8407 		ns_client_releasename(qctx->client, &qctx->fname);
8408 		dns_db_detachnode(qctx->db, &qctx->node);
8409 		qctx->type = qctx->qtype = dns_rdatatype_a;
8410 		qctx->dns64 = true;
8411 		return (query_lookup(qctx));
8412 	}
8413 
8414 	if (qctx->is_zone) {
8415 		return (query_sign_nodata(qctx));
8416 	} else {
8417 		/*
8418 		 * We don't call query_addrrset() because we don't need any
8419 		 * of its extra features (and things would probably break!).
8420 		 */
8421 		if (dns_rdataset_isassociated(qctx->rdataset)) {
8422 			ns_client_keepname(qctx->client, qctx->fname,
8423 					   qctx->dbuf);
8424 			dns_message_addname(qctx->client->message, qctx->fname,
8425 					    DNS_SECTION_AUTHORITY);
8426 			ISC_LIST_APPEND(qctx->fname->list, qctx->rdataset,
8427 					link);
8428 			qctx->fname = NULL;
8429 			qctx->rdataset = NULL;
8430 		}
8431 	}
8432 
8433 	return (ns_query_done(qctx));
8434 
8435 cleanup:
8436 	return (result);
8437 }
8438 
8439 /*%
8440  * Add RRSIGs for NOERROR/NODATA responses when answering authoritatively.
8441  */
8442 isc_result_t
8443 query_sign_nodata(query_ctx_t *qctx) {
8444 	isc_result_t result;
8445 
8446 	CCTRACE(ISC_LOG_DEBUG(3), "query_sign_nodata");
8447 
8448 	/*
8449 	 * Look for a NSEC3 record if we don't have a NSEC record.
8450 	 */
8451 	if (qctx->redirected) {
8452 		return (ns_query_done(qctx));
8453 	}
8454 	if (!dns_rdataset_isassociated(qctx->rdataset) &&
8455 	    WANTDNSSEC(qctx->client)) {
8456 		if ((qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
8457 			dns_name_t *found;
8458 			dns_name_t *qname;
8459 			dns_fixedname_t fixed;
8460 			isc_buffer_t b;
8461 
8462 			found = dns_fixedname_initname(&fixed);
8463 			qname = qctx->client->query.qname;
8464 
8465 			query_findclosestnsec3(qname, qctx->db, qctx->version,
8466 					       qctx->client, qctx->rdataset,
8467 					       qctx->sigrdataset, qctx->fname,
8468 					       true, found);
8469 			/*
8470 			 * Did we find the closest provable encloser
8471 			 * instead? If so add the nearest to the
8472 			 * closest provable encloser.
8473 			 */
8474 			if (dns_rdataset_isassociated(qctx->rdataset) &&
8475 			    !dns_name_equal(qname, found) &&
8476 			    (((qctx->client->sctx->options &
8477 			       NS_SERVER_NONEAREST) == 0) ||
8478 			     qctx->qtype == dns_rdatatype_ds))
8479 			{
8480 				unsigned int count;
8481 				unsigned int skip;
8482 
8483 				/*
8484 				 * Add the closest provable encloser.
8485 				 */
8486 				query_addrrset(qctx, &qctx->fname,
8487 					       &qctx->rdataset,
8488 					       &qctx->sigrdataset, qctx->dbuf,
8489 					       DNS_SECTION_AUTHORITY);
8490 
8491 				count = dns_name_countlabels(found) + 1;
8492 				skip = dns_name_countlabels(qname) - count;
8493 				dns_name_getlabelsequence(qname, skip, count,
8494 							  found);
8495 
8496 				fixfname(qctx->client, &qctx->fname,
8497 					 &qctx->dbuf, &b);
8498 				fixrdataset(qctx->client, &qctx->rdataset);
8499 				fixrdataset(qctx->client, &qctx->sigrdataset);
8500 				if (qctx->fname == NULL ||
8501 				    qctx->rdataset == NULL ||
8502 				    qctx->sigrdataset == NULL) {
8503 					CCTRACE(ISC_LOG_ERROR, "query_sign_"
8504 							       "nodata: "
8505 							       "failure "
8506 							       "getting "
8507 							       "closest "
8508 							       "encloser");
8509 					QUERY_ERROR(qctx, ISC_R_NOMEMORY);
8510 					return (ns_query_done(qctx));
8511 				}
8512 				/*
8513 				 * 'nearest' doesn't exist so
8514 				 * 'exist' is set to false.
8515 				 */
8516 				query_findclosestnsec3(
8517 					found, qctx->db, qctx->version,
8518 					qctx->client, qctx->rdataset,
8519 					qctx->sigrdataset, qctx->fname, false,
8520 					NULL);
8521 			}
8522 		} else {
8523 			ns_client_releasename(qctx->client, &qctx->fname);
8524 			query_addwildcardproof(qctx, false, true);
8525 		}
8526 	}
8527 	if (dns_rdataset_isassociated(qctx->rdataset)) {
8528 		/*
8529 		 * If we've got a NSEC record, we need to save the
8530 		 * name now because we're going call query_addsoa()
8531 		 * below, and it needs to use the name buffer.
8532 		 */
8533 		ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
8534 	} else if (qctx->fname != NULL) {
8535 		/*
8536 		 * We're not going to use fname, and need to release
8537 		 * our hold on the name buffer so query_addsoa()
8538 		 * may use it.
8539 		 */
8540 		ns_client_releasename(qctx->client, &qctx->fname);
8541 	}
8542 
8543 	/*
8544 	 * The RPZ SOA has already been added to the additional section
8545 	 * if this was an RPZ rewrite, but if it wasn't, add it now.
8546 	 */
8547 	if (!qctx->nxrewrite) {
8548 		result = query_addsoa(qctx, UINT32_MAX, DNS_SECTION_AUTHORITY);
8549 		if (result != ISC_R_SUCCESS) {
8550 			QUERY_ERROR(qctx, result);
8551 			return (ns_query_done(qctx));
8552 		}
8553 	}
8554 
8555 	/*
8556 	 * Add NSEC record if we found one.
8557 	 */
8558 	if (WANTDNSSEC(qctx->client) &&
8559 	    dns_rdataset_isassociated(qctx->rdataset)) {
8560 		query_addnxrrsetnsec(qctx);
8561 	}
8562 
8563 	return (ns_query_done(qctx));
8564 }
8565 
8566 static void
8567 query_addnxrrsetnsec(query_ctx_t *qctx) {
8568 	ns_client_t *client = qctx->client;
8569 	dns_rdata_t sigrdata;
8570 	dns_rdata_rrsig_t sig;
8571 	unsigned int labels;
8572 	isc_buffer_t *dbuf, b;
8573 	dns_name_t *fname;
8574 	isc_result_t result;
8575 
8576 	INSIST(qctx->fname != NULL);
8577 
8578 	if ((qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
8579 		query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
8580 			       &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY);
8581 		return;
8582 	}
8583 
8584 	if (qctx->sigrdataset == NULL ||
8585 	    !dns_rdataset_isassociated(qctx->sigrdataset)) {
8586 		return;
8587 	}
8588 
8589 	if (dns_rdataset_first(qctx->sigrdataset) != ISC_R_SUCCESS) {
8590 		return;
8591 	}
8592 
8593 	dns_rdata_init(&sigrdata);
8594 	dns_rdataset_current(qctx->sigrdataset, &sigrdata);
8595 	result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
8596 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
8597 
8598 	labels = dns_name_countlabels(qctx->fname);
8599 	if ((unsigned int)sig.labels + 1 >= labels) {
8600 		return;
8601 	}
8602 
8603 	query_addwildcardproof(qctx, true, false);
8604 
8605 	/*
8606 	 * We'll need some resources...
8607 	 */
8608 	dbuf = ns_client_getnamebuf(client);
8609 	if (dbuf == NULL) {
8610 		return;
8611 	}
8612 
8613 	fname = ns_client_newname(client, dbuf, &b);
8614 	if (fname == NULL) {
8615 		return;
8616 	}
8617 
8618 	dns_name_split(qctx->fname, sig.labels + 1, NULL, fname);
8619 	/* This will succeed, since we've stripped labels. */
8620 	RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname,
8621 					   NULL) == ISC_R_SUCCESS);
8622 	query_addrrset(qctx, &fname, &qctx->rdataset, &qctx->sigrdataset, dbuf,
8623 		       DNS_SECTION_AUTHORITY);
8624 }
8625 
8626 /*%
8627  * Handle NXDOMAIN and empty wildcard responses.
8628  */
8629 static isc_result_t
8630 query_nxdomain(query_ctx_t *qctx, bool empty_wild) {
8631 	dns_section_t section;
8632 	uint32_t ttl;
8633 	isc_result_t result;
8634 
8635 	CCTRACE(ISC_LOG_DEBUG(3), "query_nxdomain");
8636 
8637 	CALL_HOOK(NS_QUERY_NXDOMAIN_BEGIN, qctx);
8638 
8639 	INSIST(qctx->is_zone || REDIRECT(qctx->client));
8640 
8641 	if (!empty_wild) {
8642 		result = query_redirect(qctx);
8643 		if (result != ISC_R_COMPLETE) {
8644 			return (result);
8645 		}
8646 	}
8647 
8648 	if (dns_rdataset_isassociated(qctx->rdataset)) {
8649 		/*
8650 		 * If we've got a NSEC record, we need to save the
8651 		 * name now because we're going call query_addsoa()
8652 		 * below, and it needs to use the name buffer.
8653 		 */
8654 		ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
8655 	} else if (qctx->fname != NULL) {
8656 		/*
8657 		 * We're not going to use fname, and need to release
8658 		 * our hold on the name buffer so query_addsoa()
8659 		 * may use it.
8660 		 */
8661 		ns_client_releasename(qctx->client, &qctx->fname);
8662 	}
8663 
8664 	/*
8665 	 * Add SOA to the additional section if generated by a
8666 	 * RPZ rewrite.
8667 	 *
8668 	 * If the query was for a SOA record force the
8669 	 * ttl to zero so that it is possible for clients to find
8670 	 * the containing zone of an arbitrary name with a stub
8671 	 * resolver and not have it cached.
8672 	 */
8673 	section = qctx->nxrewrite ? DNS_SECTION_ADDITIONAL
8674 				  : DNS_SECTION_AUTHORITY;
8675 	ttl = UINT32_MAX;
8676 	if (!qctx->nxrewrite && qctx->qtype == dns_rdatatype_soa &&
8677 	    qctx->zone != NULL && dns_zone_getzeronosoattl(qctx->zone))
8678 	{
8679 		ttl = 0;
8680 	}
8681 	if (!qctx->nxrewrite || qctx->rpz_st->m.rpz->addsoa) {
8682 		result = query_addsoa(qctx, ttl, section);
8683 		if (result != ISC_R_SUCCESS) {
8684 			QUERY_ERROR(qctx, result);
8685 			return (ns_query_done(qctx));
8686 		}
8687 	}
8688 
8689 	if (WANTDNSSEC(qctx->client)) {
8690 		/*
8691 		 * Add NSEC record if we found one.
8692 		 */
8693 		if (dns_rdataset_isassociated(qctx->rdataset)) {
8694 			query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
8695 				       &qctx->sigrdataset, NULL,
8696 				       DNS_SECTION_AUTHORITY);
8697 		}
8698 		query_addwildcardproof(qctx, false, false);
8699 	}
8700 
8701 	/*
8702 	 * Set message rcode.
8703 	 */
8704 	if (empty_wild) {
8705 		qctx->client->message->rcode = dns_rcode_noerror;
8706 	} else {
8707 		qctx->client->message->rcode = dns_rcode_nxdomain;
8708 	}
8709 
8710 	return (ns_query_done(qctx));
8711 
8712 cleanup:
8713 	return (result);
8714 }
8715 
8716 /*
8717  * Handle both types of NXDOMAIN redirection, calling redirect()
8718  * (which implements type redirect zones) and redirect2() (which
8719  * implements recursive nxdomain-redirect lookups).
8720  *
8721  * Any result code other than ISC_R_COMPLETE means redirection was
8722  * successful and the result code should be returned up the call stack.
8723  *
8724  * ISC_R_COMPLETE means we reached the end of this function without
8725  * redirecting, so query processing should continue past it.
8726  */
8727 static isc_result_t
8728 query_redirect(query_ctx_t *qctx) {
8729 	isc_result_t result;
8730 
8731 	CCTRACE(ISC_LOG_DEBUG(3), "query_redirect");
8732 
8733 	result = redirect(qctx->client, qctx->fname, qctx->rdataset,
8734 			  &qctx->node, &qctx->db, &qctx->version, qctx->type);
8735 	switch (result) {
8736 	case ISC_R_SUCCESS:
8737 		inc_stats(qctx->client, ns_statscounter_nxdomainredirect);
8738 		return (query_prepresponse(qctx));
8739 	case DNS_R_NXRRSET:
8740 		qctx->redirected = true;
8741 		qctx->is_zone = true;
8742 		return (query_nodata(qctx, DNS_R_NXRRSET));
8743 	case DNS_R_NCACHENXRRSET:
8744 		qctx->redirected = true;
8745 		qctx->is_zone = false;
8746 		return (query_ncache(qctx, DNS_R_NCACHENXRRSET));
8747 	default:
8748 		break;
8749 	}
8750 
8751 	result = redirect2(qctx->client, qctx->fname, qctx->rdataset,
8752 			   &qctx->node, &qctx->db, &qctx->version, qctx->type,
8753 			   &qctx->is_zone);
8754 	switch (result) {
8755 	case ISC_R_SUCCESS:
8756 		inc_stats(qctx->client, ns_statscounter_nxdomainredirect);
8757 		return (query_prepresponse(qctx));
8758 	case DNS_R_CONTINUE:
8759 		inc_stats(qctx->client,
8760 			  ns_statscounter_nxdomainredirect_rlookup);
8761 		SAVE(qctx->client->query.redirect.db, qctx->db);
8762 		SAVE(qctx->client->query.redirect.node, qctx->node);
8763 		SAVE(qctx->client->query.redirect.zone, qctx->zone);
8764 		qctx->client->query.redirect.qtype = qctx->qtype;
8765 		INSIST(qctx->rdataset != NULL);
8766 		SAVE(qctx->client->query.redirect.rdataset, qctx->rdataset);
8767 		SAVE(qctx->client->query.redirect.sigrdataset,
8768 		     qctx->sigrdataset);
8769 		qctx->client->query.redirect.result = DNS_R_NCACHENXDOMAIN;
8770 		dns_name_copynf(qctx->fname,
8771 				qctx->client->query.redirect.fname);
8772 		qctx->client->query.redirect.authoritative =
8773 			qctx->authoritative;
8774 		qctx->client->query.redirect.is_zone = qctx->is_zone;
8775 		return (ns_query_done(qctx));
8776 	case DNS_R_NXRRSET:
8777 		qctx->redirected = true;
8778 		qctx->is_zone = true;
8779 		return (query_nodata(qctx, DNS_R_NXRRSET));
8780 	case DNS_R_NCACHENXRRSET:
8781 		qctx->redirected = true;
8782 		qctx->is_zone = false;
8783 		return (query_ncache(qctx, DNS_R_NCACHENXRRSET));
8784 	default:
8785 		break;
8786 	}
8787 
8788 	return (ISC_R_COMPLETE);
8789 }
8790 
8791 /*%
8792  * Logging function to be passed to dns_nsec_noexistnodata.
8793  */
8794 static void
8795 log_noexistnodata(void *val, int level, const char *fmt, ...) {
8796 	query_ctx_t *qctx = val;
8797 	va_list ap;
8798 
8799 	va_start(ap, fmt);
8800 	ns_client_logv(qctx->client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
8801 		       level, fmt, ap);
8802 	va_end(ap);
8803 }
8804 
8805 static dns_ttl_t
8806 query_synthttl(dns_rdataset_t *soardataset, dns_rdataset_t *sigsoardataset,
8807 	       dns_rdataset_t *p1rdataset, dns_rdataset_t *sigp1rdataset,
8808 	       dns_rdataset_t *p2rdataset, dns_rdataset_t *sigp2rdataset) {
8809 	dns_rdata_soa_t soa;
8810 	dns_rdata_t rdata = DNS_RDATA_INIT;
8811 	dns_ttl_t ttl;
8812 	isc_result_t result;
8813 
8814 	REQUIRE(soardataset != NULL);
8815 	REQUIRE(sigsoardataset != NULL);
8816 	REQUIRE(p1rdataset != NULL);
8817 	REQUIRE(sigp1rdataset != NULL);
8818 
8819 	result = dns_rdataset_first(soardataset);
8820 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
8821 	dns_rdataset_current(soardataset, &rdata);
8822 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
8823 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
8824 
8825 	ttl = ISC_MIN(soa.minimum, soardataset->ttl);
8826 	ttl = ISC_MIN(ttl, sigsoardataset->ttl);
8827 	ttl = ISC_MIN(ttl, p1rdataset->ttl);
8828 	ttl = ISC_MIN(ttl, sigp1rdataset->ttl);
8829 	if (p2rdataset != NULL) {
8830 		ttl = ISC_MIN(ttl, p2rdataset->ttl);
8831 	}
8832 	if (sigp2rdataset != NULL) {
8833 		ttl = ISC_MIN(ttl, sigp2rdataset->ttl);
8834 	}
8835 
8836 	return (ttl);
8837 }
8838 
8839 /*
8840  * Synthesize a NODATA response from the SOA and covering NSEC in cache.
8841  */
8842 static isc_result_t
8843 query_synthnodata(query_ctx_t *qctx, const dns_name_t *signer,
8844 		  dns_rdataset_t **soardatasetp,
8845 		  dns_rdataset_t **sigsoardatasetp) {
8846 	dns_name_t *name = NULL;
8847 	dns_ttl_t ttl;
8848 	isc_buffer_t *dbuf, b;
8849 	isc_result_t result;
8850 
8851 	/*
8852 	 * Determine the correct TTL to use for the SOA and RRSIG
8853 	 */
8854 	ttl = query_synthttl(*soardatasetp, *sigsoardatasetp, qctx->rdataset,
8855 			     qctx->sigrdataset, NULL, NULL);
8856 	(*soardatasetp)->ttl = (*sigsoardatasetp)->ttl = ttl;
8857 
8858 	/*
8859 	 * We want the SOA record to be first, so save the
8860 	 * NODATA proof's name now or else discard it.
8861 	 */
8862 	if (WANTDNSSEC(qctx->client)) {
8863 		ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
8864 	} else {
8865 		ns_client_releasename(qctx->client, &qctx->fname);
8866 	}
8867 
8868 	dbuf = ns_client_getnamebuf(qctx->client);
8869 	if (dbuf == NULL) {
8870 		result = ISC_R_NOMEMORY;
8871 		goto cleanup;
8872 	}
8873 
8874 	name = ns_client_newname(qctx->client, dbuf, &b);
8875 	if (name == NULL) {
8876 		result = ISC_R_NOMEMORY;
8877 		goto cleanup;
8878 	}
8879 
8880 	dns_name_copynf(signer, name);
8881 
8882 	/*
8883 	 * Add SOA record. Omit the RRSIG if DNSSEC was not requested.
8884 	 */
8885 	if (!WANTDNSSEC(qctx->client)) {
8886 		sigsoardatasetp = NULL;
8887 	}
8888 	query_addrrset(qctx, &name, soardatasetp, sigsoardatasetp, dbuf,
8889 		       DNS_SECTION_AUTHORITY);
8890 
8891 	if (WANTDNSSEC(qctx->client)) {
8892 		/*
8893 		 * Add NODATA proof.
8894 		 */
8895 		query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
8896 			       &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY);
8897 	}
8898 
8899 	result = ISC_R_SUCCESS;
8900 	inc_stats(qctx->client, ns_statscounter_nodatasynth);
8901 
8902 cleanup:
8903 	if (name != NULL) {
8904 		ns_client_releasename(qctx->client, &name);
8905 	}
8906 	return (result);
8907 }
8908 
8909 /*
8910  * Synthesize a wildcard answer using the contents of 'rdataset'.
8911  * qctx contains the NODATA proof.
8912  */
8913 static isc_result_t
8914 query_synthwildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
8915 		    dns_rdataset_t *sigrdataset) {
8916 	dns_name_t *name = NULL;
8917 	isc_buffer_t *dbuf, b;
8918 	isc_result_t result;
8919 	dns_rdataset_t *cloneset = NULL, *clonesigset = NULL;
8920 	dns_rdataset_t **sigrdatasetp;
8921 
8922 	CCTRACE(ISC_LOG_DEBUG(3), "query_synthwildcard");
8923 
8924 	/*
8925 	 * We want the answer to be first, so save the
8926 	 * NOQNAME proof's name now or else discard it.
8927 	 */
8928 	if (WANTDNSSEC(qctx->client)) {
8929 		ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
8930 	} else {
8931 		ns_client_releasename(qctx->client, &qctx->fname);
8932 	}
8933 
8934 	dbuf = ns_client_getnamebuf(qctx->client);
8935 	if (dbuf == NULL) {
8936 		result = ISC_R_NOMEMORY;
8937 		goto cleanup;
8938 	}
8939 
8940 	name = ns_client_newname(qctx->client, dbuf, &b);
8941 	if (name == NULL) {
8942 		result = ISC_R_NOMEMORY;
8943 		goto cleanup;
8944 	}
8945 	dns_name_copynf(qctx->client->query.qname, name);
8946 
8947 	cloneset = ns_client_newrdataset(qctx->client);
8948 	if (cloneset == NULL) {
8949 		result = ISC_R_NOMEMORY;
8950 		goto cleanup;
8951 	}
8952 	dns_rdataset_clone(rdataset, cloneset);
8953 
8954 	/*
8955 	 * Add answer RRset. Omit the RRSIG if DNSSEC was not requested.
8956 	 */
8957 	if (WANTDNSSEC(qctx->client)) {
8958 		clonesigset = ns_client_newrdataset(qctx->client);
8959 		if (clonesigset == NULL) {
8960 			result = ISC_R_NOMEMORY;
8961 			goto cleanup;
8962 		}
8963 		dns_rdataset_clone(sigrdataset, clonesigset);
8964 		sigrdatasetp = &clonesigset;
8965 	} else {
8966 		sigrdatasetp = NULL;
8967 	}
8968 
8969 	query_addrrset(qctx, &name, &cloneset, sigrdatasetp, dbuf,
8970 		       DNS_SECTION_ANSWER);
8971 
8972 	if (WANTDNSSEC(qctx->client)) {
8973 		/*
8974 		 * Add NOQNAME proof.
8975 		 */
8976 		query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
8977 			       &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY);
8978 	}
8979 
8980 	result = ISC_R_SUCCESS;
8981 	inc_stats(qctx->client, ns_statscounter_wildcardsynth);
8982 
8983 cleanup:
8984 	if (name != NULL) {
8985 		ns_client_releasename(qctx->client, &name);
8986 	}
8987 	if (cloneset != NULL) {
8988 		ns_client_putrdataset(qctx->client, &cloneset);
8989 	}
8990 	if (clonesigset != NULL) {
8991 		ns_client_putrdataset(qctx->client, &clonesigset);
8992 	}
8993 	return (result);
8994 }
8995 
8996 /*
8997  * Add a synthesized CNAME record from the wildard RRset (rdataset)
8998  * and NODATA proof by calling query_synthwildcard then setup to
8999  * follow the CNAME.
9000  */
9001 static isc_result_t
9002 query_synthcnamewildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
9003 			 dns_rdataset_t *sigrdataset) {
9004 	isc_result_t result;
9005 	dns_name_t *tname = NULL;
9006 	dns_rdata_t rdata = DNS_RDATA_INIT;
9007 	dns_rdata_cname_t cname;
9008 
9009 	result = query_synthwildcard(qctx, rdataset, sigrdataset);
9010 	if (result != ISC_R_SUCCESS) {
9011 		return (result);
9012 	}
9013 
9014 	qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
9015 
9016 	/*
9017 	 * Reset qname to be the target name of the CNAME and restart
9018 	 * the query.
9019 	 */
9020 	result = dns_message_gettempname(qctx->client->message, &tname);
9021 	if (result != ISC_R_SUCCESS) {
9022 		return (result);
9023 	}
9024 
9025 	result = dns_rdataset_first(rdataset);
9026 	if (result != ISC_R_SUCCESS) {
9027 		dns_message_puttempname(qctx->client->message, &tname);
9028 		return (result);
9029 	}
9030 
9031 	dns_rdataset_current(rdataset, &rdata);
9032 	result = dns_rdata_tostruct(&rdata, &cname, NULL);
9033 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
9034 	dns_rdata_reset(&rdata);
9035 
9036 	dns_name_init(tname, NULL);
9037 	dns_name_dup(&cname.cname, qctx->client->mctx, tname);
9038 
9039 	dns_rdata_freestruct(&cname);
9040 	ns_client_qnamereplace(qctx->client, tname);
9041 	qctx->want_restart = true;
9042 	if (!WANTRECURSION(qctx->client)) {
9043 		qctx->options |= DNS_GETDB_NOLOG;
9044 	}
9045 
9046 	return (result);
9047 }
9048 
9049 /*
9050  * Synthesize a NXDOMAIN response from qctx (which contains the
9051  * NODATA proof), nowild + nowildrdataset + signowildrdataset (which
9052  * contains the NOWILDCARD proof) and signer + soardatasetp + sigsoardatasetp
9053  * which contain the SOA record + RRSIG for the negative answer.
9054  */
9055 static isc_result_t
9056 query_synthnxdomain(query_ctx_t *qctx, dns_name_t *nowild,
9057 		    dns_rdataset_t *nowildrdataset,
9058 		    dns_rdataset_t *signowildrdataset, dns_name_t *signer,
9059 		    dns_rdataset_t **soardatasetp,
9060 		    dns_rdataset_t **sigsoardatasetp) {
9061 	dns_name_t *name = NULL;
9062 	dns_ttl_t ttl;
9063 	isc_buffer_t *dbuf, b;
9064 	isc_result_t result;
9065 	dns_rdataset_t *cloneset = NULL, *clonesigset = NULL;
9066 
9067 	CCTRACE(ISC_LOG_DEBUG(3), "query_synthnxdomain");
9068 
9069 	/*
9070 	 * Determine the correct TTL to use for the SOA and RRSIG
9071 	 */
9072 	ttl = query_synthttl(*soardatasetp, *sigsoardatasetp, qctx->rdataset,
9073 			     qctx->sigrdataset, nowildrdataset,
9074 			     signowildrdataset);
9075 	(*soardatasetp)->ttl = (*sigsoardatasetp)->ttl = ttl;
9076 
9077 	/*
9078 	 * We want the SOA record to be first, so save the
9079 	 * NOQNAME proof's name now or else discard it.
9080 	 */
9081 	if (WANTDNSSEC(qctx->client)) {
9082 		ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9083 	} else {
9084 		ns_client_releasename(qctx->client, &qctx->fname);
9085 	}
9086 
9087 	dbuf = ns_client_getnamebuf(qctx->client);
9088 	if (dbuf == NULL) {
9089 		result = ISC_R_NOMEMORY;
9090 		goto cleanup;
9091 	}
9092 
9093 	name = ns_client_newname(qctx->client, dbuf, &b);
9094 	if (name == NULL) {
9095 		result = ISC_R_NOMEMORY;
9096 		goto cleanup;
9097 	}
9098 
9099 	dns_name_copynf(signer, name);
9100 
9101 	/*
9102 	 * Add SOA record. Omit the RRSIG if DNSSEC was not requested.
9103 	 */
9104 	if (!WANTDNSSEC(qctx->client)) {
9105 		sigsoardatasetp = NULL;
9106 	}
9107 	query_addrrset(qctx, &name, soardatasetp, sigsoardatasetp, dbuf,
9108 		       DNS_SECTION_AUTHORITY);
9109 
9110 	if (WANTDNSSEC(qctx->client)) {
9111 		/*
9112 		 * Add NOQNAME proof.
9113 		 */
9114 		query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
9115 			       &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY);
9116 
9117 		dbuf = ns_client_getnamebuf(qctx->client);
9118 		if (dbuf == NULL) {
9119 			result = ISC_R_NOMEMORY;
9120 			goto cleanup;
9121 		}
9122 
9123 		name = ns_client_newname(qctx->client, dbuf, &b);
9124 		if (name == NULL) {
9125 			result = ISC_R_NOMEMORY;
9126 			goto cleanup;
9127 		}
9128 
9129 		dns_name_copynf(nowild, name);
9130 
9131 		cloneset = ns_client_newrdataset(qctx->client);
9132 		clonesigset = ns_client_newrdataset(qctx->client);
9133 		if (cloneset == NULL || clonesigset == NULL) {
9134 			result = ISC_R_NOMEMORY;
9135 			goto cleanup;
9136 		}
9137 
9138 		dns_rdataset_clone(nowildrdataset, cloneset);
9139 		dns_rdataset_clone(signowildrdataset, clonesigset);
9140 
9141 		/*
9142 		 * Add NOWILDCARD proof.
9143 		 */
9144 		query_addrrset(qctx, &name, &cloneset, &clonesigset, dbuf,
9145 			       DNS_SECTION_AUTHORITY);
9146 	}
9147 
9148 	qctx->client->message->rcode = dns_rcode_nxdomain;
9149 	result = ISC_R_SUCCESS;
9150 	inc_stats(qctx->client, ns_statscounter_nxdomainsynth);
9151 
9152 cleanup:
9153 	if (name != NULL) {
9154 		ns_client_releasename(qctx->client, &name);
9155 	}
9156 	if (cloneset != NULL) {
9157 		ns_client_putrdataset(qctx->client, &cloneset);
9158 	}
9159 	if (clonesigset != NULL) {
9160 		ns_client_putrdataset(qctx->client, &clonesigset);
9161 	}
9162 	return (result);
9163 }
9164 
9165 /*
9166  * Check that all signer names in sigrdataset match the expected signer.
9167  */
9168 static isc_result_t
9169 checksignames(dns_name_t *signer, dns_rdataset_t *sigrdataset) {
9170 	isc_result_t result;
9171 
9172 	for (result = dns_rdataset_first(sigrdataset); result == ISC_R_SUCCESS;
9173 	     result = dns_rdataset_next(sigrdataset))
9174 	{
9175 		dns_rdata_t rdata = DNS_RDATA_INIT;
9176 		dns_rdata_rrsig_t rrsig;
9177 
9178 		dns_rdataset_current(sigrdataset, &rdata);
9179 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
9180 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
9181 		if (dns_name_countlabels(signer) == 0) {
9182 			dns_name_copynf(&rrsig.signer, signer);
9183 		} else if (!dns_name_equal(signer, &rrsig.signer)) {
9184 			return (ISC_R_FAILURE);
9185 		}
9186 	}
9187 
9188 	return (ISC_R_SUCCESS);
9189 }
9190 
9191 /*%
9192  * Handle covering NSEC responses.
9193  *
9194  * Verify the NSEC record is appropriate for the QNAME; if not,
9195  * redo the initial query without DNS_DBFIND_COVERINGNSEC.
9196  *
9197  * If the covering NSEC proves that the name exists but not the type,
9198  * synthesize a NODATA response.
9199  *
9200  * If the name doesn't exist, compute the wildcard record and check whether
9201  * the wildcard name exists or not.  If we can't determine this, redo the
9202  * initial query without DNS_DBFIND_COVERINGNSEC.
9203  *
9204  * If the wildcard name does not exist, compute the SOA name and look that
9205  * up.  If the SOA record does not exist, redo the initial query without
9206  * DNS_DBFIND_COVERINGNSEC.  If the SOA record exists, synthesize an
9207  * NXDOMAIN response from the found records.
9208  *
9209  * If the wildcard name does exist, perform a lookup for the requested
9210  * type at the wildcard name.
9211  */
9212 static isc_result_t
9213 query_coveringnsec(query_ctx_t *qctx) {
9214 	dns_db_t *db = NULL;
9215 	dns_clientinfo_t ci;
9216 	dns_clientinfomethods_t cm;
9217 	dns_dbnode_t *node = NULL;
9218 	dns_fixedname_t fixed;
9219 	dns_fixedname_t fnowild;
9220 	dns_fixedname_t fsigner;
9221 	dns_fixedname_t fwild;
9222 	dns_name_t *fname = NULL;
9223 	dns_name_t *nowild = NULL;
9224 	dns_name_t *signer = NULL;
9225 	dns_name_t *wild = NULL;
9226 	dns_rdataset_t *soardataset = NULL, *sigsoardataset = NULL;
9227 	dns_rdataset_t rdataset, sigrdataset;
9228 	bool done = false;
9229 	bool exists = true, data = true;
9230 	bool redirected = false;
9231 	isc_result_t result = ISC_R_SUCCESS;
9232 	unsigned int dboptions = qctx->client->query.dboptions;
9233 
9234 	CCTRACE(ISC_LOG_DEBUG(3), "query_coveringnsec");
9235 
9236 	dns_rdataset_init(&rdataset);
9237 	dns_rdataset_init(&sigrdataset);
9238 
9239 	/*
9240 	 * If we have no signer name, stop immediately.
9241 	 */
9242 	if (!dns_rdataset_isassociated(qctx->sigrdataset)) {
9243 		goto cleanup;
9244 	}
9245 
9246 	wild = dns_fixedname_initname(&fwild);
9247 	fname = dns_fixedname_initname(&fixed);
9248 	signer = dns_fixedname_initname(&fsigner);
9249 	nowild = dns_fixedname_initname(&fnowild);
9250 
9251 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
9252 	dns_clientinfo_init(&ci, qctx->client, NULL);
9253 
9254 	/*
9255 	 * All signer names must be the same to accept.
9256 	 */
9257 	result = checksignames(signer, qctx->sigrdataset);
9258 	if (result != ISC_R_SUCCESS) {
9259 		result = ISC_R_SUCCESS;
9260 		goto cleanup;
9261 	}
9262 
9263 	/*
9264 	 * Check that we have the correct NOQNAME NSEC record.
9265 	 */
9266 	result = dns_nsec_noexistnodata(qctx->qtype, qctx->client->query.qname,
9267 					qctx->fname, qctx->rdataset, &exists,
9268 					&data, wild, log_noexistnodata, qctx);
9269 
9270 	if (result != ISC_R_SUCCESS || (exists && data)) {
9271 		goto cleanup;
9272 	}
9273 
9274 	if (exists) {
9275 		if (qctx->type == dns_rdatatype_any) { /* XXX not yet */
9276 			goto cleanup;
9277 		}
9278 		if (!ISC_LIST_EMPTY(qctx->view->dns64) &&
9279 		    (qctx->type == dns_rdatatype_a ||
9280 		     qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
9281 		{
9282 			goto cleanup;
9283 		}
9284 		if (!qctx->resuming && !STALE(qctx->rdataset) &&
9285 		    qctx->rdataset->ttl == 0 && RECURSIONOK(qctx->client))
9286 		{
9287 			goto cleanup;
9288 		}
9289 
9290 		soardataset = ns_client_newrdataset(qctx->client);
9291 		sigsoardataset = ns_client_newrdataset(qctx->client);
9292 		if (soardataset == NULL || sigsoardataset == NULL) {
9293 			goto cleanup;
9294 		}
9295 
9296 		/*
9297 		 * Look for SOA record to construct NODATA response.
9298 		 */
9299 		dns_db_attach(qctx->db, &db);
9300 		result = dns_db_findext(db, signer, qctx->version,
9301 					dns_rdatatype_soa, dboptions,
9302 					qctx->client->now, &node, fname, &cm,
9303 					&ci, soardataset, sigsoardataset);
9304 
9305 		if (result != ISC_R_SUCCESS) {
9306 			goto cleanup;
9307 		}
9308 		(void)query_synthnodata(qctx, signer, &soardataset,
9309 					&sigsoardataset);
9310 		done = true;
9311 		goto cleanup;
9312 	}
9313 
9314 	/*
9315 	 * Look up the no-wildcard proof.
9316 	 */
9317 	dns_db_attach(qctx->db, &db);
9318 	result = dns_db_findext(db, wild, qctx->version, qctx->type,
9319 				dboptions | DNS_DBFIND_COVERINGNSEC,
9320 				qctx->client->now, &node, nowild, &cm, &ci,
9321 				&rdataset, &sigrdataset);
9322 
9323 	if (rdataset.trust != dns_trust_secure ||
9324 	    sigrdataset.trust != dns_trust_secure) {
9325 		goto cleanup;
9326 	}
9327 
9328 	/*
9329 	 * Zero TTL handling of wildcard record.
9330 	 *
9331 	 * We don't yet have code to handle synthesis and type ANY or dns64
9332 	 * processing so we abort the synthesis here if there would be a
9333 	 * interaction.
9334 	 */
9335 	switch (result) {
9336 	case ISC_R_SUCCESS:
9337 		if (qctx->type == dns_rdatatype_any) { /* XXX not yet */
9338 			goto cleanup;
9339 		}
9340 		if (!ISC_LIST_EMPTY(qctx->view->dns64) &&
9341 		    (qctx->type == dns_rdatatype_a ||
9342 		     qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
9343 		{
9344 			goto cleanup;
9345 		}
9346 	/* FALLTHROUGH */
9347 	case DNS_R_CNAME:
9348 		if (!qctx->resuming && !STALE(&rdataset) && rdataset.ttl == 0 &&
9349 		    RECURSIONOK(qctx->client))
9350 		{
9351 			goto cleanup;
9352 		}
9353 	default:
9354 		break;
9355 	}
9356 
9357 	switch (result) {
9358 	case DNS_R_COVERINGNSEC:
9359 		result = dns_nsec_noexistnodata(qctx->qtype, wild, nowild,
9360 						&rdataset, &exists, &data, NULL,
9361 						log_noexistnodata, qctx);
9362 		if (result != ISC_R_SUCCESS || exists) {
9363 			goto cleanup;
9364 		}
9365 		break;
9366 	case ISC_R_SUCCESS: /* wild card match */
9367 		(void)query_synthwildcard(qctx, &rdataset, &sigrdataset);
9368 		done = true;
9369 		goto cleanup;
9370 	case DNS_R_CNAME: /* wild card cname */
9371 		(void)query_synthcnamewildcard(qctx, &rdataset, &sigrdataset);
9372 		done = true;
9373 		goto cleanup;
9374 	case DNS_R_NCACHENXRRSET:  /* wild card nodata */
9375 	case DNS_R_NCACHENXDOMAIN: /* direct nxdomain */
9376 	default:
9377 		goto cleanup;
9378 	}
9379 
9380 	/*
9381 	 * We now have the proof that we have an NXDOMAIN.  Apply
9382 	 * NXDOMAIN redirection if configured.
9383 	 */
9384 	result = query_redirect(qctx);
9385 	if (result != ISC_R_COMPLETE) {
9386 		redirected = true;
9387 		goto cleanup;
9388 	}
9389 
9390 	/*
9391 	 * Must be signed to accept.
9392 	 */
9393 	if (!dns_rdataset_isassociated(&sigrdataset)) {
9394 		goto cleanup;
9395 	}
9396 
9397 	/*
9398 	 * Check signer signer names again.
9399 	 */
9400 	result = checksignames(signer, &sigrdataset);
9401 	if (result != ISC_R_SUCCESS) {
9402 		result = ISC_R_SUCCESS;
9403 		goto cleanup;
9404 	}
9405 
9406 	if (node != NULL) {
9407 		dns_db_detachnode(db, &node);
9408 	}
9409 
9410 	soardataset = ns_client_newrdataset(qctx->client);
9411 	sigsoardataset = ns_client_newrdataset(qctx->client);
9412 	if (soardataset == NULL || sigsoardataset == NULL) {
9413 		goto cleanup;
9414 	}
9415 
9416 	/*
9417 	 * Look for SOA record to construct NXDOMAIN response.
9418 	 */
9419 	result = dns_db_findext(db, signer, qctx->version, dns_rdatatype_soa,
9420 				dboptions, qctx->client->now, &node, fname, &cm,
9421 				&ci, soardataset, sigsoardataset);
9422 
9423 	if (result != ISC_R_SUCCESS) {
9424 		goto cleanup;
9425 	}
9426 
9427 	(void)query_synthnxdomain(qctx, nowild, &rdataset, &sigrdataset, signer,
9428 				  &soardataset, &sigsoardataset);
9429 	done = true;
9430 
9431 cleanup:
9432 	if (dns_rdataset_isassociated(&rdataset)) {
9433 		dns_rdataset_disassociate(&rdataset);
9434 	}
9435 	if (dns_rdataset_isassociated(&sigrdataset)) {
9436 		dns_rdataset_disassociate(&sigrdataset);
9437 	}
9438 	if (soardataset != NULL) {
9439 		ns_client_putrdataset(qctx->client, &soardataset);
9440 	}
9441 	if (sigsoardataset != NULL) {
9442 		ns_client_putrdataset(qctx->client, &sigsoardataset);
9443 	}
9444 	if (db != NULL) {
9445 		if (node != NULL) {
9446 			dns_db_detachnode(db, &node);
9447 		}
9448 		dns_db_detach(&db);
9449 	}
9450 
9451 	if (redirected) {
9452 		return (result);
9453 	}
9454 
9455 	if (!done) {
9456 		/*
9457 		 * No covering NSEC was found; proceed with recursion.
9458 		 */
9459 		qctx->findcoveringnsec = false;
9460 		if (qctx->fname != NULL) {
9461 			ns_client_releasename(qctx->client, &qctx->fname);
9462 		}
9463 		if (qctx->node != NULL) {
9464 			dns_db_detachnode(qctx->db, &qctx->node);
9465 		}
9466 		ns_client_putrdataset(qctx->client, &qctx->rdataset);
9467 		if (qctx->sigrdataset != NULL) {
9468 			ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
9469 		}
9470 		return (query_lookup(qctx));
9471 	}
9472 
9473 	return (ns_query_done(qctx));
9474 }
9475 
9476 /*%
9477  * Handle negative cache responses, DNS_R_NCACHENXRRSET or
9478  * DNS_R_NCACHENXDOMAIN. (Note: may also be called with result
9479  * set to DNS_R_NXDOMAIN when handling DNS64 lookups.)
9480  */
9481 static isc_result_t
9482 query_ncache(query_ctx_t *qctx, isc_result_t result) {
9483 	INSIST(!qctx->is_zone);
9484 	INSIST(result == DNS_R_NCACHENXDOMAIN ||
9485 	       result == DNS_R_NCACHENXRRSET || result == DNS_R_NXDOMAIN);
9486 
9487 	CCTRACE(ISC_LOG_DEBUG(3), "query_ncache");
9488 
9489 	CALL_HOOK(NS_QUERY_NCACHE_BEGIN, qctx);
9490 
9491 	qctx->authoritative = false;
9492 
9493 	if (result == DNS_R_NCACHENXDOMAIN) {
9494 		/*
9495 		 * Set message rcode. (This is not done when
9496 		 * result == DNS_R_NXDOMAIN because that means we're
9497 		 * being called after a DNS64 lookup and don't want
9498 		 * to update the rcode now.)
9499 		 */
9500 		qctx->client->message->rcode = dns_rcode_nxdomain;
9501 
9502 		/* Look for RFC 1918 leakage from Internet. */
9503 		if (qctx->qtype == dns_rdatatype_ptr &&
9504 		    qctx->client->message->rdclass == dns_rdataclass_in &&
9505 		    dns_name_countlabels(qctx->fname) == 7)
9506 		{
9507 			warn_rfc1918(qctx->client, qctx->fname, qctx->rdataset);
9508 		}
9509 	}
9510 
9511 	return (query_nodata(qctx, result));
9512 
9513 cleanup:
9514 	return (result);
9515 }
9516 
9517 /*
9518  * If we have a zero ttl from the cache, refetch.
9519  */
9520 static isc_result_t
9521 query_zerottl_refetch(query_ctx_t *qctx) {
9522 	isc_result_t result;
9523 
9524 	CCTRACE(ISC_LOG_DEBUG(3), "query_zerottl_refetch");
9525 
9526 	if (qctx->is_zone || qctx->resuming || STALE(qctx->rdataset) ||
9527 	    qctx->rdataset->ttl != 0 || !RECURSIONOK(qctx->client))
9528 	{
9529 		return (ISC_R_COMPLETE);
9530 	}
9531 
9532 	qctx_clean(qctx);
9533 
9534 	INSIST(!REDIRECT(qctx->client));
9535 
9536 	result = ns_query_recurse(qctx->client, qctx->qtype,
9537 				  qctx->client->query.qname, NULL, NULL,
9538 				  qctx->resuming);
9539 	if (result == ISC_R_SUCCESS) {
9540 		CALL_HOOK(NS_QUERY_ZEROTTL_RECURSE, qctx);
9541 		qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
9542 
9543 		if (qctx->dns64) {
9544 			qctx->client->query.attributes |= NS_QUERYATTR_DNS64;
9545 		}
9546 		if (qctx->dns64_exclude) {
9547 			qctx->client->query.attributes |=
9548 				NS_QUERYATTR_DNS64EXCLUDE;
9549 		}
9550 	} else {
9551 		QUERY_ERROR(qctx, result);
9552 	}
9553 
9554 	return (ns_query_done(qctx));
9555 
9556 cleanup:
9557 	return (result);
9558 }
9559 
9560 /*
9561  * Handle CNAME responses.
9562  */
9563 static isc_result_t
9564 query_cname(query_ctx_t *qctx) {
9565 	isc_result_t result;
9566 	dns_name_t *tname;
9567 	dns_rdataset_t *trdataset;
9568 	dns_rdataset_t **sigrdatasetp = NULL;
9569 	dns_rdata_t rdata = DNS_RDATA_INIT;
9570 	dns_rdata_cname_t cname;
9571 
9572 	CCTRACE(ISC_LOG_DEBUG(3), "query_cname");
9573 
9574 	CALL_HOOK(NS_QUERY_CNAME_BEGIN, qctx);
9575 
9576 	result = query_zerottl_refetch(qctx);
9577 	if (result != ISC_R_COMPLETE) {
9578 		return (result);
9579 	}
9580 
9581 	/*
9582 	 * Keep a copy of the rdataset.  We have to do this because
9583 	 * query_addrrset may clear 'rdataset' (to prevent the
9584 	 * cleanup code from cleaning it up).
9585 	 */
9586 	trdataset = qctx->rdataset;
9587 
9588 	/*
9589 	 * Add the CNAME to the answer section.
9590 	 */
9591 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
9592 		sigrdatasetp = &qctx->sigrdataset;
9593 	}
9594 
9595 	if (WANTDNSSEC(qctx->client) &&
9596 	    (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
9597 	{
9598 		dns_fixedname_init(&qctx->wildcardname);
9599 		dns_name_copynf(qctx->fname,
9600 				dns_fixedname_name(&qctx->wildcardname));
9601 		qctx->need_wildcardproof = true;
9602 	}
9603 
9604 	if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) {
9605 		qctx->noqname = qctx->rdataset;
9606 	} else {
9607 		qctx->noqname = NULL;
9608 	}
9609 
9610 	if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
9611 		query_prefetch(qctx->client, qctx->fname, qctx->rdataset);
9612 	}
9613 
9614 	query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp,
9615 		       qctx->dbuf, DNS_SECTION_ANSWER);
9616 
9617 	query_addnoqnameproof(qctx);
9618 
9619 	/*
9620 	 * We set the PARTIALANSWER attribute so that if anything goes
9621 	 * wrong later on, we'll return what we've got so far.
9622 	 */
9623 	qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
9624 
9625 	/*
9626 	 * Reset qname to be the target name of the CNAME and restart
9627 	 * the query.
9628 	 */
9629 	tname = NULL;
9630 	result = dns_message_gettempname(qctx->client->message, &tname);
9631 	if (result != ISC_R_SUCCESS) {
9632 		return (ns_query_done(qctx));
9633 	}
9634 
9635 	result = dns_rdataset_first(trdataset);
9636 	if (result != ISC_R_SUCCESS) {
9637 		dns_message_puttempname(qctx->client->message, &tname);
9638 		return (ns_query_done(qctx));
9639 	}
9640 
9641 	dns_rdataset_current(trdataset, &rdata);
9642 	result = dns_rdata_tostruct(&rdata, &cname, NULL);
9643 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
9644 	dns_rdata_reset(&rdata);
9645 
9646 	dns_name_init(tname, NULL);
9647 	dns_name_dup(&cname.cname, qctx->client->mctx, tname);
9648 
9649 	dns_rdata_freestruct(&cname);
9650 	ns_client_qnamereplace(qctx->client, tname);
9651 	qctx->want_restart = true;
9652 	if (!WANTRECURSION(qctx->client)) {
9653 		qctx->options |= DNS_GETDB_NOLOG;
9654 	}
9655 
9656 	query_addauth(qctx);
9657 
9658 	return (ns_query_done(qctx));
9659 
9660 cleanup:
9661 	return (result);
9662 }
9663 
9664 /*
9665  * Handle DNAME responses.
9666  */
9667 static isc_result_t
9668 query_dname(query_ctx_t *qctx) {
9669 	dns_name_t *tname, *prefix;
9670 	dns_rdata_t rdata = DNS_RDATA_INIT;
9671 	dns_rdata_dname_t dname;
9672 	dns_fixedname_t fixed;
9673 	dns_rdataset_t *trdataset;
9674 	dns_rdataset_t **sigrdatasetp = NULL;
9675 	dns_namereln_t namereln;
9676 	isc_buffer_t b;
9677 	int order;
9678 	isc_result_t result;
9679 	unsigned int nlabels;
9680 
9681 	CCTRACE(ISC_LOG_DEBUG(3), "query_dname");
9682 
9683 	CALL_HOOK(NS_QUERY_DNAME_BEGIN, qctx);
9684 
9685 	/*
9686 	 * Compare the current qname to the found name.  We need
9687 	 * to know how many labels and bits are in common because
9688 	 * we're going to have to split qname later on.
9689 	 */
9690 	namereln = dns_name_fullcompare(qctx->client->query.qname, qctx->fname,
9691 					&order, &nlabels);
9692 	INSIST(namereln == dns_namereln_subdomain);
9693 
9694 	/*
9695 	 * Keep a copy of the rdataset.  We have to do this because
9696 	 * query_addrrset may clear 'rdataset' (to prevent the
9697 	 * cleanup code from cleaning it up).
9698 	 */
9699 	trdataset = qctx->rdataset;
9700 
9701 	/*
9702 	 * Add the DNAME to the answer section.
9703 	 */
9704 	if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
9705 		sigrdatasetp = &qctx->sigrdataset;
9706 	}
9707 
9708 	if (WANTDNSSEC(qctx->client) &&
9709 	    (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
9710 	{
9711 		dns_fixedname_init(&qctx->wildcardname);
9712 		dns_name_copynf(qctx->fname,
9713 				dns_fixedname_name(&qctx->wildcardname));
9714 		qctx->need_wildcardproof = true;
9715 	}
9716 
9717 	if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
9718 		query_prefetch(qctx->client, qctx->fname, qctx->rdataset);
9719 	}
9720 	query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp,
9721 		       qctx->dbuf, DNS_SECTION_ANSWER);
9722 
9723 	/*
9724 	 * We set the PARTIALANSWER attribute so that if anything goes
9725 	 * wrong later on, we'll return what we've got so far.
9726 	 */
9727 	qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
9728 
9729 	/*
9730 	 * Get the target name of the DNAME.
9731 	 */
9732 	tname = NULL;
9733 	result = dns_message_gettempname(qctx->client->message, &tname);
9734 	if (result != ISC_R_SUCCESS) {
9735 		return (ns_query_done(qctx));
9736 	}
9737 
9738 	result = dns_rdataset_first(trdataset);
9739 	if (result != ISC_R_SUCCESS) {
9740 		dns_message_puttempname(qctx->client->message, &tname);
9741 		return (ns_query_done(qctx));
9742 	}
9743 
9744 	dns_rdataset_current(trdataset, &rdata);
9745 	result = dns_rdata_tostruct(&rdata, &dname, NULL);
9746 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
9747 	dns_rdata_reset(&rdata);
9748 
9749 	dns_name_clone(&dname.dname, tname);
9750 	dns_rdata_freestruct(&dname);
9751 
9752 	/*
9753 	 * Construct the new qname consisting of
9754 	 * <found name prefix>.<dname target>
9755 	 */
9756 	prefix = dns_fixedname_initname(&fixed);
9757 	dns_name_split(qctx->client->query.qname, nlabels, prefix, NULL);
9758 	INSIST(qctx->fname == NULL);
9759 	qctx->dbuf = ns_client_getnamebuf(qctx->client);
9760 	if (qctx->dbuf == NULL) {
9761 		dns_message_puttempname(qctx->client->message, &tname);
9762 		return (ns_query_done(qctx));
9763 	}
9764 	qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
9765 	if (qctx->fname == NULL) {
9766 		dns_message_puttempname(qctx->client->message, &tname);
9767 		return (ns_query_done(qctx));
9768 	}
9769 	result = dns_name_concatenate(prefix, tname, qctx->fname, NULL);
9770 	dns_message_puttempname(qctx->client->message, &tname);
9771 
9772 	/*
9773 	 * RFC2672, section 4.1, subsection 3c says
9774 	 * we should return YXDOMAIN if the constructed
9775 	 * name would be too long.
9776 	 */
9777 	if (result == DNS_R_NAMETOOLONG) {
9778 		qctx->client->message->rcode = dns_rcode_yxdomain;
9779 	}
9780 	if (result != ISC_R_SUCCESS) {
9781 		return (ns_query_done(qctx));
9782 	}
9783 
9784 	ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9785 
9786 	/*
9787 	 * Synthesize a CNAME consisting of
9788 	 *   <old qname> <dname ttl> CNAME <new qname>
9789 	 *	    with <dname trust value>
9790 	 *
9791 	 * Synthesize a CNAME so old old clients that don't understand
9792 	 * DNAME can chain.
9793 	 *
9794 	 * We do not try to synthesize a signature because we hope
9795 	 * that security aware servers will understand DNAME.  Also,
9796 	 * even if we had an online key, making a signature
9797 	 * on-the-fly is costly, and not really legitimate anyway
9798 	 * since the synthesized CNAME is NOT in the zone.
9799 	 */
9800 	result = query_addcname(qctx, trdataset->trust, trdataset->ttl);
9801 	if (result != ISC_R_SUCCESS) {
9802 		return (ns_query_done(qctx));
9803 	}
9804 
9805 	/*
9806 	 * Switch to the new qname and restart.
9807 	 */
9808 	ns_client_qnamereplace(qctx->client, qctx->fname);
9809 	qctx->fname = NULL;
9810 	qctx->want_restart = true;
9811 	if (!WANTRECURSION(qctx->client)) {
9812 		qctx->options |= DNS_GETDB_NOLOG;
9813 	}
9814 
9815 	query_addauth(qctx);
9816 
9817 	return (ns_query_done(qctx));
9818 
9819 cleanup:
9820 	return (result);
9821 }
9822 
9823 /*%
9824  * Add CNAME to response.
9825  */
9826 static isc_result_t
9827 query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) {
9828 	ns_client_t *client = qctx->client;
9829 	dns_rdataset_t *rdataset = NULL;
9830 	dns_rdatalist_t *rdatalist = NULL;
9831 	dns_rdata_t *rdata = NULL;
9832 	isc_region_t r;
9833 	dns_name_t *aname = NULL;
9834 	isc_result_t result;
9835 
9836 	result = dns_message_gettempname(client->message, &aname);
9837 	if (result != ISC_R_SUCCESS) {
9838 		return (result);
9839 	}
9840 	dns_name_dup(client->query.qname, client->mctx, aname);
9841 
9842 	result = dns_message_gettemprdatalist(client->message, &rdatalist);
9843 	if (result != ISC_R_SUCCESS) {
9844 		dns_message_puttempname(client->message, &aname);
9845 		return (result);
9846 	}
9847 
9848 	result = dns_message_gettemprdata(client->message, &rdata);
9849 	if (result != ISC_R_SUCCESS) {
9850 		dns_message_puttempname(client->message, &aname);
9851 		dns_message_puttemprdatalist(client->message, &rdatalist);
9852 		return (result);
9853 	}
9854 
9855 	result = dns_message_gettemprdataset(client->message, &rdataset);
9856 	if (result != ISC_R_SUCCESS) {
9857 		dns_message_puttempname(client->message, &aname);
9858 		dns_message_puttemprdatalist(client->message, &rdatalist);
9859 		dns_message_puttemprdata(client->message, &rdata);
9860 		return (result);
9861 	}
9862 
9863 	rdatalist->type = dns_rdatatype_cname;
9864 	rdatalist->rdclass = client->message->rdclass;
9865 	rdatalist->ttl = ttl;
9866 
9867 	dns_name_toregion(qctx->fname, &r);
9868 	rdata->data = r.base;
9869 	rdata->length = r.length;
9870 	rdata->rdclass = client->message->rdclass;
9871 	rdata->type = dns_rdatatype_cname;
9872 
9873 	ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
9874 	RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
9875 		      ISC_R_SUCCESS);
9876 	rdataset->trust = trust;
9877 	dns_rdataset_setownercase(rdataset, aname);
9878 
9879 	query_addrrset(qctx, &aname, &rdataset, NULL, NULL, DNS_SECTION_ANSWER);
9880 	if (rdataset != NULL) {
9881 		if (dns_rdataset_isassociated(rdataset)) {
9882 			dns_rdataset_disassociate(rdataset);
9883 		}
9884 		dns_message_puttemprdataset(client->message, &rdataset);
9885 	}
9886 	if (aname != NULL) {
9887 		dns_message_puttempname(client->message, &aname);
9888 	}
9889 
9890 	return (ISC_R_SUCCESS);
9891 }
9892 
9893 /*%
9894  * Prepare to respond: determine whether a wildcard proof is needed,
9895  * then hand off to query_respond() or (for type ANY queries)
9896  * query_respond_any().
9897  */
9898 static isc_result_t
9899 query_prepresponse(query_ctx_t *qctx) {
9900 	isc_result_t result;
9901 
9902 	CCTRACE(ISC_LOG_DEBUG(3), "query_prepresponse");
9903 
9904 	CALL_HOOK(NS_QUERY_PREP_RESPONSE_BEGIN, qctx);
9905 
9906 	if (WANTDNSSEC(qctx->client) &&
9907 	    (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0)
9908 	{
9909 		dns_fixedname_init(&qctx->wildcardname);
9910 		dns_name_copynf(qctx->fname,
9911 				dns_fixedname_name(&qctx->wildcardname));
9912 		qctx->need_wildcardproof = true;
9913 	}
9914 
9915 	if (qctx->type == dns_rdatatype_any) {
9916 		return (query_respond_any(qctx));
9917 	}
9918 
9919 	result = query_zerottl_refetch(qctx);
9920 	if (result != ISC_R_COMPLETE) {
9921 		return (result);
9922 	}
9923 
9924 	return (query_respond(qctx));
9925 
9926 cleanup:
9927 	return (result);
9928 }
9929 
9930 /*%
9931  * Add SOA to the authority section when sending negative responses
9932  * (or to the additional section if sending negative responses triggered
9933  * by RPZ rewriting.)
9934  */
9935 static isc_result_t
9936 query_addsoa(query_ctx_t *qctx, unsigned int override_ttl,
9937 	     dns_section_t section) {
9938 	ns_client_t *client = qctx->client;
9939 	dns_name_t *name;
9940 	dns_dbnode_t *node;
9941 	isc_result_t result, eresult;
9942 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
9943 	dns_rdataset_t **sigrdatasetp = NULL;
9944 	dns_clientinfomethods_t cm;
9945 	dns_clientinfo_t ci;
9946 
9947 	CTRACE(ISC_LOG_DEBUG(3), "query_addsoa");
9948 	/*
9949 	 * Initialization.
9950 	 */
9951 	eresult = ISC_R_SUCCESS;
9952 	name = NULL;
9953 	rdataset = NULL;
9954 	node = NULL;
9955 
9956 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
9957 	dns_clientinfo_init(&ci, client, NULL);
9958 
9959 	/*
9960 	 * Don't add the SOA record for test which set "-T nosoa".
9961 	 */
9962 	if (((client->sctx->options & NS_SERVER_NOSOA) != 0) &&
9963 	    (!WANTDNSSEC(client) || !dns_rdataset_isassociated(qctx->rdataset)))
9964 	{
9965 		return (ISC_R_SUCCESS);
9966 	}
9967 
9968 	/*
9969 	 * Get resources and make 'name' be the database origin.
9970 	 */
9971 	result = dns_message_gettempname(client->message, &name);
9972 	if (result != ISC_R_SUCCESS) {
9973 		return (result);
9974 	}
9975 	dns_name_init(name, NULL);
9976 	dns_name_clone(dns_db_origin(qctx->db), name);
9977 	rdataset = ns_client_newrdataset(client);
9978 	if (rdataset == NULL) {
9979 		CTRACE(ISC_LOG_ERROR, "unable to allocate rdataset");
9980 		eresult = DNS_R_SERVFAIL;
9981 		goto cleanup;
9982 	}
9983 	if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) {
9984 		sigrdataset = ns_client_newrdataset(client);
9985 		if (sigrdataset == NULL) {
9986 			CTRACE(ISC_LOG_ERROR, "unable to allocate sigrdataset");
9987 			eresult = DNS_R_SERVFAIL;
9988 			goto cleanup;
9989 		}
9990 	}
9991 
9992 	/*
9993 	 * Find the SOA.
9994 	 */
9995 	result = dns_db_getoriginnode(qctx->db, &node);
9996 	if (result == ISC_R_SUCCESS) {
9997 		result = dns_db_findrdataset(qctx->db, node, qctx->version,
9998 					     dns_rdatatype_soa, 0, client->now,
9999 					     rdataset, sigrdataset);
10000 	} else {
10001 		dns_fixedname_t foundname;
10002 		dns_name_t *fname;
10003 
10004 		fname = dns_fixedname_initname(&foundname);
10005 
10006 		result = dns_db_findext(qctx->db, name, qctx->version,
10007 					dns_rdatatype_soa,
10008 					client->query.dboptions, 0, &node,
10009 					fname, &cm, &ci, rdataset, sigrdataset);
10010 	}
10011 	if (result != ISC_R_SUCCESS) {
10012 		/*
10013 		 * This is bad.  We tried to get the SOA RR at the zone top
10014 		 * and it didn't work!
10015 		 */
10016 		CTRACE(ISC_LOG_ERROR, "unable to find SOA RR at zone apex");
10017 		eresult = DNS_R_SERVFAIL;
10018 	} else {
10019 		/*
10020 		 * Extract the SOA MINIMUM.
10021 		 */
10022 		dns_rdata_soa_t soa;
10023 		dns_rdata_t rdata = DNS_RDATA_INIT;
10024 		result = dns_rdataset_first(rdataset);
10025 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
10026 		dns_rdataset_current(rdataset, &rdata);
10027 		result = dns_rdata_tostruct(&rdata, &soa, NULL);
10028 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
10029 
10030 		if (override_ttl != UINT32_MAX && override_ttl < rdataset->ttl)
10031 		{
10032 			rdataset->ttl = override_ttl;
10033 			if (sigrdataset != NULL) {
10034 				sigrdataset->ttl = override_ttl;
10035 			}
10036 		}
10037 
10038 		/*
10039 		 * Add the SOA and its SIG to the response, with the
10040 		 * TTLs adjusted per RFC2308 section 3.
10041 		 */
10042 		if (rdataset->ttl > soa.minimum) {
10043 			rdataset->ttl = soa.minimum;
10044 		}
10045 		if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum) {
10046 			sigrdataset->ttl = soa.minimum;
10047 		}
10048 
10049 		if (sigrdataset != NULL) {
10050 			sigrdatasetp = &sigrdataset;
10051 		} else {
10052 			sigrdatasetp = NULL;
10053 		}
10054 
10055 		if (section == DNS_SECTION_ADDITIONAL) {
10056 			rdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
10057 		}
10058 		query_addrrset(qctx, &name, &rdataset, sigrdatasetp, NULL,
10059 			       section);
10060 	}
10061 
10062 cleanup:
10063 	ns_client_putrdataset(client, &rdataset);
10064 	if (sigrdataset != NULL) {
10065 		ns_client_putrdataset(client, &sigrdataset);
10066 	}
10067 	if (name != NULL) {
10068 		ns_client_releasename(client, &name);
10069 	}
10070 	if (node != NULL) {
10071 		dns_db_detachnode(qctx->db, &node);
10072 	}
10073 
10074 	return (eresult);
10075 }
10076 
10077 /*%
10078  * Add NS to authority section (used when the zone apex is already known).
10079  */
10080 static isc_result_t
10081 query_addns(query_ctx_t *qctx) {
10082 	ns_client_t *client = qctx->client;
10083 	isc_result_t result, eresult;
10084 	dns_name_t *name = NULL, *fname;
10085 	dns_dbnode_t *node = NULL;
10086 	dns_fixedname_t foundname;
10087 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
10088 	dns_rdataset_t **sigrdatasetp = NULL;
10089 	dns_clientinfomethods_t cm;
10090 	dns_clientinfo_t ci;
10091 
10092 	CTRACE(ISC_LOG_DEBUG(3), "query_addns");
10093 
10094 	/*
10095 	 * Initialization.
10096 	 */
10097 	eresult = ISC_R_SUCCESS;
10098 	fname = dns_fixedname_initname(&foundname);
10099 
10100 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
10101 	dns_clientinfo_init(&ci, client, NULL);
10102 
10103 	/*
10104 	 * Get resources and make 'name' be the database origin.
10105 	 */
10106 	result = dns_message_gettempname(client->message, &name);
10107 	if (result != ISC_R_SUCCESS) {
10108 		CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_message_gettempname "
10109 					 "failed: done");
10110 		return (result);
10111 	}
10112 	dns_name_init(name, NULL);
10113 	dns_name_clone(dns_db_origin(qctx->db), name);
10114 	rdataset = ns_client_newrdataset(client);
10115 	if (rdataset == NULL) {
10116 		CTRACE(ISC_LOG_ERROR, "query_addns: ns_client_newrdataset "
10117 				      "failed");
10118 		eresult = DNS_R_SERVFAIL;
10119 		goto cleanup;
10120 	}
10121 
10122 	if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) {
10123 		sigrdataset = ns_client_newrdataset(client);
10124 		if (sigrdataset == NULL) {
10125 			CTRACE(ISC_LOG_ERROR, "query_addns: "
10126 					      "ns_client_newrdataset failed");
10127 			eresult = DNS_R_SERVFAIL;
10128 			goto cleanup;
10129 		}
10130 	}
10131 
10132 	/*
10133 	 * Find the NS rdataset.
10134 	 */
10135 	result = dns_db_getoriginnode(qctx->db, &node);
10136 	if (result == ISC_R_SUCCESS) {
10137 		result = dns_db_findrdataset(qctx->db, node, qctx->version,
10138 					     dns_rdatatype_ns, 0, client->now,
10139 					     rdataset, sigrdataset);
10140 	} else {
10141 		CTRACE(ISC_LOG_DEBUG(3), "query_addns: calling dns_db_find");
10142 		result = dns_db_findext(qctx->db, name, NULL, dns_rdatatype_ns,
10143 					client->query.dboptions, 0, &node,
10144 					fname, &cm, &ci, rdataset, sigrdataset);
10145 		CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_db_find complete");
10146 	}
10147 	if (result != ISC_R_SUCCESS) {
10148 		CTRACE(ISC_LOG_ERROR, "query_addns: "
10149 				      "dns_db_findrdataset or dns_db_find "
10150 				      "failed");
10151 		/*
10152 		 * This is bad.  We tried to get the NS rdataset at the zone
10153 		 * top and it didn't work!
10154 		 */
10155 		eresult = DNS_R_SERVFAIL;
10156 	} else {
10157 		if (sigrdataset != NULL) {
10158 			sigrdatasetp = &sigrdataset;
10159 		}
10160 		query_addrrset(qctx, &name, &rdataset, sigrdatasetp, NULL,
10161 			       DNS_SECTION_AUTHORITY);
10162 	}
10163 
10164 cleanup:
10165 	CTRACE(ISC_LOG_DEBUG(3), "query_addns: cleanup");
10166 	ns_client_putrdataset(client, &rdataset);
10167 	if (sigrdataset != NULL) {
10168 		ns_client_putrdataset(client, &sigrdataset);
10169 	}
10170 	if (name != NULL) {
10171 		ns_client_releasename(client, &name);
10172 	}
10173 	if (node != NULL) {
10174 		dns_db_detachnode(qctx->db, &node);
10175 	}
10176 
10177 	CTRACE(ISC_LOG_DEBUG(3), "query_addns: done");
10178 	return (eresult);
10179 }
10180 
10181 /*%
10182  * Find the zone cut and add the best NS rrset to the authority section.
10183  */
10184 static void
10185 query_addbestns(query_ctx_t *qctx) {
10186 	ns_client_t *client = qctx->client;
10187 	dns_db_t *db = NULL, *zdb = NULL;
10188 	dns_dbnode_t *node = NULL;
10189 	dns_name_t *fname = NULL, *zfname = NULL;
10190 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
10191 	dns_rdataset_t *zrdataset = NULL, *zsigrdataset = NULL;
10192 	bool is_zone = false, use_zone = false;
10193 	isc_buffer_t *dbuf = NULL;
10194 	isc_result_t result;
10195 	dns_dbversion_t *version = NULL;
10196 	dns_zone_t *zone = NULL;
10197 	isc_buffer_t b;
10198 	dns_clientinfomethods_t cm;
10199 	dns_clientinfo_t ci;
10200 
10201 	CTRACE(ISC_LOG_DEBUG(3), "query_addbestns");
10202 
10203 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
10204 	dns_clientinfo_init(&ci, client, NULL);
10205 
10206 	/*
10207 	 * Find the right database.
10208 	 */
10209 	result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0,
10210 			     &zone, &db, &version, &is_zone);
10211 	if (result != ISC_R_SUCCESS) {
10212 		goto cleanup;
10213 	}
10214 
10215 db_find:
10216 	/*
10217 	 * We'll need some resources...
10218 	 */
10219 	dbuf = ns_client_getnamebuf(client);
10220 	if (dbuf == NULL) {
10221 		goto cleanup;
10222 	}
10223 	fname = ns_client_newname(client, dbuf, &b);
10224 	rdataset = ns_client_newrdataset(client);
10225 	if (fname == NULL || rdataset == NULL) {
10226 		goto cleanup;
10227 	}
10228 
10229 	/*
10230 	 * Get the RRSIGs if the client requested them or if we may
10231 	 * need to validate answers from the cache.
10232 	 */
10233 	if (WANTDNSSEC(client) || !is_zone) {
10234 		sigrdataset = ns_client_newrdataset(client);
10235 		if (sigrdataset == NULL) {
10236 			goto cleanup;
10237 		}
10238 	}
10239 
10240 	/*
10241 	 * Now look for the zonecut.
10242 	 */
10243 	if (is_zone) {
10244 		result = dns_db_findext(
10245 			db, client->query.qname, version, dns_rdatatype_ns,
10246 			client->query.dboptions, client->now, &node, fname, &cm,
10247 			&ci, rdataset, sigrdataset);
10248 		if (result != DNS_R_DELEGATION) {
10249 			goto cleanup;
10250 		}
10251 		if (USECACHE(client)) {
10252 			ns_client_keepname(client, fname, dbuf);
10253 			dns_db_detachnode(db, &node);
10254 			SAVE(zdb, db);
10255 			SAVE(zfname, fname);
10256 			SAVE(zrdataset, rdataset);
10257 			SAVE(zsigrdataset, sigrdataset);
10258 			version = NULL;
10259 			dns_db_attach(client->view->cachedb, &db);
10260 			is_zone = false;
10261 			goto db_find;
10262 		}
10263 	} else {
10264 		result = dns_db_findzonecut(
10265 			db, client->query.qname, client->query.dboptions,
10266 			client->now, &node, fname, NULL, rdataset, sigrdataset);
10267 		if (result == ISC_R_SUCCESS) {
10268 			if (zfname != NULL &&
10269 			    !dns_name_issubdomain(fname, zfname)) {
10270 				/*
10271 				 * We found a zonecut in the cache, but our
10272 				 * zone delegation is better.
10273 				 */
10274 				use_zone = true;
10275 			}
10276 		} else if (result == ISC_R_NOTFOUND && zfname != NULL) {
10277 			/*
10278 			 * We didn't find anything in the cache, but we
10279 			 * have a zone delegation, so use it.
10280 			 */
10281 			use_zone = true;
10282 		} else {
10283 			goto cleanup;
10284 		}
10285 	}
10286 
10287 	if (use_zone) {
10288 		ns_client_releasename(client, &fname);
10289 		/*
10290 		 * We've already done ns_client_keepname() on
10291 		 * zfname, so we must set dbuf to NULL to
10292 		 * prevent query_addrrset() from trying to
10293 		 * call ns_client_keepname() again.
10294 		 */
10295 		dbuf = NULL;
10296 		ns_client_putrdataset(client, &rdataset);
10297 		if (sigrdataset != NULL) {
10298 			ns_client_putrdataset(client, &sigrdataset);
10299 		}
10300 
10301 		if (node != NULL) {
10302 			dns_db_detachnode(db, &node);
10303 		}
10304 		dns_db_detach(&db);
10305 
10306 		RESTORE(db, zdb);
10307 		RESTORE(fname, zfname);
10308 		RESTORE(rdataset, zrdataset);
10309 		RESTORE(sigrdataset, zsigrdataset);
10310 	}
10311 
10312 	/*
10313 	 * Attempt to validate RRsets that are pending or that are glue.
10314 	 */
10315 	if ((DNS_TRUST_PENDING(rdataset->trust) ||
10316 	     (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust))) &&
10317 	    !validate(client, db, fname, rdataset, sigrdataset) &&
10318 	    !PENDINGOK(client->query.dboptions))
10319 	{
10320 		goto cleanup;
10321 	}
10322 
10323 	if ((DNS_TRUST_GLUE(rdataset->trust) ||
10324 	     (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) &&
10325 	    !validate(client, db, fname, rdataset, sigrdataset) &&
10326 	    SECURE(client) && WANTDNSSEC(client))
10327 	{
10328 		goto cleanup;
10329 	}
10330 
10331 	/*
10332 	 * If the answer is secure only add NS records if they are secure
10333 	 * when the client may be looking for AD in the response.
10334 	 */
10335 	if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) &&
10336 	    ((rdataset->trust != dns_trust_secure) ||
10337 	     (sigrdataset != NULL && sigrdataset->trust != dns_trust_secure)))
10338 	{
10339 		goto cleanup;
10340 	}
10341 
10342 	/*
10343 	 * If the client doesn't want DNSSEC we can discard the sigrdataset
10344 	 * now.
10345 	 */
10346 	if (!WANTDNSSEC(client)) {
10347 		ns_client_putrdataset(client, &sigrdataset);
10348 	}
10349 
10350 	query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
10351 		       DNS_SECTION_AUTHORITY);
10352 
10353 cleanup:
10354 	if (rdataset != NULL) {
10355 		ns_client_putrdataset(client, &rdataset);
10356 	}
10357 	if (sigrdataset != NULL) {
10358 		ns_client_putrdataset(client, &sigrdataset);
10359 	}
10360 	if (fname != NULL) {
10361 		ns_client_releasename(client, &fname);
10362 	}
10363 	if (node != NULL) {
10364 		dns_db_detachnode(db, &node);
10365 	}
10366 	if (db != NULL) {
10367 		dns_db_detach(&db);
10368 	}
10369 	if (zone != NULL) {
10370 		dns_zone_detach(&zone);
10371 	}
10372 	if (zdb != NULL) {
10373 		ns_client_putrdataset(client, &zrdataset);
10374 		if (zsigrdataset != NULL) {
10375 			ns_client_putrdataset(client, &zsigrdataset);
10376 		}
10377 		if (zfname != NULL) {
10378 			ns_client_releasename(client, &zfname);
10379 		}
10380 		dns_db_detach(&zdb);
10381 	}
10382 }
10383 
10384 static void
10385 query_addwildcardproof(query_ctx_t *qctx, bool ispositive, bool nodata) {
10386 	ns_client_t *client = qctx->client;
10387 	isc_buffer_t *dbuf, b;
10388 	dns_name_t *name;
10389 	dns_name_t *fname = NULL;
10390 	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
10391 	dns_fixedname_t wfixed;
10392 	dns_name_t *wname;
10393 	dns_dbnode_t *node = NULL;
10394 	unsigned int options;
10395 	unsigned int olabels, nlabels, labels;
10396 	isc_result_t result;
10397 	dns_rdata_t rdata = DNS_RDATA_INIT;
10398 	dns_rdata_nsec_t nsec;
10399 	bool have_wname;
10400 	int order;
10401 	dns_fixedname_t cfixed;
10402 	dns_name_t *cname;
10403 	dns_clientinfomethods_t cm;
10404 	dns_clientinfo_t ci;
10405 
10406 	CTRACE(ISC_LOG_DEBUG(3), "query_addwildcardproof");
10407 
10408 	dns_clientinfomethods_init(&cm, ns_client_sourceip);
10409 	dns_clientinfo_init(&ci, client, NULL);
10410 
10411 	/*
10412 	 * If a name has been specifically flagged as needing
10413 	 * a wildcard proof then it will have been copied to
10414 	 * qctx->wildcardname. Otherwise we just use the client
10415 	 * QNAME.
10416 	 */
10417 	if (qctx->need_wildcardproof) {
10418 		name = dns_fixedname_name(&qctx->wildcardname);
10419 	} else {
10420 		name = client->query.qname;
10421 	}
10422 
10423 	/*
10424 	 * Get the NOQNAME proof then if !ispositive
10425 	 * get the NOWILDCARD proof.
10426 	 *
10427 	 * DNS_DBFIND_NOWILD finds the NSEC records that covers the
10428 	 * name ignoring any wildcard.  From the owner and next names
10429 	 * of this record you can compute which wildcard (if it exists)
10430 	 * will match by finding the longest common suffix of the
10431 	 * owner name and next names with the qname and prefixing that
10432 	 * with the wildcard label.
10433 	 *
10434 	 * e.g.
10435 	 *   Given:
10436 	 *	example SOA
10437 	 *	example NSEC b.example
10438 	 *	b.example A
10439 	 *	b.example NSEC a.d.example
10440 	 *	a.d.example A
10441 	 *	a.d.example NSEC g.f.example
10442 	 *	g.f.example A
10443 	 *	g.f.example NSEC z.i.example
10444 	 *	z.i.example A
10445 	 *	z.i.example NSEC example
10446 	 *
10447 	 *   QNAME:
10448 	 *   a.example -> example NSEC b.example
10449 	 *	owner common example
10450 	 *	next common example
10451 	 *	wild *.example
10452 	 *   d.b.example -> b.example NSEC a.d.example
10453 	 *	owner common b.example
10454 	 *	next common example
10455 	 *	wild *.b.example
10456 	 *   a.f.example -> a.d.example NSEC g.f.example
10457 	 *	owner common example
10458 	 *	next common f.example
10459 	 *	wild *.f.example
10460 	 *  j.example -> z.i.example NSEC example
10461 	 *	owner common example
10462 	 *	next common example
10463 	 *	wild *.example
10464 	 */
10465 	options = client->query.dboptions | DNS_DBFIND_NOWILD;
10466 	wname = dns_fixedname_initname(&wfixed);
10467 again:
10468 	have_wname = false;
10469 	/*
10470 	 * We'll need some resources...
10471 	 */
10472 	dbuf = ns_client_getnamebuf(client);
10473 	if (dbuf == NULL) {
10474 		goto cleanup;
10475 	}
10476 	fname = ns_client_newname(client, dbuf, &b);
10477 	rdataset = ns_client_newrdataset(client);
10478 	sigrdataset = ns_client_newrdataset(client);
10479 	if (fname == NULL || rdataset == NULL || sigrdataset == NULL) {
10480 		goto cleanup;
10481 	}
10482 
10483 	result = dns_db_findext(qctx->db, name, qctx->version,
10484 				dns_rdatatype_nsec, options, 0, &node, fname,
10485 				&cm, &ci, rdataset, sigrdataset);
10486 	if (node != NULL) {
10487 		dns_db_detachnode(qctx->db, &node);
10488 	}
10489 
10490 	if (!dns_rdataset_isassociated(rdataset)) {
10491 		/*
10492 		 * No NSEC proof available, return NSEC3 proofs instead.
10493 		 */
10494 		cname = dns_fixedname_initname(&cfixed);
10495 		/*
10496 		 * Find the closest encloser.
10497 		 */
10498 		dns_name_copynf(name, cname);
10499 		while (result == DNS_R_NXDOMAIN) {
10500 			labels = dns_name_countlabels(cname) - 1;
10501 			/*
10502 			 * Sanity check.
10503 			 */
10504 			if (labels == 0U) {
10505 				goto cleanup;
10506 			}
10507 			dns_name_split(cname, labels, NULL, cname);
10508 			result = dns_db_findext(qctx->db, cname, qctx->version,
10509 						dns_rdatatype_nsec, options, 0,
10510 						NULL, fname, &cm, &ci, NULL,
10511 						NULL);
10512 		}
10513 		/*
10514 		 * Add closest (provable) encloser NSEC3.
10515 		 */
10516 		query_findclosestnsec3(cname, qctx->db, qctx->version, client,
10517 				       rdataset, sigrdataset, fname, true,
10518 				       cname);
10519 		if (!dns_rdataset_isassociated(rdataset)) {
10520 			goto cleanup;
10521 		}
10522 		if (!ispositive) {
10523 			query_addrrset(qctx, &fname, &rdataset, &sigrdataset,
10524 				       dbuf, DNS_SECTION_AUTHORITY);
10525 		}
10526 
10527 		/*
10528 		 * Replace resources which were consumed by query_addrrset.
10529 		 */
10530 		if (fname == NULL) {
10531 			dbuf = ns_client_getnamebuf(client);
10532 			if (dbuf == NULL) {
10533 				goto cleanup;
10534 			}
10535 			fname = ns_client_newname(client, dbuf, &b);
10536 		}
10537 
10538 		if (rdataset == NULL) {
10539 			rdataset = ns_client_newrdataset(client);
10540 		} else if (dns_rdataset_isassociated(rdataset)) {
10541 			dns_rdataset_disassociate(rdataset);
10542 		}
10543 
10544 		if (sigrdataset == NULL) {
10545 			sigrdataset = ns_client_newrdataset(client);
10546 		} else if (dns_rdataset_isassociated(sigrdataset)) {
10547 			dns_rdataset_disassociate(sigrdataset);
10548 		}
10549 
10550 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL) {
10551 			goto cleanup;
10552 		}
10553 		/*
10554 		 * Add no qname proof.
10555 		 */
10556 		labels = dns_name_countlabels(cname) + 1;
10557 		if (dns_name_countlabels(name) == labels) {
10558 			dns_name_copynf(name, wname);
10559 		} else {
10560 			dns_name_split(name, labels, NULL, wname);
10561 		}
10562 
10563 		query_findclosestnsec3(wname, qctx->db, qctx->version, client,
10564 				       rdataset, sigrdataset, fname, false,
10565 				       NULL);
10566 		if (!dns_rdataset_isassociated(rdataset)) {
10567 			goto cleanup;
10568 		}
10569 		query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
10570 			       DNS_SECTION_AUTHORITY);
10571 
10572 		if (ispositive) {
10573 			goto cleanup;
10574 		}
10575 
10576 		/*
10577 		 * Replace resources which were consumed by query_addrrset.
10578 		 */
10579 		if (fname == NULL) {
10580 			dbuf = ns_client_getnamebuf(client);
10581 			if (dbuf == NULL) {
10582 				goto cleanup;
10583 			}
10584 			fname = ns_client_newname(client, dbuf, &b);
10585 		}
10586 
10587 		if (rdataset == NULL) {
10588 			rdataset = ns_client_newrdataset(client);
10589 		} else if (dns_rdataset_isassociated(rdataset)) {
10590 			dns_rdataset_disassociate(rdataset);
10591 		}
10592 
10593 		if (sigrdataset == NULL) {
10594 			sigrdataset = ns_client_newrdataset(client);
10595 		} else if (dns_rdataset_isassociated(sigrdataset)) {
10596 			dns_rdataset_disassociate(sigrdataset);
10597 		}
10598 
10599 		if (fname == NULL || rdataset == NULL || sigrdataset == NULL) {
10600 			goto cleanup;
10601 		}
10602 		/*
10603 		 * Add the no wildcard proof.
10604 		 */
10605 		result = dns_name_concatenate(dns_wildcardname, cname, wname,
10606 					      NULL);
10607 		if (result != ISC_R_SUCCESS) {
10608 			goto cleanup;
10609 		}
10610 
10611 		query_findclosestnsec3(wname, qctx->db, qctx->version, client,
10612 				       rdataset, sigrdataset, fname, nodata,
10613 				       NULL);
10614 		if (!dns_rdataset_isassociated(rdataset)) {
10615 			goto cleanup;
10616 		}
10617 		query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
10618 			       DNS_SECTION_AUTHORITY);
10619 
10620 		goto cleanup;
10621 	} else if (result == DNS_R_NXDOMAIN) {
10622 		if (!ispositive) {
10623 			result = dns_rdataset_first(rdataset);
10624 		}
10625 		if (result == ISC_R_SUCCESS) {
10626 			dns_rdataset_current(rdataset, &rdata);
10627 			result = dns_rdata_tostruct(&rdata, &nsec, NULL);
10628 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
10629 			(void)dns_name_fullcompare(name, fname, &order,
10630 						   &olabels);
10631 			(void)dns_name_fullcompare(name, &nsec.next, &order,
10632 						   &nlabels);
10633 			/*
10634 			 * Check for a pathological condition created when
10635 			 * serving some malformed signed zones and bail out.
10636 			 */
10637 			if (dns_name_countlabels(name) == nlabels) {
10638 				goto cleanup;
10639 			}
10640 
10641 			if (olabels > nlabels) {
10642 				dns_name_split(name, olabels, NULL, wname);
10643 			} else {
10644 				dns_name_split(name, nlabels, NULL, wname);
10645 			}
10646 			result = dns_name_concatenate(dns_wildcardname, wname,
10647 						      wname, NULL);
10648 			if (result == ISC_R_SUCCESS) {
10649 				have_wname = true;
10650 			}
10651 			dns_rdata_freestruct(&nsec);
10652 		}
10653 		query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
10654 			       DNS_SECTION_AUTHORITY);
10655 	}
10656 	if (rdataset != NULL) {
10657 		ns_client_putrdataset(client, &rdataset);
10658 	}
10659 	if (sigrdataset != NULL) {
10660 		ns_client_putrdataset(client, &sigrdataset);
10661 	}
10662 	if (fname != NULL) {
10663 		ns_client_releasename(client, &fname);
10664 	}
10665 	if (have_wname) {
10666 		ispositive = true; /* prevent loop */
10667 		if (!dns_name_equal(name, wname)) {
10668 			name = wname;
10669 			goto again;
10670 		}
10671 	}
10672 cleanup:
10673 	if (rdataset != NULL) {
10674 		ns_client_putrdataset(client, &rdataset);
10675 	}
10676 	if (sigrdataset != NULL) {
10677 		ns_client_putrdataset(client, &sigrdataset);
10678 	}
10679 	if (fname != NULL) {
10680 		ns_client_releasename(client, &fname);
10681 	}
10682 }
10683 
10684 /*%
10685  * Add NS records, and NSEC/NSEC3 wildcard proof records if needed,
10686  * to the authority section.
10687  */
10688 static void
10689 query_addauth(query_ctx_t *qctx) {
10690 	CCTRACE(ISC_LOG_DEBUG(3), "query_addauth");
10691 	/*
10692 	 * Add NS records to the authority section (if we haven't already
10693 	 * added them to the answer section).
10694 	 */
10695 	if (!qctx->want_restart && !NOAUTHORITY(qctx->client)) {
10696 		if (qctx->is_zone) {
10697 			if (!qctx->answer_has_ns) {
10698 				(void)query_addns(qctx);
10699 			}
10700 		} else if (!qctx->answer_has_ns &&
10701 			   qctx->qtype != dns_rdatatype_ns) {
10702 			if (qctx->fname != NULL) {
10703 				ns_client_releasename(qctx->client,
10704 						      &qctx->fname);
10705 			}
10706 			query_addbestns(qctx);
10707 		}
10708 	}
10709 
10710 	/*
10711 	 * Add NSEC records to the authority section if they're needed for
10712 	 * DNSSEC wildcard proofs.
10713 	 */
10714 	if (qctx->need_wildcardproof && dns_db_issecure(qctx->db)) {
10715 		query_addwildcardproof(qctx, true, false);
10716 	}
10717 }
10718 
10719 /*
10720  * Find the sort order of 'rdata' in the topology-like
10721  * ACL forming the second element in a 2-element top-level
10722  * sortlist statement.
10723  */
10724 static int
10725 query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) {
10726 	isc_netaddr_t netaddr;
10727 
10728 	if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) {
10729 		return (INT_MAX);
10730 	}
10731 	return (ns_sortlist_addrorder2(&netaddr, arg));
10732 }
10733 
10734 /*
10735  * Find the sort order of 'rdata' in the matching element
10736  * of a 1-element top-level sortlist statement.
10737  */
10738 static int
10739 query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) {
10740 	isc_netaddr_t netaddr;
10741 
10742 	if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) {
10743 		return (INT_MAX);
10744 	}
10745 	return (ns_sortlist_addrorder1(&netaddr, arg));
10746 }
10747 
10748 /*
10749  * Find the sortlist statement that applies to 'client' and set up
10750  * the sortlist info in in client->message appropriately.
10751  */
10752 static void
10753 query_setup_sortlist(query_ctx_t *qctx) {
10754 	isc_netaddr_t netaddr;
10755 	ns_client_t *client = qctx->client;
10756 	dns_aclenv_t *env =
10757 		ns_interfacemgr_getaclenv(client->manager->interface->mgr);
10758 	const void *order_arg = NULL;
10759 
10760 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
10761 	switch (ns_sortlist_setup(client->view->sortlist, env, &netaddr,
10762 				  &order_arg)) {
10763 	case NS_SORTLISTTYPE_1ELEMENT:
10764 		dns_message_setsortorder(client->message,
10765 					 query_sortlist_order_1element, env,
10766 					 NULL, order_arg);
10767 		break;
10768 	case NS_SORTLISTTYPE_2ELEMENT:
10769 		dns_message_setsortorder(client->message,
10770 					 query_sortlist_order_2element, env,
10771 					 order_arg, NULL);
10772 		break;
10773 	case NS_SORTLISTTYPE_NONE:
10774 		break;
10775 	default:
10776 		INSIST(0);
10777 		ISC_UNREACHABLE();
10778 	}
10779 }
10780 
10781 /*
10782  * When sending a referral, if the answer to the question is
10783  * in the glue, sort it to the start of the additional section.
10784  */
10785 static inline void
10786 query_glueanswer(query_ctx_t *qctx) {
10787 	const dns_namelist_t *secs = qctx->client->message->sections;
10788 	const dns_section_t section = DNS_SECTION_ADDITIONAL;
10789 	dns_name_t *name;
10790 	dns_message_t *msg;
10791 	dns_rdataset_t *rdataset = NULL;
10792 
10793 	if (!ISC_LIST_EMPTY(secs[DNS_SECTION_ANSWER]) ||
10794 	    qctx->client->message->rcode != dns_rcode_noerror ||
10795 	    (qctx->qtype != dns_rdatatype_a &&
10796 	     qctx->qtype != dns_rdatatype_aaaa))
10797 	{
10798 		return;
10799 	}
10800 
10801 	msg = qctx->client->message;
10802 	for (name = ISC_LIST_HEAD(msg->sections[section]); name != NULL;
10803 	     name = ISC_LIST_NEXT(name, link))
10804 	{
10805 		if (dns_name_equal(name, qctx->client->query.qname)) {
10806 			for (rdataset = ISC_LIST_HEAD(name->list);
10807 			     rdataset != NULL;
10808 			     rdataset = ISC_LIST_NEXT(rdataset, link))
10809 			{
10810 				if (rdataset->type == qctx->qtype) {
10811 					break;
10812 				}
10813 			}
10814 			break;
10815 		}
10816 	}
10817 	if (rdataset != NULL) {
10818 		ISC_LIST_UNLINK(msg->sections[section], name, link);
10819 		ISC_LIST_PREPEND(msg->sections[section], name, link);
10820 		ISC_LIST_UNLINK(name->list, rdataset, link);
10821 		ISC_LIST_PREPEND(name->list, rdataset, link);
10822 		rdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
10823 	}
10824 }
10825 
10826 isc_result_t
10827 ns_query_done(query_ctx_t *qctx) {
10828 	isc_result_t result;
10829 	const dns_namelist_t *secs = qctx->client->message->sections;
10830 
10831 	CCTRACE(ISC_LOG_DEBUG(3), "ns_query_done");
10832 
10833 	CALL_HOOK(NS_QUERY_DONE_BEGIN, qctx);
10834 
10835 	/*
10836 	 * General cleanup.
10837 	 */
10838 	qctx->rpz_st = qctx->client->query.rpz_st;
10839 	if (qctx->rpz_st != NULL &&
10840 	    (qctx->rpz_st->state & DNS_RPZ_RECURSING) == 0) {
10841 		rpz_match_clear(qctx->rpz_st);
10842 		qctx->rpz_st->state &= ~DNS_RPZ_DONE_QNAME;
10843 	}
10844 
10845 	qctx_clean(qctx);
10846 	qctx_freedata(qctx);
10847 
10848 	if (qctx->client->query.gluedb != NULL) {
10849 		dns_db_detach(&qctx->client->query.gluedb);
10850 	}
10851 
10852 	/*
10853 	 * Clear the AA bit if we're not authoritative.
10854 	 */
10855 	if (qctx->client->query.restarts == 0 && !qctx->authoritative) {
10856 		qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
10857 	}
10858 
10859 	/*
10860 	 * Do we need to restart the query (e.g. for CNAME chaining)?
10861 	 */
10862 	if (qctx->want_restart && qctx->client->query.restarts < MAX_RESTARTS) {
10863 		qctx->client->query.restarts++;
10864 		return (ns__query_start(qctx));
10865 	}
10866 
10867 	if (qctx->result != ISC_R_SUCCESS &&
10868 	    (!PARTIALANSWER(qctx->client) || WANTRECURSION(qctx->client) ||
10869 	     qctx->result == DNS_R_DROP))
10870 	{
10871 		if (qctx->result == DNS_R_DUPLICATE ||
10872 		    qctx->result == DNS_R_DROP) {
10873 			/*
10874 			 * This was a duplicate query that we are
10875 			 * recursing on or the result of rate limiting.
10876 			 * Don't send a response now for a duplicate query,
10877 			 * because the original will still cause a response.
10878 			 */
10879 			query_next(qctx->client, qctx->result);
10880 		} else {
10881 			/*
10882 			 * If we don't have any answer to give the client,
10883 			 * or if the client requested recursion and thus wanted
10884 			 * the complete answer, send an error response.
10885 			 */
10886 			INSIST(qctx->line >= 0);
10887 			query_error(qctx->client, qctx->result, qctx->line);
10888 		}
10889 
10890 		qctx->detach_client = true;
10891 		return (qctx->result);
10892 	}
10893 
10894 	/*
10895 	 * If we're recursing then just return; the query will
10896 	 * resume when recursion ends.
10897 	 */
10898 	if (RECURSING(qctx->client)) {
10899 		return (qctx->result);
10900 	}
10901 
10902 	/*
10903 	 * We are done.  Set up sortlist data for the message
10904 	 * rendering code, sort the answer to the front of the
10905 	 * additional section if necessary, make a final tweak
10906 	 * to the AA bit if the auth-nxdomain config option
10907 	 * says so, then render and send the response.
10908 	 */
10909 	query_setup_sortlist(qctx);
10910 	query_glueanswer(qctx);
10911 
10912 	if (qctx->client->message->rcode == dns_rcode_nxdomain &&
10913 	    qctx->view->auth_nxdomain)
10914 	{
10915 		qctx->client->message->flags |= DNS_MESSAGEFLAG_AA;
10916 	}
10917 
10918 	/*
10919 	 * If the response is somehow unexpected for the client and this
10920 	 * is a result of recursion, return an error to the caller
10921 	 * to indicate it may need to be logged.
10922 	 */
10923 	if (qctx->resuming &&
10924 	    (ISC_LIST_EMPTY(secs[DNS_SECTION_ANSWER]) ||
10925 	     qctx->client->message->rcode != dns_rcode_noerror))
10926 	{
10927 		qctx->result = ISC_R_FAILURE;
10928 	}
10929 
10930 	CALL_HOOK(NS_QUERY_DONE_SEND, qctx);
10931 
10932 	query_send(qctx->client);
10933 
10934 	qctx->detach_client = true;
10935 	return (qctx->result);
10936 
10937 cleanup:
10938 	return (result);
10939 }
10940 
10941 static inline void
10942 log_tat(ns_client_t *client) {
10943 	char namebuf[DNS_NAME_FORMATSIZE];
10944 	char clientbuf[ISC_NETADDR_FORMATSIZE];
10945 	char classbuf[DNS_RDATACLASS_FORMATSIZE];
10946 	isc_netaddr_t netaddr;
10947 	char *tags = NULL;
10948 	size_t taglen = 0;
10949 
10950 	if (!isc_log_wouldlog(ns_lctx, ISC_LOG_INFO)) {
10951 		return;
10952 	}
10953 
10954 	if ((client->query.qtype != dns_rdatatype_null ||
10955 	     !dns_name_istat(client->query.qname)) &&
10956 	    (client->keytag == NULL ||
10957 	     client->query.qtype != dns_rdatatype_dnskey))
10958 	{
10959 		return;
10960 	}
10961 
10962 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
10963 	dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
10964 	isc_netaddr_format(&netaddr, clientbuf, sizeof(clientbuf));
10965 	dns_rdataclass_format(client->view->rdclass, classbuf,
10966 			      sizeof(classbuf));
10967 
10968 	if (client->query.qtype == dns_rdatatype_dnskey) {
10969 		uint16_t keytags = client->keytag_len / 2;
10970 		size_t len = taglen = sizeof("65000") * keytags + 1;
10971 		char *cp = tags = isc_mem_get(client->mctx, taglen);
10972 		int i = 0;
10973 
10974 		INSIST(client->keytag != NULL);
10975 		if (tags != NULL) {
10976 			while (keytags-- > 0U) {
10977 				int n;
10978 				uint16_t keytag;
10979 				keytag = (client->keytag[i * 2] << 8) |
10980 					 client->keytag[i * 2 + 1];
10981 				n = snprintf(cp, len, " %u", keytag);
10982 				if (n > 0 && (size_t)n <= len) {
10983 					cp += n;
10984 					len -= n;
10985 					i++;
10986 				} else {
10987 					break;
10988 				}
10989 			}
10990 		}
10991 	}
10992 
10993 	isc_log_write(ns_lctx, NS_LOGCATEGORY_TAT, NS_LOGMODULE_QUERY,
10994 		      ISC_LOG_INFO, "trust-anchor-telemetry '%s/%s' from %s%s",
10995 		      namebuf, classbuf, clientbuf, tags != NULL ? tags : "");
10996 	if (tags != NULL) {
10997 		isc_mem_put(client->mctx, tags, taglen);
10998 	}
10999 }
11000 
11001 static inline void
11002 log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
11003 	char namebuf[DNS_NAME_FORMATSIZE];
11004 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
11005 	char classbuf[DNS_RDATACLASS_FORMATSIZE];
11006 	char onbuf[ISC_NETADDR_FORMATSIZE];
11007 	char ecsbuf[DNS_ECS_FORMATSIZE + sizeof(" [ECS ]") - 1] = { 0 };
11008 	char ednsbuf[sizeof("E(65535)")] = { 0 };
11009 	dns_rdataset_t *rdataset;
11010 	int level = ISC_LOG_INFO;
11011 
11012 	if (!isc_log_wouldlog(ns_lctx, level)) {
11013 		return;
11014 	}
11015 
11016 	rdataset = ISC_LIST_HEAD(client->query.qname->list);
11017 	INSIST(rdataset != NULL);
11018 	dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
11019 	dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf));
11020 	dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf));
11021 	isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf));
11022 
11023 	if (client->ednsversion >= 0) {
11024 		snprintf(ednsbuf, sizeof(ednsbuf), "E(%hd)",
11025 			 client->ednsversion);
11026 	}
11027 
11028 	if (HAVEECS(client)) {
11029 		strlcpy(ecsbuf, " [ECS ", sizeof(ecsbuf));
11030 		dns_ecs_format(&client->ecs, ecsbuf + 6, sizeof(ecsbuf) - 6);
11031 		strlcat(ecsbuf, "]", sizeof(ecsbuf));
11032 	}
11033 
11034 	ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, level,
11035 		      "query: %s %s %s %s%s%s%s%s%s%s (%s)%s", namebuf,
11036 		      classbuf, typebuf, WANTRECURSION(client) ? "+" : "-",
11037 		      (client->signer != NULL) ? "S" : "", ednsbuf,
11038 		      TCP(client) ? "T" : "",
11039 		      ((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "",
11040 		      ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "",
11041 		      HAVECOOKIE(client) ? "V" : WANTCOOKIE(client) ? "K" : "",
11042 		      onbuf, ecsbuf);
11043 }
11044 
11045 static inline void
11046 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) {
11047 	char namebuf[DNS_NAME_FORMATSIZE];
11048 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
11049 	char classbuf[DNS_RDATACLASS_FORMATSIZE];
11050 	const char *namep, *typep, *classp, *sep1, *sep2;
11051 	dns_rdataset_t *rdataset;
11052 
11053 	if (!isc_log_wouldlog(ns_lctx, level)) {
11054 		return;
11055 	}
11056 
11057 	namep = typep = classp = sep1 = sep2 = "";
11058 
11059 	/*
11060 	 * Query errors can happen for various reasons.  In some cases we cannot
11061 	 * even assume the query contains a valid question section, so we should
11062 	 * expect exceptional cases.
11063 	 */
11064 	if (client->query.origqname != NULL) {
11065 		dns_name_format(client->query.origqname, namebuf,
11066 				sizeof(namebuf));
11067 		namep = namebuf;
11068 		sep1 = " for ";
11069 
11070 		rdataset = ISC_LIST_HEAD(client->query.origqname->list);
11071 		if (rdataset != NULL) {
11072 			dns_rdataclass_format(rdataset->rdclass, classbuf,
11073 					      sizeof(classbuf));
11074 			classp = classbuf;
11075 			dns_rdatatype_format(rdataset->type, typebuf,
11076 					     sizeof(typebuf));
11077 			typep = typebuf;
11078 			sep2 = "/";
11079 		}
11080 	}
11081 
11082 	ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY,
11083 		      level, "query failed (%s)%s%s%s%s%s%s at %s:%d",
11084 		      isc_result_totext(result), sep1, namep, sep2, classp,
11085 		      sep2, typep, __FILE__, line);
11086 }
11087 
11088 void
11089 ns_query_start(ns_client_t *client) {
11090 	isc_result_t result;
11091 	dns_message_t *message;
11092 	dns_rdataset_t *rdataset;
11093 	dns_rdatatype_t qtype;
11094 	unsigned int saved_extflags;
11095 	unsigned int saved_flags;
11096 
11097 	REQUIRE(NS_CLIENT_VALID(client));
11098 
11099 	message = client->message;
11100 	saved_extflags = client->extflags;
11101 	saved_flags = client->message->flags;
11102 
11103 	CTRACE(ISC_LOG_DEBUG(3), "ns_query_start");
11104 
11105 	/*
11106 	 * Ensure that appropriate cleanups occur.
11107 	 */
11108 	client->cleanup = query_cleanup;
11109 
11110 	if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) {
11111 		client->query.attributes |= NS_QUERYATTR_WANTRECURSION;
11112 	}
11113 
11114 	if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) {
11115 		client->attributes |= NS_CLIENTATTR_WANTDNSSEC;
11116 	}
11117 
11118 	switch (client->view->minimalresponses) {
11119 	case dns_minimal_no:
11120 		break;
11121 	case dns_minimal_yes:
11122 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
11123 					     NS_QUERYATTR_NOADDITIONAL);
11124 		break;
11125 	case dns_minimal_noauth:
11126 		client->query.attributes |= NS_QUERYATTR_NOAUTHORITY;
11127 		break;
11128 	case dns_minimal_noauthrec:
11129 		if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) {
11130 			client->query.attributes |= NS_QUERYATTR_NOAUTHORITY;
11131 		}
11132 		break;
11133 	}
11134 
11135 	if (client->view->cachedb == NULL || !client->view->recursion) {
11136 		/*
11137 		 * We don't have a cache.  Turn off cache support and
11138 		 * recursion.
11139 		 */
11140 		client->query.attributes &= ~(NS_QUERYATTR_RECURSIONOK |
11141 					      NS_QUERYATTR_CACHEOK);
11142 		client->attributes |= NS_CLIENTATTR_NOSETFC;
11143 	} else if ((client->attributes & NS_CLIENTATTR_RA) == 0 ||
11144 		   (message->flags & DNS_MESSAGEFLAG_RD) == 0)
11145 	{
11146 		/*
11147 		 * If the client isn't allowed to recurse (due to
11148 		 * "recursion no", the allow-recursion ACL, or the
11149 		 * lack of a resolver in this view), or if it
11150 		 * doesn't want recursion, turn recursion off.
11151 		 */
11152 		client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
11153 		client->attributes |= NS_CLIENTATTR_NOSETFC;
11154 	}
11155 
11156 	/*
11157 	 * Check for multiple question queries, since edns1 is dead.
11158 	 */
11159 	if (message->counts[DNS_SECTION_QUESTION] > 1) {
11160 		query_error(client, DNS_R_FORMERR, __LINE__);
11161 		return;
11162 	}
11163 
11164 	/*
11165 	 * Get the question name.
11166 	 */
11167 	result = dns_message_firstname(message, DNS_SECTION_QUESTION);
11168 	if (result != ISC_R_SUCCESS) {
11169 		query_error(client, result, __LINE__);
11170 		return;
11171 	}
11172 	dns_message_currentname(message, DNS_SECTION_QUESTION,
11173 				&client->query.qname);
11174 	client->query.origqname = client->query.qname;
11175 	result = dns_message_nextname(message, DNS_SECTION_QUESTION);
11176 	if (result != ISC_R_NOMORE) {
11177 		if (result == ISC_R_SUCCESS) {
11178 			/*
11179 			 * There's more than one QNAME in the question
11180 			 * section.
11181 			 */
11182 			query_error(client, DNS_R_FORMERR, __LINE__);
11183 		} else {
11184 			query_error(client, result, __LINE__);
11185 		}
11186 		return;
11187 	}
11188 
11189 	if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0) {
11190 		log_query(client, saved_flags, saved_extflags);
11191 	}
11192 
11193 	/*
11194 	 * Check for meta-queries like IXFR and AXFR.
11195 	 */
11196 	rdataset = ISC_LIST_HEAD(client->query.qname->list);
11197 	INSIST(rdataset != NULL);
11198 	client->query.qtype = qtype = rdataset->type;
11199 	dns_rdatatypestats_increment(client->sctx->rcvquerystats, qtype);
11200 
11201 	log_tat(client);
11202 
11203 	if (dns_rdatatype_ismeta(qtype)) {
11204 		switch (qtype) {
11205 		case dns_rdatatype_any:
11206 			break; /* Let the query logic handle it. */
11207 		case dns_rdatatype_ixfr:
11208 		case dns_rdatatype_axfr:
11209 			ns_xfr_start(client, rdataset->type);
11210 			return;
11211 		case dns_rdatatype_maila:
11212 		case dns_rdatatype_mailb:
11213 			query_error(client, DNS_R_NOTIMP, __LINE__);
11214 			return;
11215 		case dns_rdatatype_tkey:
11216 			result = dns_tkey_processquery(
11217 				client->message, client->sctx->tkeyctx,
11218 				client->view->dynamickeys);
11219 			if (result == ISC_R_SUCCESS) {
11220 				query_send(client);
11221 			} else {
11222 				query_error(client, result, __LINE__);
11223 			}
11224 			return;
11225 		default: /* TSIG, etc. */
11226 			query_error(client, DNS_R_FORMERR, __LINE__);
11227 			return;
11228 		}
11229 	}
11230 
11231 	/*
11232 	 * Turn on minimal response for (C)DNSKEY and (C)DS queries.
11233 	 */
11234 	if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds ||
11235 	    qtype == dns_rdatatype_cdnskey || qtype == dns_rdatatype_cds)
11236 	{
11237 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
11238 					     NS_QUERYATTR_NOADDITIONAL);
11239 	}
11240 
11241 	/*
11242 	 * Maybe turn on minimal responses for ANY queries.
11243 	 */
11244 	if (qtype == dns_rdatatype_any && client->view->minimal_any &&
11245 	    !TCP(client)) {
11246 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
11247 					     NS_QUERYATTR_NOADDITIONAL);
11248 	}
11249 
11250 	/*
11251 	 * Turn on minimal responses for EDNS/UDP bufsize 512 queries.
11252 	 */
11253 	if (client->ednsversion >= 0 && client->udpsize <= 512U && !TCP(client))
11254 	{
11255 		client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
11256 					     NS_QUERYATTR_NOADDITIONAL);
11257 	}
11258 
11259 	/*
11260 	 * If the client has requested that DNSSEC checking be disabled,
11261 	 * allow lookups to return pending data and instruct the resolver
11262 	 * to return data before validation has completed.
11263 	 *
11264 	 * We don't need to set DNS_DBFIND_PENDINGOK when validation is
11265 	 * disabled as there will be no pending data.
11266 	 */
11267 	if ((message->flags & DNS_MESSAGEFLAG_CD) != 0 ||
11268 	    qtype == dns_rdatatype_rrsig) {
11269 		client->query.dboptions |= DNS_DBFIND_PENDINGOK;
11270 		client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
11271 	} else if (!client->view->enablevalidation) {
11272 		client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
11273 	}
11274 
11275 	if (client->view->qminimization) {
11276 		client->query.fetchoptions |= DNS_FETCHOPT_QMINIMIZE |
11277 					      DNS_FETCHOPT_QMIN_SKIP_IP6A;
11278 		if (client->view->qmin_strict) {
11279 			client->query.fetchoptions |= DNS_FETCHOPT_QMIN_STRICT;
11280 		} else {
11281 			client->query.fetchoptions |= DNS_FETCHOPT_QMIN_USE_A;
11282 		}
11283 	}
11284 
11285 	/*
11286 	 * Allow glue NS records to be added to the authority section
11287 	 * if the answer is secure.
11288 	 */
11289 	if ((message->flags & DNS_MESSAGEFLAG_CD) != 0) {
11290 		client->query.attributes &= ~NS_QUERYATTR_SECURE;
11291 	}
11292 
11293 	/*
11294 	 * Set NS_CLIENTATTR_WANTAD if the client has set AD in the query.
11295 	 * This allows AD to be returned on queries without DO set.
11296 	 */
11297 	if ((message->flags & DNS_MESSAGEFLAG_AD) != 0) {
11298 		client->attributes |= NS_CLIENTATTR_WANTAD;
11299 	}
11300 
11301 	/*
11302 	 * This is an ordinary query.
11303 	 */
11304 	result = dns_message_reply(message, true);
11305 	if (result != ISC_R_SUCCESS) {
11306 		query_next(client, result);
11307 		return;
11308 	}
11309 
11310 	/*
11311 	 * Assume authoritative response until it is known to be
11312 	 * otherwise.
11313 	 *
11314 	 * If "-T noaa" has been set on the command line don't set
11315 	 * AA on authoritative answers.
11316 	 */
11317 	if ((client->sctx->options & NS_SERVER_NOAA) == 0) {
11318 		message->flags |= DNS_MESSAGEFLAG_AA;
11319 	}
11320 
11321 	/*
11322 	 * Set AD.  We must clear it if we add non-validated data to a
11323 	 * response.
11324 	 */
11325 	if (WANTDNSSEC(client) || WANTAD(client)) {
11326 		message->flags |= DNS_MESSAGEFLAG_AD;
11327 	}
11328 
11329 	(void)query_setup(client, qtype);
11330 }
11331