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