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