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