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