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