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