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