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