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