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, ®ion);
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, ®ion);
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, ®ion);
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(¶m->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(¶m->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