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