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