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