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