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