1 /* $NetBSD: resolver.c,v 1.22 2015/09/03 07:33:34 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /*! \file */ 21 22 #include <config.h> 23 #include <ctype.h> 24 25 #include <isc/counter.h> 26 #include <isc/log.h> 27 #include <isc/platform.h> 28 #include <isc/print.h> 29 #include <isc/string.h> 30 #include <isc/random.h> 31 #include <isc/socket.h> 32 #include <isc/stats.h> 33 #include <isc/task.h> 34 #include <isc/timer.h> 35 #include <isc/util.h> 36 37 #ifdef AES_SIT 38 #include <isc/aes.h> 39 #else 40 #include <isc/hmacsha.h> 41 #endif 42 43 #include <dns/acl.h> 44 #include <dns/adb.h> 45 #include <dns/cache.h> 46 #include <dns/db.h> 47 #include <dns/dispatch.h> 48 #include <dns/ds.h> 49 #include <dns/events.h> 50 #include <dns/forward.h> 51 #include <dns/keytable.h> 52 #include <dns/log.h> 53 #include <dns/message.h> 54 #include <dns/ncache.h> 55 #include <dns/nsec.h> 56 #include <dns/nsec3.h> 57 #include <dns/opcode.h> 58 #include <dns/peer.h> 59 #include <dns/rbt.h> 60 #include <dns/rcode.h> 61 #include <dns/rdata.h> 62 #include <dns/rdataclass.h> 63 #include <dns/rdatalist.h> 64 #include <dns/rdataset.h> 65 #include <dns/rdatastruct.h> 66 #include <dns/rdatatype.h> 67 #include <dns/resolver.h> 68 #include <dns/result.h> 69 #include <dns/rootns.h> 70 #include <dns/stats.h> 71 #include <dns/tsig.h> 72 #include <dns/validator.h> 73 74 #define DNS_RESOLVER_TRACE 75 #ifdef DNS_RESOLVER_TRACE 76 #define RTRACE(m) isc_log_write(dns_lctx, \ 77 DNS_LOGCATEGORY_RESOLVER, \ 78 DNS_LOGMODULE_RESOLVER, \ 79 ISC_LOG_DEBUG(3), \ 80 "res %p: %s", res, (m)) 81 #define RRTRACE(r, m) isc_log_write(dns_lctx, \ 82 DNS_LOGCATEGORY_RESOLVER, \ 83 DNS_LOGMODULE_RESOLVER, \ 84 ISC_LOG_DEBUG(3), \ 85 "res %p: %s", (r), (m)) 86 #define FCTXTRACE(m) isc_log_write(dns_lctx, \ 87 DNS_LOGCATEGORY_RESOLVER, \ 88 DNS_LOGMODULE_RESOLVER, \ 89 ISC_LOG_DEBUG(3), \ 90 "fctx %p(%s): %s", fctx, fctx->info, (m)) 91 #define FCTXTRACE2(m1, m2) \ 92 isc_log_write(dns_lctx, \ 93 DNS_LOGCATEGORY_RESOLVER, \ 94 DNS_LOGMODULE_RESOLVER, \ 95 ISC_LOG_DEBUG(3), \ 96 "fctx %p(%s): %s %s", \ 97 fctx, fctx->info, (m1), (m2)) 98 #define FTRACE(m) isc_log_write(dns_lctx, \ 99 DNS_LOGCATEGORY_RESOLVER, \ 100 DNS_LOGMODULE_RESOLVER, \ 101 ISC_LOG_DEBUG(3), \ 102 "fetch %p (fctx %p(%s)): %s", \ 103 fetch, fetch->private, \ 104 fetch->private->info, (m)) 105 #define QTRACE(m) isc_log_write(dns_lctx, \ 106 DNS_LOGCATEGORY_RESOLVER, \ 107 DNS_LOGMODULE_RESOLVER, \ 108 ISC_LOG_DEBUG(3), \ 109 "resquery %p (fctx %p(%s)): %s", \ 110 query, query->fctx, \ 111 query->fctx->info, (m)) 112 #else 113 #define RTRACE(m) 114 #define RRTRACE(r, m) 115 #define FCTXTRACE(m) 116 #define FCTXTRACE2(m1, m2) 117 #define FTRACE(m) 118 #define QTRACE(m) 119 #endif 120 121 #define US_PER_SEC 1000000U 122 /* 123 * The maximum time we will wait for a single query. 124 */ 125 #define MAX_SINGLE_QUERY_TIMEOUT 9U 126 #define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_SEC) 127 128 /* 129 * We need to allow a individual query time to complete / timeout. 130 */ 131 #define MINIMUM_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1U) 132 133 /* The default time in seconds for the whole query to live. */ 134 #ifndef DEFAULT_QUERY_TIMEOUT 135 #define DEFAULT_QUERY_TIMEOUT MINIMUM_QUERY_TIMEOUT 136 #endif 137 138 #ifndef MAXIMUM_QUERY_TIMEOUT 139 #define MAXIMUM_QUERY_TIMEOUT 30 /* The maximum time in seconds for the whole query to live. */ 140 #endif 141 142 /* The default maximum number of recursions to follow before giving up. */ 143 #ifndef DEFAULT_RECURSION_DEPTH 144 #define DEFAULT_RECURSION_DEPTH 7 145 #endif 146 147 /* The default maximum number of iterative queries to allow before giving up. */ 148 #ifndef DEFAULT_MAX_QUERIES 149 #define DEFAULT_MAX_QUERIES 75 150 #endif 151 152 /*% 153 * Maximum EDNS0 input packet size. 154 */ 155 #define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */ 156 157 /*% 158 * This defines the maximum number of timeouts we will permit before we 159 * disable EDNS0 on the query. 160 */ 161 #define MAX_EDNS0_TIMEOUTS 3 162 163 typedef struct fetchctx fetchctx_t; 164 165 typedef struct query { 166 /* Locked by task event serialization. */ 167 unsigned int magic; 168 fetchctx_t * fctx; 169 isc_mem_t * mctx; 170 dns_dispatchmgr_t * dispatchmgr; 171 dns_dispatch_t * dispatch; 172 isc_boolean_t exclusivesocket; 173 dns_adbaddrinfo_t * addrinfo; 174 isc_socket_t * tcpsocket; 175 isc_time_t start; 176 dns_messageid_t id; 177 dns_dispentry_t * dispentry; 178 ISC_LINK(struct query) link; 179 isc_buffer_t buffer; 180 isc_buffer_t *tsig; 181 dns_tsigkey_t *tsigkey; 182 isc_socketevent_t sendevent; 183 isc_dscp_t dscp; 184 int ednsversion; 185 unsigned int options; 186 unsigned int attributes; 187 unsigned int sends; 188 unsigned int connects; 189 unsigned int udpsize; 190 unsigned char data[512]; 191 } resquery_t; 192 193 struct tried { 194 isc_sockaddr_t addr; 195 unsigned int count; 196 ISC_LINK(struct tried) link; 197 }; 198 199 #define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!') 200 #define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC) 201 202 #define RESQUERY_ATTR_CANCELED 0x02 203 204 #define RESQUERY_CONNECTING(q) ((q)->connects > 0) 205 #define RESQUERY_CANCELED(q) (((q)->attributes & \ 206 RESQUERY_ATTR_CANCELED) != 0) 207 #define RESQUERY_SENDING(q) ((q)->sends > 0) 208 209 typedef enum { 210 fetchstate_init = 0, /*%< Start event has not run yet. */ 211 fetchstate_active, 212 fetchstate_done /*%< FETCHDONE events posted. */ 213 } fetchstate; 214 215 typedef enum { 216 badns_unreachable = 0, 217 badns_response, 218 badns_validation 219 } badnstype_t; 220 221 struct fetchctx { 222 /*% Not locked. */ 223 unsigned int magic; 224 dns_resolver_t * res; 225 dns_name_t name; 226 dns_rdatatype_t type; 227 unsigned int options; 228 unsigned int bucketnum; 229 char * info; 230 isc_mem_t * mctx; 231 232 /*% Locked by appropriate bucket lock. */ 233 fetchstate state; 234 isc_boolean_t want_shutdown; 235 isc_boolean_t cloned; 236 isc_boolean_t spilled; 237 unsigned int references; 238 isc_event_t control_event; 239 ISC_LINK(struct fetchctx) link; 240 ISC_LIST(dns_fetchevent_t) events; 241 /*% Locked by task event serialization. */ 242 dns_name_t domain; 243 dns_rdataset_t nameservers; 244 unsigned int attributes; 245 isc_timer_t * timer; 246 isc_time_t expires; 247 isc_interval_t interval; 248 dns_message_t * qmessage; 249 dns_message_t * rmessage; 250 ISC_LIST(resquery_t) queries; 251 dns_adbfindlist_t finds; 252 dns_adbfind_t * find; 253 dns_adbfindlist_t altfinds; 254 dns_adbfind_t * altfind; 255 dns_adbaddrinfolist_t forwaddrs; 256 dns_adbaddrinfolist_t altaddrs; 257 dns_forwarderlist_t forwarders; 258 dns_fwdpolicy_t fwdpolicy; 259 isc_sockaddrlist_t bad; 260 ISC_LIST(struct tried) edns; 261 ISC_LIST(struct tried) edns512; 262 isc_sockaddrlist_t bad_edns; 263 dns_validator_t * validator; 264 ISC_LIST(dns_validator_t) validators; 265 dns_db_t * cache; 266 dns_adb_t * adb; 267 isc_boolean_t ns_ttl_ok; 268 isc_uint32_t ns_ttl; 269 isc_counter_t * qc; 270 271 /*% 272 * The number of events we're waiting for. 273 */ 274 unsigned int pending; 275 276 /*% 277 * The number of times we've "restarted" the current 278 * nameserver set. This acts as a failsafe to prevent 279 * us from pounding constantly on a particular set of 280 * servers that, for whatever reason, are not giving 281 * us useful responses, but are responding in such a 282 * way that they are not marked "bad". 283 */ 284 unsigned int restarts; 285 286 /*% 287 * The number of timeouts that have occurred since we 288 * last successfully received a response packet. This 289 * is used for EDNS0 black hole detection. 290 */ 291 unsigned int timeouts; 292 293 /*% 294 * Look aside state for DS lookups. 295 */ 296 dns_name_t nsname; 297 dns_fetch_t * nsfetch; 298 dns_rdataset_t nsrrset; 299 300 /*% 301 * Number of queries that reference this context. 302 */ 303 unsigned int nqueries; 304 305 /*% 306 * The reason to print when logging a successful 307 * response to a query. 308 */ 309 const char * reason; 310 311 /*% 312 * Random numbers to use for mixing up server addresses. 313 */ 314 isc_uint32_t rand_buf; 315 isc_uint32_t rand_bits; 316 317 /*% 318 * Fetch-local statistics for detailed logging. 319 */ 320 isc_result_t result; /*%< fetch result */ 321 isc_result_t vresult; /*%< validation result */ 322 int exitline; 323 isc_time_t start; 324 isc_uint64_t duration; 325 isc_boolean_t logged; 326 unsigned int querysent; 327 unsigned int referrals; 328 unsigned int lamecount; 329 unsigned int neterr; 330 unsigned int badresp; 331 unsigned int adberr; 332 unsigned int findfail; 333 unsigned int valfail; 334 isc_boolean_t timeout; 335 dns_adbaddrinfo_t *addrinfo; 336 isc_sockaddr_t *client; 337 unsigned int depth; 338 }; 339 340 #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!') 341 #define VALID_FCTX(fctx) ISC_MAGIC_VALID(fctx, FCTX_MAGIC) 342 343 #define FCTX_ATTR_HAVEANSWER 0x0001 344 #define FCTX_ATTR_GLUING 0x0002 345 #define FCTX_ATTR_ADDRWAIT 0x0004 346 #define FCTX_ATTR_SHUTTINGDOWN 0x0008 347 #define FCTX_ATTR_WANTCACHE 0x0010 348 #define FCTX_ATTR_WANTNCACHE 0x0020 349 #define FCTX_ATTR_NEEDEDNS0 0x0040 350 #define FCTX_ATTR_TRIEDFIND 0x0080 351 #define FCTX_ATTR_TRIEDALT 0x0100 352 353 #define HAVE_ANSWER(f) (((f)->attributes & FCTX_ATTR_HAVEANSWER) != \ 354 0) 355 #define GLUING(f) (((f)->attributes & FCTX_ATTR_GLUING) != \ 356 0) 357 #define ADDRWAIT(f) (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \ 358 0) 359 #define SHUTTINGDOWN(f) (((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \ 360 != 0) 361 #define WANTCACHE(f) (((f)->attributes & FCTX_ATTR_WANTCACHE) != 0) 362 #define WANTNCACHE(f) (((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0) 363 #define NEEDEDNS0(f) (((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0) 364 #define TRIEDFIND(f) (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0) 365 #define TRIEDALT(f) (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0) 366 367 typedef struct { 368 dns_adbaddrinfo_t * addrinfo; 369 fetchctx_t * fctx; 370 } dns_valarg_t; 371 372 struct dns_fetch { 373 unsigned int magic; 374 isc_mem_t * mctx; 375 fetchctx_t * private; 376 }; 377 378 #define DNS_FETCH_MAGIC ISC_MAGIC('F', 't', 'c', 'h') 379 #define DNS_FETCH_VALID(fetch) ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC) 380 381 typedef struct fctxbucket { 382 isc_task_t * task; 383 isc_mutex_t lock; 384 ISC_LIST(fetchctx_t) fctxs; 385 isc_boolean_t exiting; 386 isc_mem_t * mctx; 387 } fctxbucket_t; 388 389 typedef struct alternate { 390 isc_boolean_t isaddress; 391 union { 392 isc_sockaddr_t addr; 393 struct { 394 dns_name_t name; 395 in_port_t port; 396 } _n; 397 } _u; 398 ISC_LINK(struct alternate) link; 399 } alternate_t; 400 401 typedef struct dns_badcache dns_badcache_t; 402 struct dns_badcache { 403 dns_badcache_t * next; 404 dns_rdatatype_t type; 405 isc_time_t expire; 406 unsigned int hashval; 407 dns_name_t name; 408 }; 409 #define DNS_BADCACHE_SIZE 1021 410 #define DNS_BADCACHE_TTL(fctx) \ 411 (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30) 412 413 struct dns_resolver { 414 /* Unlocked. */ 415 unsigned int magic; 416 isc_mem_t * mctx; 417 isc_mutex_t lock; 418 isc_mutex_t nlock; 419 isc_mutex_t primelock; 420 dns_rdataclass_t rdclass; 421 isc_socketmgr_t * socketmgr; 422 isc_timermgr_t * timermgr; 423 isc_taskmgr_t * taskmgr; 424 dns_view_t * view; 425 isc_boolean_t frozen; 426 unsigned int options; 427 dns_dispatchmgr_t * dispatchmgr; 428 dns_dispatchset_t * dispatches4; 429 isc_boolean_t exclusivev4; 430 dns_dispatchset_t * dispatches6; 431 isc_dscp_t querydscp4; 432 isc_dscp_t querydscp6; 433 isc_boolean_t exclusivev6; 434 unsigned int nbuckets; 435 fctxbucket_t * buckets; 436 isc_uint32_t lame_ttl; 437 ISC_LIST(alternate_t) alternates; 438 isc_uint16_t udpsize; 439 #if USE_ALGLOCK 440 isc_rwlock_t alglock; 441 #endif 442 dns_rbt_t * algorithms; 443 dns_rbt_t * digests; 444 #if USE_MBSLOCK 445 isc_rwlock_t mbslock; 446 #endif 447 dns_rbt_t * mustbesecure; 448 unsigned int spillatmax; 449 unsigned int spillatmin; 450 isc_timer_t * spillattimer; 451 isc_boolean_t zero_no_soa_ttl; 452 unsigned int query_timeout; 453 unsigned int maxdepth; 454 unsigned int maxqueries; 455 456 /* Locked by lock. */ 457 unsigned int references; 458 isc_boolean_t exiting; 459 isc_eventlist_t whenshutdown; 460 unsigned int activebuckets; 461 isc_boolean_t priming; 462 unsigned int spillat; /* clients-per-query */ 463 464 /* Bad cache. */ 465 dns_badcache_t ** badcache; 466 unsigned int badcount; 467 unsigned int badhash; 468 unsigned int badsweep; 469 470 /* Locked by primelock. */ 471 dns_fetch_t * primefetch; 472 /* Locked by nlock. */ 473 unsigned int nfctx; 474 }; 475 476 #define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!') 477 #define VALID_RESOLVER(res) ISC_MAGIC_VALID(res, RES_MAGIC) 478 479 /*% 480 * Private addrinfo flags. These must not conflict with DNS_FETCHOPT_NOEDNS0 481 * (0x008) which we also use as an addrinfo flag. 482 */ 483 #define FCTX_ADDRINFO_MARK 0x0001 484 #define FCTX_ADDRINFO_FORWARDER 0x1000 485 #define FCTX_ADDRINFO_TRIED 0x2000 486 #define FCTX_ADDRINFO_EDNSOK 0x4000 487 #define FCTX_ADDRINFO_NOSIT 0x8000 488 489 #define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \ 490 == 0) 491 #define ISFORWARDER(a) (((a)->flags & \ 492 FCTX_ADDRINFO_FORWARDER) != 0) 493 #define TRIED(a) (((a)->flags & \ 494 FCTX_ADDRINFO_TRIED) != 0) 495 #define NOSIT(a) (((a)->flags & \ 496 FCTX_ADDRINFO_NOSIT) != 0) 497 #define EDNSOK(a) (((a)->flags & \ 498 FCTX_ADDRINFO_EDNSOK) != 0) 499 500 501 #define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) 502 #define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) 503 504 static void destroy(dns_resolver_t *res); 505 static void empty_bucket(dns_resolver_t *res); 506 static isc_result_t resquery_send(resquery_t *query); 507 static void resquery_response(isc_task_t *task, isc_event_t *event); 508 static void resquery_connected(isc_task_t *task, isc_event_t *event); 509 static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, 510 isc_boolean_t badcache); 511 static void fctx_destroy(fetchctx_t *fctx); 512 static isc_boolean_t fctx_unlink(fetchctx_t *fctx); 513 static isc_result_t ncache_adderesult(dns_message_t *message, 514 dns_db_t *cache, dns_dbnode_t *node, 515 dns_rdatatype_t covers, 516 isc_stdtime_t now, dns_ttl_t maxttl, 517 isc_boolean_t optout, 518 isc_boolean_t secure, 519 dns_rdataset_t *ardataset, 520 isc_result_t *eresultp); 521 static void validated(isc_task_t *task, isc_event_t *event); 522 static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked); 523 static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, 524 isc_result_t reason, badnstype_t badtype); 525 static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name, 526 dns_rdatatype_t type, 527 dns_name_t **noqname); 528 529 /*% 530 * Increment resolver-related statistics counters. 531 */ 532 static inline void 533 inc_stats(dns_resolver_t *res, isc_statscounter_t counter) { 534 if (res->view->resstats != NULL) 535 isc_stats_increment(res->view->resstats, counter); 536 } 537 538 static inline void 539 dec_stats(dns_resolver_t *res, isc_statscounter_t counter) { 540 if (res->view->resstats != NULL) 541 isc_stats_decrement(res->view->resstats, counter); 542 } 543 544 static isc_result_t 545 valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name, 546 dns_rdatatype_t type, dns_rdataset_t *rdataset, 547 dns_rdataset_t *sigrdataset, unsigned int valoptions, 548 isc_task_t *task) 549 { 550 dns_validator_t *validator = NULL; 551 dns_valarg_t *valarg; 552 isc_result_t result; 553 554 valarg = isc_mem_get(fctx->mctx, sizeof(*valarg)); 555 if (valarg == NULL) 556 return (ISC_R_NOMEMORY); 557 558 valarg->fctx = fctx; 559 valarg->addrinfo = addrinfo; 560 561 if (!ISC_LIST_EMPTY(fctx->validators)) 562 INSIST((valoptions & DNS_VALIDATOR_DEFER) != 0); 563 564 result = dns_validator_create(fctx->res->view, name, type, rdataset, 565 sigrdataset, fctx->rmessage, 566 valoptions, task, validated, valarg, 567 &validator); 568 if (result == ISC_R_SUCCESS) { 569 inc_stats(fctx->res, dns_resstatscounter_val); 570 if ((valoptions & DNS_VALIDATOR_DEFER) == 0) { 571 INSIST(fctx->validator == NULL); 572 fctx->validator = validator; 573 } 574 ISC_LIST_APPEND(fctx->validators, validator, link); 575 } else 576 isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); 577 return (result); 578 } 579 580 static isc_boolean_t 581 rrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) { 582 dns_namereln_t namereln; 583 dns_rdata_rrsig_t rrsig; 584 dns_rdata_t rdata = DNS_RDATA_INIT; 585 int order; 586 isc_result_t result; 587 unsigned int labels; 588 589 for (result = dns_rdataset_first(rdataset); 590 result == ISC_R_SUCCESS; 591 result = dns_rdataset_next(rdataset)) { 592 dns_rdataset_current(rdataset, &rdata); 593 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 594 RUNTIME_CHECK(result == ISC_R_SUCCESS); 595 namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain, 596 &order, &labels); 597 if (namereln == dns_namereln_subdomain) 598 return (ISC_TRUE); 599 dns_rdata_reset(&rdata); 600 } 601 return (ISC_FALSE); 602 } 603 604 static isc_boolean_t 605 fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) { 606 dns_name_t *name; 607 dns_name_t *domain = &fctx->domain; 608 dns_rdataset_t *rdataset; 609 dns_rdatatype_t type; 610 isc_result_t result; 611 isc_boolean_t keep_auth = ISC_FALSE; 612 613 if (message->rcode == dns_rcode_nxdomain) 614 return (ISC_FALSE); 615 616 /* 617 * A DS RRset can appear anywhere in a zone, even for a delegation-only 618 * zone. So a response to an explicit query for this type should be 619 * excluded from delegation-only fixup. 620 * 621 * SOA, NS, and DNSKEY can only exist at a zone apex, so a postive 622 * response to a query for these types can never violate the 623 * delegation-only assumption: if the query name is below a 624 * zone cut, the response should normally be a referral, which should 625 * be accepted; if the query name is below a zone cut but the server 626 * happens to have authority for the zone of the query name, the 627 * response is a (non-referral) answer. But this does not violate 628 * delegation-only because the query name must be in a different zone 629 * due to the "apex-only" nature of these types. Note that if the 630 * remote server happens to have authority for a child zone of a 631 * delegation-only zone, we may still incorrectly "fix" the response 632 * with NXDOMAIN for queries for other types. Unfortunately it's 633 * generally impossible to differentiate this case from violation of 634 * the delegation-only assumption. Once the resolver learns the 635 * correct zone cut, possibly via a separate query for an "apex-only" 636 * type, queries for other types will be resolved correctly. 637 * 638 * A query for type ANY will be accepted if it hits an exceptional 639 * type above in the answer section as it should be from a child 640 * zone. 641 * 642 * Also accept answers with RRSIG records from the child zone. 643 * Direct queries for RRSIG records should not be answered from 644 * the parent zone. 645 */ 646 647 if (message->counts[DNS_SECTION_ANSWER] != 0 && 648 (fctx->type == dns_rdatatype_ns || 649 fctx->type == dns_rdatatype_ds || 650 fctx->type == dns_rdatatype_soa || 651 fctx->type == dns_rdatatype_any || 652 fctx->type == dns_rdatatype_rrsig || 653 fctx->type == dns_rdatatype_dnskey)) { 654 result = dns_message_firstname(message, DNS_SECTION_ANSWER); 655 while (result == ISC_R_SUCCESS) { 656 name = NULL; 657 dns_message_currentname(message, DNS_SECTION_ANSWER, 658 &name); 659 for (rdataset = ISC_LIST_HEAD(name->list); 660 rdataset != NULL; 661 rdataset = ISC_LIST_NEXT(rdataset, link)) { 662 if (!dns_name_equal(name, &fctx->name)) 663 continue; 664 type = rdataset->type; 665 /* 666 * RRsig from child? 667 */ 668 if (type == dns_rdatatype_rrsig && 669 rrsig_fromchildzone(fctx, rdataset)) 670 return (ISC_FALSE); 671 /* 672 * Direct query for apex records or DS. 673 */ 674 if (fctx->type == type && 675 (type == dns_rdatatype_ds || 676 type == dns_rdatatype_ns || 677 type == dns_rdatatype_soa || 678 type == dns_rdatatype_dnskey)) 679 return (ISC_FALSE); 680 /* 681 * Indirect query for apex records or DS. 682 */ 683 if (fctx->type == dns_rdatatype_any && 684 (type == dns_rdatatype_ns || 685 type == dns_rdatatype_ds || 686 type == dns_rdatatype_soa || 687 type == dns_rdatatype_dnskey)) 688 return (ISC_FALSE); 689 } 690 result = dns_message_nextname(message, 691 DNS_SECTION_ANSWER); 692 } 693 } 694 695 /* 696 * A NODATA response to a DS query? 697 */ 698 if (fctx->type == dns_rdatatype_ds && 699 message->counts[DNS_SECTION_ANSWER] == 0) 700 return (ISC_FALSE); 701 702 /* Look for referral or indication of answer from child zone? */ 703 if (message->counts[DNS_SECTION_AUTHORITY] == 0) 704 goto munge; 705 706 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); 707 while (result == ISC_R_SUCCESS) { 708 name = NULL; 709 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); 710 for (rdataset = ISC_LIST_HEAD(name->list); 711 rdataset != NULL; 712 rdataset = ISC_LIST_NEXT(rdataset, link)) { 713 type = rdataset->type; 714 if (type == dns_rdatatype_soa && 715 dns_name_equal(name, domain)) 716 keep_auth = ISC_TRUE; 717 718 if (type != dns_rdatatype_ns && 719 type != dns_rdatatype_soa && 720 type != dns_rdatatype_rrsig) 721 continue; 722 723 if (type == dns_rdatatype_rrsig) { 724 if (rrsig_fromchildzone(fctx, rdataset)) 725 return (ISC_FALSE); 726 else 727 continue; 728 } 729 730 /* NS or SOA records. */ 731 if (dns_name_equal(name, domain)) { 732 /* 733 * If a query for ANY causes a negative 734 * response, we can be sure that this is 735 * an empty node. For other type of queries 736 * we cannot differentiate an empty node 737 * from a node that just doesn't have that 738 * type of record. We only accept the former 739 * case. 740 */ 741 if (message->counts[DNS_SECTION_ANSWER] == 0 && 742 fctx->type == dns_rdatatype_any) 743 return (ISC_FALSE); 744 } else if (dns_name_issubdomain(name, domain)) { 745 /* Referral or answer from child zone. */ 746 return (ISC_FALSE); 747 } 748 } 749 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); 750 } 751 752 munge: 753 message->rcode = dns_rcode_nxdomain; 754 message->counts[DNS_SECTION_ANSWER] = 0; 755 if (!keep_auth) 756 message->counts[DNS_SECTION_AUTHORITY] = 0; 757 message->counts[DNS_SECTION_ADDITIONAL] = 0; 758 return (ISC_TRUE); 759 } 760 761 static inline isc_result_t 762 fctx_starttimer(fetchctx_t *fctx) { 763 /* 764 * Start the lifetime timer for fctx. 765 * 766 * This is also used for stopping the idle timer; in that 767 * case we must purge events already posted to ensure that 768 * no further idle events are delivered. 769 */ 770 return (isc_timer_reset(fctx->timer, isc_timertype_once, 771 &fctx->expires, NULL, ISC_TRUE)); 772 } 773 774 static inline void 775 fctx_stoptimer(fetchctx_t *fctx) { 776 isc_result_t result; 777 778 /* 779 * We don't return a result if resetting the timer to inactive fails 780 * since there's nothing to be done about it. Resetting to inactive 781 * should never fail anyway, since the code as currently written 782 * cannot fail in that case. 783 */ 784 result = isc_timer_reset(fctx->timer, isc_timertype_inactive, 785 NULL, NULL, ISC_TRUE); 786 if (result != ISC_R_SUCCESS) { 787 UNEXPECTED_ERROR(__FILE__, __LINE__, 788 "isc_timer_reset(): %s", 789 isc_result_totext(result)); 790 } 791 } 792 793 794 static inline isc_result_t 795 fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) { 796 /* 797 * Start the idle timer for fctx. The lifetime timer continues 798 * to be in effect. 799 */ 800 return (isc_timer_reset(fctx->timer, isc_timertype_once, 801 &fctx->expires, interval, ISC_FALSE)); 802 } 803 804 /* 805 * Stopping the idle timer is equivalent to calling fctx_starttimer(), but 806 * we use fctx_stopidletimer for readability in the code below. 807 */ 808 #define fctx_stopidletimer fctx_starttimer 809 810 811 static inline void 812 resquery_destroy(resquery_t **queryp) { 813 resquery_t *query; 814 815 REQUIRE(queryp != NULL); 816 query = *queryp; 817 REQUIRE(!ISC_LINK_LINKED(query, link)); 818 819 INSIST(query->tcpsocket == NULL); 820 821 query->fctx->nqueries--; 822 if (SHUTTINGDOWN(query->fctx)) { 823 dns_resolver_t *res = query->fctx->res; 824 if (maybe_destroy(query->fctx, ISC_FALSE)) 825 empty_bucket(res); 826 } 827 query->magic = 0; 828 isc_mem_put(query->mctx, query, sizeof(*query)); 829 *queryp = NULL; 830 } 831 832 static void 833 fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, 834 isc_time_t *finish, isc_boolean_t no_response) 835 { 836 fetchctx_t *fctx; 837 resquery_t *query; 838 unsigned int rtt, rttms; 839 unsigned int factor; 840 dns_adbfind_t *find; 841 dns_adbaddrinfo_t *addrinfo; 842 isc_socket_t *socket; 843 isc_stdtime_t now; 844 845 query = *queryp; 846 fctx = query->fctx; 847 848 FCTXTRACE("cancelquery"); 849 850 REQUIRE(!RESQUERY_CANCELED(query)); 851 852 query->attributes |= RESQUERY_ATTR_CANCELED; 853 854 /* 855 * Should we update the RTT? 856 */ 857 if (finish != NULL || no_response) { 858 if (finish != NULL) { 859 /* 860 * We have both the start and finish times for this 861 * packet, so we can compute a real RTT. 862 */ 863 rtt = (unsigned int)isc_time_microdiff(finish, 864 &query->start); 865 factor = DNS_ADB_RTTADJDEFAULT; 866 867 rttms = rtt / 1000; 868 if (rttms < DNS_RESOLVER_QRYRTTCLASS0) { 869 inc_stats(fctx->res, 870 dns_resstatscounter_queryrtt0); 871 } else if (rttms < DNS_RESOLVER_QRYRTTCLASS1) { 872 inc_stats(fctx->res, 873 dns_resstatscounter_queryrtt1); 874 } else if (rttms < DNS_RESOLVER_QRYRTTCLASS2) { 875 inc_stats(fctx->res, 876 dns_resstatscounter_queryrtt2); 877 } else if (rttms < DNS_RESOLVER_QRYRTTCLASS3) { 878 inc_stats(fctx->res, 879 dns_resstatscounter_queryrtt3); 880 } else if (rttms < DNS_RESOLVER_QRYRTTCLASS4) { 881 inc_stats(fctx->res, 882 dns_resstatscounter_queryrtt4); 883 } else { 884 inc_stats(fctx->res, 885 dns_resstatscounter_queryrtt5); 886 } 887 } else { 888 isc_uint32_t value; 889 isc_uint32_t mask; 890 /* 891 * We don't have an RTT for this query. Maybe the 892 * packet was lost, or maybe this server is very 893 * slow. We don't know. Increase the RTT. 894 */ 895 INSIST(no_response); 896 isc_random_get(&value); 897 if (query->addrinfo->srtt > 800000) 898 mask = 0x3fff; 899 else if (query->addrinfo->srtt > 400000) 900 mask = 0x7fff; 901 else if (query->addrinfo->srtt > 200000) 902 mask = 0xffff; 903 else if (query->addrinfo->srtt > 100000) 904 mask = 0x1ffff; 905 else if (query->addrinfo->srtt > 50000) 906 mask = 0x3ffff; 907 else if (query->addrinfo->srtt > 25000) 908 mask = 0x7ffff; 909 else 910 mask = 0xfffff; 911 if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) 912 dns_adb_ednsto(fctx->adb, query->addrinfo, 913 query->udpsize); 914 else 915 dns_adb_timeout(fctx->adb, query->addrinfo); 916 917 /* 918 * Don't adjust timeout on EDNS queries unless we have 919 * seen a EDNS response. 920 */ 921 if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 && 922 !EDNSOK(query->addrinfo)) { 923 mask >>= 2; 924 } 925 rtt = query->addrinfo->srtt + (value & mask); 926 if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US) 927 rtt = MAX_SINGLE_QUERY_TIMEOUT_US; 928 /* 929 * Replace the current RTT with our value. 930 */ 931 factor = DNS_ADB_RTTADJREPLACE; 932 } 933 dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor); 934 } 935 936 /* Remember that the server has been tried. */ 937 if (!TRIED(query->addrinfo)) { 938 dns_adb_changeflags(fctx->adb, query->addrinfo, 939 FCTX_ADDRINFO_TRIED, FCTX_ADDRINFO_TRIED); 940 } 941 942 /* 943 * Age RTTs of servers not tried. 944 */ 945 isc_stdtime_get(&now); 946 if (finish != NULL) 947 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); 948 addrinfo != NULL; 949 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) 950 if (UNMARKED(addrinfo)) 951 dns_adb_agesrtt(fctx->adb, addrinfo, now); 952 953 if (finish != NULL && TRIEDFIND(fctx)) 954 for (find = ISC_LIST_HEAD(fctx->finds); 955 find != NULL; 956 find = ISC_LIST_NEXT(find, publink)) 957 for (addrinfo = ISC_LIST_HEAD(find->list); 958 addrinfo != NULL; 959 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) 960 if (UNMARKED(addrinfo)) 961 dns_adb_agesrtt(fctx->adb, addrinfo, 962 now); 963 964 if (finish != NULL && TRIEDALT(fctx)) { 965 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); 966 addrinfo != NULL; 967 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) 968 if (UNMARKED(addrinfo)) 969 dns_adb_agesrtt(fctx->adb, addrinfo, now); 970 for (find = ISC_LIST_HEAD(fctx->altfinds); 971 find != NULL; 972 find = ISC_LIST_NEXT(find, publink)) 973 for (addrinfo = ISC_LIST_HEAD(find->list); 974 addrinfo != NULL; 975 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) 976 if (UNMARKED(addrinfo)) 977 dns_adb_agesrtt(fctx->adb, addrinfo, 978 now); 979 } 980 981 /* 982 * Check for any outstanding socket events. If they exist, cancel 983 * them and let the event handlers finish the cleanup. The resolver 984 * only needs to worry about managing the connect and send events; 985 * the dispatcher manages the recv events. 986 */ 987 if (RESQUERY_CONNECTING(query)) { 988 /* 989 * Cancel the connect. 990 */ 991 if (query->tcpsocket != NULL) { 992 isc_socket_cancel(query->tcpsocket, NULL, 993 ISC_SOCKCANCEL_CONNECT); 994 } else if (query->dispentry != NULL) { 995 INSIST(query->exclusivesocket); 996 socket = dns_dispatch_getentrysocket(query->dispentry); 997 if (socket != NULL) 998 isc_socket_cancel(socket, NULL, 999 ISC_SOCKCANCEL_CONNECT); 1000 } 1001 } else if (RESQUERY_SENDING(query)) { 1002 /* 1003 * Cancel the pending send. 1004 */ 1005 if (query->exclusivesocket && query->dispentry != NULL) 1006 socket = dns_dispatch_getentrysocket(query->dispentry); 1007 else 1008 socket = dns_dispatch_getsocket(query->dispatch); 1009 if (socket != NULL) 1010 isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND); 1011 } 1012 1013 if (query->dispentry != NULL) 1014 dns_dispatch_removeresponse(&query->dispentry, deventp); 1015 1016 ISC_LIST_UNLINK(fctx->queries, query, link); 1017 1018 if (query->tsig != NULL) 1019 isc_buffer_free(&query->tsig); 1020 1021 if (query->tsigkey != NULL) 1022 dns_tsigkey_detach(&query->tsigkey); 1023 1024 if (query->dispatch != NULL) 1025 dns_dispatch_detach(&query->dispatch); 1026 1027 if (! (RESQUERY_CONNECTING(query) || RESQUERY_SENDING(query))) 1028 /* 1029 * It's safe to destroy the query now. 1030 */ 1031 resquery_destroy(&query); 1032 } 1033 1034 static void 1035 fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) { 1036 resquery_t *query, *next_query; 1037 1038 FCTXTRACE("cancelqueries"); 1039 1040 for (query = ISC_LIST_HEAD(fctx->queries); 1041 query != NULL; 1042 query = next_query) { 1043 next_query = ISC_LIST_NEXT(query, link); 1044 fctx_cancelquery(&query, NULL, NULL, no_response); 1045 } 1046 } 1047 1048 static void 1049 fctx_cleanupfinds(fetchctx_t *fctx) { 1050 dns_adbfind_t *find, *next_find; 1051 1052 REQUIRE(ISC_LIST_EMPTY(fctx->queries)); 1053 1054 for (find = ISC_LIST_HEAD(fctx->finds); 1055 find != NULL; 1056 find = next_find) { 1057 next_find = ISC_LIST_NEXT(find, publink); 1058 ISC_LIST_UNLINK(fctx->finds, find, publink); 1059 dns_adb_destroyfind(&find); 1060 } 1061 fctx->find = NULL; 1062 } 1063 1064 static void 1065 fctx_cleanupaltfinds(fetchctx_t *fctx) { 1066 dns_adbfind_t *find, *next_find; 1067 1068 REQUIRE(ISC_LIST_EMPTY(fctx->queries)); 1069 1070 for (find = ISC_LIST_HEAD(fctx->altfinds); 1071 find != NULL; 1072 find = next_find) { 1073 next_find = ISC_LIST_NEXT(find, publink); 1074 ISC_LIST_UNLINK(fctx->altfinds, find, publink); 1075 dns_adb_destroyfind(&find); 1076 } 1077 fctx->altfind = NULL; 1078 } 1079 1080 static void 1081 fctx_cleanupforwaddrs(fetchctx_t *fctx) { 1082 dns_adbaddrinfo_t *addr, *next_addr; 1083 1084 REQUIRE(ISC_LIST_EMPTY(fctx->queries)); 1085 1086 for (addr = ISC_LIST_HEAD(fctx->forwaddrs); 1087 addr != NULL; 1088 addr = next_addr) { 1089 next_addr = ISC_LIST_NEXT(addr, publink); 1090 ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink); 1091 dns_adb_freeaddrinfo(fctx->adb, &addr); 1092 } 1093 } 1094 1095 static void 1096 fctx_cleanupaltaddrs(fetchctx_t *fctx) { 1097 dns_adbaddrinfo_t *addr, *next_addr; 1098 1099 REQUIRE(ISC_LIST_EMPTY(fctx->queries)); 1100 1101 for (addr = ISC_LIST_HEAD(fctx->altaddrs); 1102 addr != NULL; 1103 addr = next_addr) { 1104 next_addr = ISC_LIST_NEXT(addr, publink); 1105 ISC_LIST_UNLINK(fctx->altaddrs, addr, publink); 1106 dns_adb_freeaddrinfo(fctx->adb, &addr); 1107 } 1108 } 1109 1110 static inline void 1111 fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) { 1112 FCTXTRACE("stopeverything"); 1113 fctx_cancelqueries(fctx, no_response); 1114 fctx_cleanupfinds(fctx); 1115 fctx_cleanupaltfinds(fctx); 1116 fctx_cleanupforwaddrs(fctx); 1117 fctx_cleanupaltaddrs(fctx); 1118 fctx_stoptimer(fctx); 1119 } 1120 1121 static inline void 1122 fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) { 1123 dns_fetchevent_t *event, *next_event; 1124 isc_task_t *task; 1125 unsigned int count = 0; 1126 isc_interval_t i; 1127 isc_boolean_t logit = ISC_FALSE; 1128 isc_time_t now; 1129 unsigned int old_spillat; 1130 unsigned int new_spillat = 0; /* initialized to silence 1131 compiler warnings */ 1132 1133 /* 1134 * Caller must be holding the appropriate bucket lock. 1135 */ 1136 REQUIRE(fctx->state == fetchstate_done); 1137 1138 FCTXTRACE("sendevents"); 1139 1140 /* 1141 * Keep some record of fetch result for logging later (if required). 1142 */ 1143 fctx->result = result; 1144 fctx->exitline = line; 1145 TIME_NOW(&now); 1146 fctx->duration = isc_time_microdiff(&now, &fctx->start); 1147 1148 for (event = ISC_LIST_HEAD(fctx->events); 1149 event != NULL; 1150 event = next_event) { 1151 next_event = ISC_LIST_NEXT(event, ev_link); 1152 ISC_LIST_UNLINK(fctx->events, event, ev_link); 1153 task = event->ev_sender; 1154 event->ev_sender = fctx; 1155 event->vresult = fctx->vresult; 1156 if (!HAVE_ANSWER(fctx)) 1157 event->result = result; 1158 1159 INSIST(result != ISC_R_SUCCESS || 1160 dns_rdataset_isassociated(event->rdataset) || 1161 fctx->type == dns_rdatatype_any || 1162 fctx->type == dns_rdatatype_rrsig || 1163 fctx->type == dns_rdatatype_sig); 1164 1165 /* 1166 * Negative results must be indicated in event->result. 1167 */ 1168 if (dns_rdataset_isassociated(event->rdataset) && 1169 NEGATIVE(event->rdataset)) { 1170 INSIST(event->result == DNS_R_NCACHENXDOMAIN || 1171 event->result == DNS_R_NCACHENXRRSET); 1172 } 1173 1174 isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event)); 1175 count++; 1176 } 1177 1178 if ((fctx->attributes & FCTX_ATTR_HAVEANSWER) != 0 && 1179 fctx->spilled && 1180 (count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) { 1181 LOCK(&fctx->res->lock); 1182 if (count == fctx->res->spillat && !fctx->res->exiting) { 1183 old_spillat = fctx->res->spillat; 1184 fctx->res->spillat += 5; 1185 if (fctx->res->spillat > fctx->res->spillatmax && 1186 fctx->res->spillatmax != 0) 1187 fctx->res->spillat = fctx->res->spillatmax; 1188 new_spillat = fctx->res->spillat; 1189 if (new_spillat != old_spillat) { 1190 logit = ISC_TRUE; 1191 } 1192 isc_interval_set(&i, 20 * 60, 0); 1193 result = isc_timer_reset(fctx->res->spillattimer, 1194 isc_timertype_ticker, NULL, 1195 &i, ISC_TRUE); 1196 RUNTIME_CHECK(result == ISC_R_SUCCESS); 1197 } 1198 UNLOCK(&fctx->res->lock); 1199 if (logit) 1200 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 1201 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, 1202 "clients-per-query increased to %u", 1203 new_spillat); 1204 } 1205 } 1206 1207 static inline void 1208 log_edns(fetchctx_t *fctx) { 1209 char domainbuf[DNS_NAME_FORMATSIZE]; 1210 1211 if (fctx->reason == NULL) 1212 return; 1213 1214 /* 1215 * We do not know if fctx->domain is the actual domain the record 1216 * lives in or a parent domain so we have a '?' after it. 1217 */ 1218 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); 1219 isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED, 1220 DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, 1221 "success resolving '%s' (in '%s'?) after %s", 1222 fctx->info, domainbuf, fctx->reason); 1223 1224 fctx->reason = NULL; 1225 } 1226 1227 static void 1228 fctx_done(fetchctx_t *fctx, isc_result_t result, int line) { 1229 dns_resolver_t *res; 1230 isc_boolean_t no_response; 1231 1232 REQUIRE(line >= 0); 1233 1234 FCTXTRACE("done"); 1235 1236 res = fctx->res; 1237 1238 if (result == ISC_R_SUCCESS) { 1239 /*% 1240 * Log any deferred EDNS timeout messages. 1241 */ 1242 log_edns(fctx); 1243 no_response = ISC_TRUE; 1244 } else 1245 no_response = ISC_FALSE; 1246 1247 fctx->reason = NULL; 1248 fctx_stopeverything(fctx, no_response); 1249 1250 LOCK(&res->buckets[fctx->bucketnum].lock); 1251 1252 fctx->state = fetchstate_done; 1253 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; 1254 fctx_sendevents(fctx, result, line); 1255 1256 UNLOCK(&res->buckets[fctx->bucketnum].lock); 1257 } 1258 1259 static void 1260 process_sendevent(resquery_t *query, isc_event_t *event) { 1261 isc_socketevent_t *sevent = (isc_socketevent_t *)event; 1262 isc_boolean_t retry = ISC_FALSE; 1263 isc_result_t result; 1264 fetchctx_t *fctx; 1265 1266 fctx = query->fctx; 1267 1268 if (RESQUERY_CANCELED(query)) { 1269 if (query->sends == 0 && query->connects == 0) { 1270 /* 1271 * This query was canceled while the 1272 * isc_socket_sendto/connect() was in progress. 1273 */ 1274 if (query->tcpsocket != NULL) 1275 isc_socket_detach(&query->tcpsocket); 1276 resquery_destroy(&query); 1277 } 1278 } else { 1279 switch (sevent->result) { 1280 case ISC_R_SUCCESS: 1281 break; 1282 1283 case ISC_R_HOSTUNREACH: 1284 case ISC_R_NETUNREACH: 1285 case ISC_R_NOPERM: 1286 case ISC_R_ADDRNOTAVAIL: 1287 case ISC_R_CONNREFUSED: 1288 1289 /* 1290 * No route to remote. 1291 */ 1292 add_bad(fctx, query->addrinfo, sevent->result, 1293 badns_unreachable); 1294 fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); 1295 retry = ISC_TRUE; 1296 break; 1297 1298 default: 1299 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); 1300 break; 1301 } 1302 } 1303 1304 if (event->ev_type == ISC_SOCKEVENT_CONNECT) 1305 isc_event_free(&event); 1306 1307 if (retry) { 1308 /* 1309 * Behave as if the idle timer has expired. For TCP 1310 * this may not actually reflect the latest timer. 1311 */ 1312 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; 1313 result = fctx_stopidletimer(fctx); 1314 if (result != ISC_R_SUCCESS) 1315 fctx_done(fctx, result, __LINE__); 1316 else 1317 fctx_try(fctx, ISC_TRUE, ISC_FALSE); 1318 } 1319 } 1320 1321 static void 1322 resquery_udpconnected(isc_task_t *task, isc_event_t *event) { 1323 resquery_t *query = event->ev_arg; 1324 1325 REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); 1326 1327 QTRACE("udpconnected"); 1328 1329 UNUSED(task); 1330 1331 INSIST(RESQUERY_CONNECTING(query)); 1332 1333 query->connects--; 1334 1335 process_sendevent(query, event); 1336 } 1337 1338 static void 1339 resquery_senddone(isc_task_t *task, isc_event_t *event) { 1340 resquery_t *query = event->ev_arg; 1341 1342 REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); 1343 1344 QTRACE("senddone"); 1345 1346 /* 1347 * XXXRTH 1348 * 1349 * Currently we don't wait for the senddone event before retrying 1350 * a query. This means that if we get really behind, we may end 1351 * up doing extra work! 1352 */ 1353 1354 UNUSED(task); 1355 1356 INSIST(RESQUERY_SENDING(query)); 1357 1358 query->sends--; 1359 1360 process_sendevent(query, event); 1361 } 1362 1363 static inline isc_result_t 1364 fctx_addopt(dns_message_t *message, unsigned int version, 1365 isc_uint16_t udpsize, dns_ednsopt_t *ednsopts, size_t count) 1366 { 1367 dns_rdataset_t *rdataset = NULL; 1368 isc_result_t result; 1369 1370 result = dns_message_buildopt(message, &rdataset, version, udpsize, 1371 DNS_MESSAGEEXTFLAG_DO, ednsopts, count); 1372 if (result != ISC_R_SUCCESS) 1373 return (result); 1374 return (dns_message_setopt(message, rdataset)); 1375 } 1376 1377 static inline void 1378 fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) { 1379 unsigned int seconds; 1380 unsigned int us; 1381 1382 /* 1383 * We retry every .8 seconds the first two times through the address 1384 * list, and then we do exponential back-off. 1385 */ 1386 if (fctx->restarts < 3) 1387 us = 800000; 1388 else 1389 us = (800000 << (fctx->restarts - 2)); 1390 1391 /* 1392 * Add a fudge factor to the expected rtt based on the current 1393 * estimate. 1394 */ 1395 if (rtt < 50000) 1396 rtt += 50000; 1397 else if (rtt < 100000) 1398 rtt += 100000; 1399 else 1400 rtt += 200000; 1401 1402 /* 1403 * Always wait for at least the expected rtt. 1404 */ 1405 if (us < rtt) 1406 us = rtt; 1407 1408 /* 1409 * But don't ever wait for more than 10 seconds. 1410 */ 1411 if (us > MAX_SINGLE_QUERY_TIMEOUT_US) 1412 us = MAX_SINGLE_QUERY_TIMEOUT_US; 1413 1414 seconds = us / US_PER_SEC; 1415 us -= seconds * US_PER_SEC; 1416 isc_interval_set(&fctx->interval, seconds, us * 1000); 1417 } 1418 1419 static isc_result_t 1420 fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, 1421 unsigned int options) 1422 { 1423 dns_resolver_t *res; 1424 isc_task_t *task; 1425 isc_result_t result; 1426 resquery_t *query; 1427 isc_sockaddr_t addr; 1428 isc_boolean_t have_addr = ISC_FALSE; 1429 unsigned int srtt; 1430 isc_dscp_t dscp = -1; 1431 1432 FCTXTRACE("query"); 1433 1434 res = fctx->res; 1435 task = res->buckets[fctx->bucketnum].task; 1436 1437 srtt = addrinfo->srtt; 1438 1439 /* 1440 * A forwarder needs to make multiple queries. Give it at least 1441 * a second to do these in. 1442 */ 1443 if (ISFORWARDER(addrinfo) && srtt < 1000000) 1444 srtt = 1000000; 1445 1446 fctx_setretryinterval(fctx, srtt); 1447 result = fctx_startidletimer(fctx, &fctx->interval); 1448 if (result != ISC_R_SUCCESS) 1449 return (result); 1450 1451 INSIST(ISC_LIST_EMPTY(fctx->validators)); 1452 1453 dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE); 1454 1455 query = isc_mem_get(fctx->mctx, sizeof(*query)); 1456 if (query == NULL) { 1457 result = ISC_R_NOMEMORY; 1458 goto stop_idle_timer; 1459 } 1460 query->mctx = fctx->mctx; 1461 query->options = options; 1462 query->attributes = 0; 1463 query->sends = 0; 1464 query->connects = 0; 1465 query->dscp = addrinfo->dscp; 1466 /* 1467 * Note that the caller MUST guarantee that 'addrinfo' will remain 1468 * valid until this query is canceled. 1469 */ 1470 query->addrinfo = addrinfo; 1471 TIME_NOW(&query->start); 1472 1473 /* 1474 * If this is a TCP query, then we need to make a socket and 1475 * a dispatch for it here. Otherwise we use the resolver's 1476 * shared dispatch. 1477 */ 1478 query->dispatchmgr = res->dispatchmgr; 1479 query->dispatch = NULL; 1480 query->exclusivesocket = ISC_FALSE; 1481 query->tcpsocket = NULL; 1482 if (res->view->peers != NULL) { 1483 dns_peer_t *peer = NULL; 1484 isc_netaddr_t dstip; 1485 isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr); 1486 result = dns_peerlist_peerbyaddr(res->view->peers, 1487 &dstip, &peer); 1488 if (result == ISC_R_SUCCESS) { 1489 result = dns_peer_getquerysource(peer, &addr); 1490 if (result == ISC_R_SUCCESS) 1491 have_addr = ISC_TRUE; 1492 result = dns_peer_getquerydscp(peer, &dscp); 1493 if (result == ISC_R_SUCCESS) 1494 query->dscp = dscp; 1495 } 1496 } 1497 1498 dscp = -1; 1499 if ((query->options & DNS_FETCHOPT_TCP) != 0) { 1500 int pf; 1501 1502 pf = isc_sockaddr_pf(&addrinfo->sockaddr); 1503 if (!have_addr) { 1504 switch (pf) { 1505 case PF_INET: 1506 result = dns_dispatch_getlocaladdress( 1507 res->dispatches4->dispatches[0], 1508 &addr); 1509 dscp = dns_resolver_getquerydscp4(fctx->res); 1510 break; 1511 case PF_INET6: 1512 result = dns_dispatch_getlocaladdress( 1513 res->dispatches6->dispatches[0], 1514 &addr); 1515 dscp = dns_resolver_getquerydscp6(fctx->res); 1516 break; 1517 default: 1518 result = ISC_R_NOTIMPLEMENTED; 1519 break; 1520 } 1521 if (result != ISC_R_SUCCESS) 1522 goto cleanup_query; 1523 } 1524 isc_sockaddr_setport(&addr, 0); 1525 if (query->dscp == -1) 1526 query->dscp = dscp; 1527 1528 result = isc_socket_create(res->socketmgr, pf, 1529 isc_sockettype_tcp, 1530 &query->tcpsocket); 1531 if (result != ISC_R_SUCCESS) 1532 goto cleanup_query; 1533 1534 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT 1535 result = isc_socket_bind(query->tcpsocket, &addr, 0); 1536 if (result != ISC_R_SUCCESS) 1537 goto cleanup_socket; 1538 #endif 1539 /* 1540 * A dispatch will be created once the connect succeeds. 1541 */ 1542 } else { 1543 if (have_addr) { 1544 unsigned int attrs, attrmask; 1545 attrs = DNS_DISPATCHATTR_UDP; 1546 switch (isc_sockaddr_pf(&addr)) { 1547 case AF_INET: 1548 attrs |= DNS_DISPATCHATTR_IPV4; 1549 dscp = dns_resolver_getquerydscp4(fctx->res); 1550 break; 1551 case AF_INET6: 1552 attrs |= DNS_DISPATCHATTR_IPV6; 1553 dscp = dns_resolver_getquerydscp6(fctx->res); 1554 break; 1555 default: 1556 result = ISC_R_NOTIMPLEMENTED; 1557 goto cleanup_query; 1558 } 1559 attrmask = DNS_DISPATCHATTR_UDP; 1560 attrmask |= DNS_DISPATCHATTR_TCP; 1561 attrmask |= DNS_DISPATCHATTR_IPV4; 1562 attrmask |= DNS_DISPATCHATTR_IPV6; 1563 result = dns_dispatch_getudp(res->dispatchmgr, 1564 res->socketmgr, 1565 res->taskmgr, &addr, 1566 4096, 20000, 32768, 16411, 1567 16433, attrs, attrmask, 1568 &query->dispatch); 1569 if (result != ISC_R_SUCCESS) 1570 goto cleanup_query; 1571 } else { 1572 switch (isc_sockaddr_pf(&addrinfo->sockaddr)) { 1573 case PF_INET: 1574 dns_dispatch_attach( 1575 dns_resolver_dispatchv4(res), 1576 &query->dispatch); 1577 query->exclusivesocket = res->exclusivev4; 1578 dscp = dns_resolver_getquerydscp4(fctx->res); 1579 break; 1580 case PF_INET6: 1581 dns_dispatch_attach( 1582 dns_resolver_dispatchv6(res), 1583 &query->dispatch); 1584 query->exclusivesocket = res->exclusivev6; 1585 dscp = dns_resolver_getquerydscp6(fctx->res); 1586 break; 1587 default: 1588 result = ISC_R_NOTIMPLEMENTED; 1589 goto cleanup_query; 1590 } 1591 } 1592 1593 if (query->dscp == -1) 1594 query->dscp = dscp; 1595 /* 1596 * We should always have a valid dispatcher here. If we 1597 * don't support a protocol family, then its dispatcher 1598 * will be NULL, but we shouldn't be finding addresses for 1599 * protocol types we don't support, so the dispatcher 1600 * we found should never be NULL. 1601 */ 1602 INSIST(query->dispatch != NULL); 1603 } 1604 1605 query->dispentry = NULL; 1606 query->fctx = fctx; 1607 query->tsig = NULL; 1608 query->tsigkey = NULL; 1609 ISC_LINK_INIT(query, link); 1610 query->magic = QUERY_MAGIC; 1611 1612 if ((query->options & DNS_FETCHOPT_TCP) != 0) { 1613 /* 1614 * Connect to the remote server. 1615 * 1616 * XXXRTH Should we attach to the socket? 1617 */ 1618 if (query->dscp != -1) 1619 isc_socket_dscp(query->tcpsocket, query->dscp); 1620 result = isc_socket_connect(query->tcpsocket, 1621 &addrinfo->sockaddr, task, 1622 resquery_connected, query); 1623 if (result != ISC_R_SUCCESS) 1624 goto cleanup_socket; 1625 query->connects++; 1626 QTRACE("connecting via TCP"); 1627 } else { 1628 result = resquery_send(query); 1629 if (result != ISC_R_SUCCESS) 1630 goto cleanup_dispatch; 1631 } 1632 1633 fctx->querysent++; 1634 1635 ISC_LIST_APPEND(fctx->queries, query, link); 1636 query->fctx->nqueries++; 1637 if (isc_sockaddr_pf(&addrinfo->sockaddr) == PF_INET) 1638 inc_stats(res, dns_resstatscounter_queryv4); 1639 else 1640 inc_stats(res, dns_resstatscounter_queryv6); 1641 if (res->view->resquerystats != NULL) 1642 dns_rdatatypestats_increment(res->view->resquerystats, 1643 fctx->type); 1644 1645 return (ISC_R_SUCCESS); 1646 1647 cleanup_socket: 1648 isc_socket_detach(&query->tcpsocket); 1649 1650 cleanup_dispatch: 1651 if (query->dispatch != NULL) 1652 dns_dispatch_detach(&query->dispatch); 1653 1654 cleanup_query: 1655 if (query->connects == 0) { 1656 query->magic = 0; 1657 isc_mem_put(fctx->mctx, query, sizeof(*query)); 1658 } 1659 1660 stop_idle_timer: 1661 RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS); 1662 1663 return (result); 1664 } 1665 1666 static isc_boolean_t 1667 bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { 1668 isc_sockaddr_t *sa; 1669 1670 for (sa = ISC_LIST_HEAD(fctx->bad_edns); 1671 sa != NULL; 1672 sa = ISC_LIST_NEXT(sa, link)) { 1673 if (isc_sockaddr_equal(sa, address)) 1674 return (ISC_TRUE); 1675 } 1676 1677 return (ISC_FALSE); 1678 } 1679 1680 static void 1681 add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { 1682 isc_sockaddr_t *sa; 1683 1684 if (bad_edns(fctx, address)) 1685 return; 1686 1687 sa = isc_mem_get(fctx->mctx, sizeof(*sa)); 1688 if (sa == NULL) 1689 return; 1690 1691 *sa = *address; 1692 ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link); 1693 } 1694 1695 static struct tried * 1696 triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { 1697 struct tried *tried; 1698 1699 for (tried = ISC_LIST_HEAD(fctx->edns); 1700 tried != NULL; 1701 tried = ISC_LIST_NEXT(tried, link)) { 1702 if (isc_sockaddr_equal(&tried->addr, address)) 1703 return (tried); 1704 } 1705 1706 return (NULL); 1707 } 1708 1709 static void 1710 add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { 1711 struct tried *tried; 1712 1713 tried = triededns(fctx, address); 1714 if (tried != NULL) { 1715 tried->count++; 1716 return; 1717 } 1718 1719 tried = isc_mem_get(fctx->mctx, sizeof(*tried)); 1720 if (tried == NULL) 1721 return; 1722 1723 tried->addr = *address; 1724 tried->count = 1; 1725 ISC_LIST_INITANDAPPEND(fctx->edns, tried, link); 1726 } 1727 1728 static struct tried * 1729 triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { 1730 struct tried *tried; 1731 1732 for (tried = ISC_LIST_HEAD(fctx->edns512); 1733 tried != NULL; 1734 tried = ISC_LIST_NEXT(tried, link)) { 1735 if (isc_sockaddr_equal(&tried->addr, address)) 1736 return (tried); 1737 } 1738 1739 return (NULL); 1740 } 1741 1742 static void 1743 add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { 1744 struct tried *tried; 1745 1746 tried = triededns512(fctx, address); 1747 if (tried != NULL) { 1748 tried->count++; 1749 return; 1750 } 1751 1752 tried = isc_mem_get(fctx->mctx, sizeof(*tried)); 1753 if (tried == NULL) 1754 return; 1755 1756 tried->addr = *address; 1757 tried->count = 1; 1758 ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link); 1759 } 1760 1761 #ifdef ISC_PLATFORM_USESIT 1762 static void 1763 compute_cc(resquery_t *query, unsigned char *sit, size_t len) { 1764 #ifdef AES_SIT 1765 unsigned char digest[ISC_AES_BLOCK_LENGTH]; 1766 unsigned char input[16]; 1767 isc_netaddr_t netaddr; 1768 unsigned int i; 1769 1770 INSIST(len >= 8U); 1771 1772 isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); 1773 switch (netaddr.family) { 1774 case AF_INET: 1775 memmove(input, (unsigned char *)&netaddr.type.in, 4); 1776 memset(input + 4, 0, 12); 1777 break; 1778 case AF_INET6: 1779 memmove(input, (unsigned char *)&netaddr.type.in6, 16); 1780 break; 1781 } 1782 isc_aes128_crypt(query->fctx->res->view->secret, input, digest); 1783 for (i = 0; i < 8; i++) 1784 digest[i] ^= digest[i + 8]; 1785 memmove(sit, digest, 8); 1786 #endif 1787 #ifdef HMAC_SHA1_SIT 1788 unsigned char digest[ISC_SHA1_DIGESTLENGTH]; 1789 isc_netaddr_t netaddr; 1790 isc_hmacsha1_t hmacsha1; 1791 1792 INSIST(len >= 8U); 1793 1794 isc_hmacsha1_init(&hmacsha1, query->fctx->res->view->secret, 1795 ISC_SHA1_DIGESTLENGTH); 1796 isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); 1797 switch (netaddr.family) { 1798 case AF_INET: 1799 isc_hmacsha1_update(&hmacsha1, 1800 (unsigned char *)&netaddr.type.in, 4); 1801 break; 1802 case AF_INET6: 1803 isc_hmacsha1_update(&hmacsha1, 1804 (unsigned char *)&netaddr.type.in6, 16); 1805 break; 1806 } 1807 isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest)); 1808 memmove(sit, digest, 8); 1809 isc_hmacsha1_invalidate(&hmacsha1); 1810 #endif 1811 #ifdef HMAC_SHA256_SIT 1812 unsigned char digest[ISC_SHA256_DIGESTLENGTH]; 1813 isc_netaddr_t netaddr; 1814 isc_hmacsha256_t hmacsha256; 1815 1816 INSIST(len >= 8U); 1817 1818 isc_hmacsha256_init(&hmacsha256, query->fctx->res->view->secret, 1819 ISC_SHA256_DIGESTLENGTH); 1820 isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); 1821 switch (netaddr.family) { 1822 case AF_INET: 1823 isc_hmacsha256_update(&hmacsha256, 1824 (unsigned char *)&netaddr.type.in, 4); 1825 break; 1826 case AF_INET6: 1827 isc_hmacsha256_update(&hmacsha256, 1828 (unsigned char *)&netaddr.type.in6, 16); 1829 break; 1830 } 1831 isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest)); 1832 memmove(sit, digest, 8); 1833 isc_hmacsha256_invalidate(&hmacsha256); 1834 #endif 1835 } 1836 #endif 1837 1838 static isc_boolean_t 1839 wouldvalidate(fetchctx_t *fctx) { 1840 isc_boolean_t secure_domain; 1841 isc_result_t result; 1842 1843 if (!fctx->res->view->enablevalidation) 1844 return (ISC_FALSE); 1845 1846 if (fctx->res->view->dlv != NULL) 1847 return (ISC_TRUE); 1848 1849 result = dns_view_issecuredomain(fctx->res->view, &fctx->name, 1850 &secure_domain); 1851 if (result != ISC_R_SUCCESS) 1852 return (ISC_FALSE); 1853 return (secure_domain); 1854 } 1855 1856 static isc_result_t 1857 resquery_send(resquery_t *query) { 1858 fetchctx_t *fctx; 1859 isc_result_t result; 1860 dns_name_t *qname = NULL; 1861 dns_rdataset_t *qrdataset = NULL; 1862 isc_region_t r; 1863 dns_resolver_t *res; 1864 isc_task_t *task; 1865 isc_socket_t *socket; 1866 isc_buffer_t tcpbuffer; 1867 isc_sockaddr_t *address; 1868 isc_buffer_t *buffer; 1869 isc_netaddr_t ipaddr; 1870 dns_tsigkey_t *tsigkey = NULL; 1871 dns_peer_t *peer = NULL; 1872 isc_boolean_t useedns; 1873 dns_compress_t cctx; 1874 isc_boolean_t cleanup_cctx = ISC_FALSE; 1875 isc_boolean_t secure_domain; 1876 isc_boolean_t connecting = ISC_FALSE; 1877 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; 1878 unsigned ednsopt = 0; 1879 isc_uint16_t hint = 0, udpsize = 0; /* No EDNS */ 1880 1881 fctx = query->fctx; 1882 QTRACE("send"); 1883 1884 res = fctx->res; 1885 task = res->buckets[fctx->bucketnum].task; 1886 address = NULL; 1887 1888 if ((query->options & DNS_FETCHOPT_TCP) != 0) { 1889 /* 1890 * Reserve space for the TCP message length. 1891 */ 1892 isc_buffer_init(&tcpbuffer, query->data, sizeof(query->data)); 1893 isc_buffer_init(&query->buffer, query->data + 2, 1894 sizeof(query->data) - 2); 1895 buffer = &tcpbuffer; 1896 } else { 1897 isc_buffer_init(&query->buffer, query->data, 1898 sizeof(query->data)); 1899 buffer = &query->buffer; 1900 } 1901 1902 result = dns_message_gettempname(fctx->qmessage, &qname); 1903 if (result != ISC_R_SUCCESS) 1904 goto cleanup_temps; 1905 result = dns_message_gettemprdataset(fctx->qmessage, &qrdataset); 1906 if (result != ISC_R_SUCCESS) 1907 goto cleanup_temps; 1908 1909 /* 1910 * Get a query id from the dispatch. 1911 */ 1912 result = dns_dispatch_addresponse2(query->dispatch, 1913 &query->addrinfo->sockaddr, 1914 task, 1915 resquery_response, 1916 query, 1917 &query->id, 1918 &query->dispentry, 1919 res->socketmgr); 1920 if (result != ISC_R_SUCCESS) 1921 goto cleanup_temps; 1922 1923 fctx->qmessage->opcode = dns_opcode_query; 1924 1925 /* 1926 * Set up question. 1927 */ 1928 dns_name_init(qname, NULL); 1929 dns_name_clone(&fctx->name, qname); 1930 dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type); 1931 ISC_LIST_APPEND(qname->list, qrdataset, link); 1932 dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION); 1933 qname = NULL; 1934 qrdataset = NULL; 1935 1936 /* 1937 * Set RD if the client has requested that we do a recursive query, 1938 * or if we're sending to a forwarder. 1939 */ 1940 if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0 || 1941 ISFORWARDER(query->addrinfo)) 1942 fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD; 1943 1944 /* 1945 * Set CD if the client says not to validate, or if the 1946 * question is under a secure entry point and this is a 1947 * recursive/forward query -- unless the client said not to. 1948 */ 1949 if ((query->options & DNS_FETCHOPT_NOCDFLAG) != 0) 1950 /* Do nothing */ 1951 ; 1952 else if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) 1953 fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; 1954 else if (res->view->enablevalidation && 1955 ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0)) { 1956 result = dns_view_issecuredomain(res->view, &fctx->name, 1957 &secure_domain); 1958 if (result != ISC_R_SUCCESS) 1959 secure_domain = ISC_FALSE; 1960 if (res->view->dlv != NULL) 1961 secure_domain = ISC_TRUE; 1962 if (secure_domain) 1963 fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; 1964 } 1965 1966 /* 1967 * We don't have to set opcode because it defaults to query. 1968 */ 1969 fctx->qmessage->id = query->id; 1970 1971 /* 1972 * Convert the question to wire format. 1973 */ 1974 result = dns_compress_init(&cctx, -1, fctx->res->mctx); 1975 if (result != ISC_R_SUCCESS) 1976 goto cleanup_message; 1977 cleanup_cctx = ISC_TRUE; 1978 1979 result = dns_message_renderbegin(fctx->qmessage, &cctx, 1980 &query->buffer); 1981 if (result != ISC_R_SUCCESS) 1982 goto cleanup_message; 1983 1984 result = dns_message_rendersection(fctx->qmessage, 1985 DNS_SECTION_QUESTION, 0); 1986 if (result != ISC_R_SUCCESS) 1987 goto cleanup_message; 1988 1989 peer = NULL; 1990 isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr); 1991 (void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer); 1992 1993 /* 1994 * The ADB does not know about servers with "edns no". Check this, 1995 * and then inform the ADB for future use. 1996 */ 1997 if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0 && 1998 peer != NULL && 1999 dns_peer_getsupportedns(peer, &useedns) == ISC_R_SUCCESS && 2000 !useedns) 2001 { 2002 query->options |= DNS_FETCHOPT_NOEDNS0; 2003 dns_adb_changeflags(fctx->adb, query->addrinfo, 2004 DNS_FETCHOPT_NOEDNS0, 2005 DNS_FETCHOPT_NOEDNS0); 2006 } 2007 2008 /* Sync NOEDNS0 flag in addrinfo->flags and options now. */ 2009 if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0) 2010 query->options |= DNS_FETCHOPT_NOEDNS0; 2011 2012 /* See if response history indicates that EDNS is not supported. */ 2013 if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 && 2014 dns_adb_noedns(fctx->adb, query->addrinfo)) 2015 query->options |= DNS_FETCHOPT_NOEDNS0; 2016 2017 if (fctx->timeout && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { 2018 isc_sockaddr_t *sockaddr = &query->addrinfo->sockaddr; 2019 struct tried *tried; 2020 2021 if (fctx->timeouts > (MAX_EDNS0_TIMEOUTS * 2) && 2022 (!EDNSOK(query->addrinfo) || !wouldvalidate(fctx))) { 2023 query->options |= DNS_FETCHOPT_NOEDNS0; 2024 fctx->reason = "disabling EDNS"; 2025 } else if ((tried = triededns512(fctx, sockaddr)) != NULL && 2026 tried->count >= 2U && 2027 (!EDNSOK(query->addrinfo) || !wouldvalidate(fctx))) { 2028 query->options |= DNS_FETCHOPT_NOEDNS0; 2029 fctx->reason = "disabling EDNS"; 2030 } else if ((tried = triededns(fctx, sockaddr)) != NULL) { 2031 if (tried->count == 1U) { 2032 hint = dns_adb_getudpsize(fctx->adb, 2033 query->addrinfo); 2034 } else if (tried->count >= 2U) { 2035 query->options |= DNS_FETCHOPT_EDNS512; 2036 fctx->reason = "reducing the advertised EDNS " 2037 "UDP packet size to 512 octets"; 2038 } 2039 } 2040 } 2041 fctx->timeout = ISC_FALSE; 2042 2043 /* 2044 * Use EDNS0, unless the caller doesn't want it, or we know that 2045 * the remote server doesn't like it. 2046 */ 2047 if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { 2048 if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) { 2049 unsigned int version = 0; /* Default version. */ 2050 unsigned int flags = query->addrinfo->flags; 2051 isc_boolean_t reqnsid = res->view->requestnsid; 2052 #ifdef ISC_PLATFORM_USESIT 2053 isc_boolean_t reqsit = res->view->requestsit; 2054 unsigned char sit[64]; 2055 #endif 2056 2057 if ((flags & FCTX_ADDRINFO_EDNSOK) != 0 && 2058 (query->options & DNS_FETCHOPT_EDNS512) == 0) { 2059 udpsize = dns_adb_probesize2(fctx->adb, 2060 query->addrinfo, 2061 fctx->timeouts); 2062 if (udpsize > res->udpsize) 2063 udpsize = res->udpsize; 2064 } 2065 2066 if (peer != NULL) 2067 (void)dns_peer_getudpsize(peer, &udpsize); 2068 2069 if (udpsize == 0U && res->udpsize == 512U) 2070 udpsize = 512; 2071 2072 /* 2073 * Was the size forced to 512 in the configuration? 2074 */ 2075 if (udpsize == 512U) 2076 query->options |= DNS_FETCHOPT_EDNS512; 2077 2078 /* 2079 * We have talked to this server before. 2080 */ 2081 if (hint != 0U) 2082 udpsize = hint; 2083 2084 /* 2085 * We know nothing about the peer's capabilities 2086 * so start with minimal EDNS UDP size. 2087 */ 2088 if (udpsize == 0U) 2089 udpsize = 512; 2090 2091 if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) { 2092 version = flags & DNS_FETCHOPT_EDNSVERSIONMASK; 2093 version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT; 2094 } 2095 2096 /* Request NSID/SIT for current view or peer? */ 2097 if (peer != NULL) { 2098 (void) dns_peer_getrequestnsid(peer, &reqnsid); 2099 #ifdef ISC_PLATFORM_USESIT 2100 (void) dns_peer_getrequestsit(peer, &reqsit); 2101 #endif 2102 } 2103 #ifdef ISC_PLATFORM_USESIT 2104 if (NOSIT(query->addrinfo)) 2105 reqsit = ISC_FALSE; 2106 #endif 2107 if (reqnsid) { 2108 INSIST(ednsopt < DNS_EDNSOPTIONS); 2109 ednsopts[ednsopt].code = DNS_OPT_NSID; 2110 ednsopts[ednsopt].length = 0; 2111 ednsopts[ednsopt].value = NULL; 2112 ednsopt++; 2113 } 2114 #ifdef ISC_PLATFORM_USESIT 2115 if (reqsit) { 2116 INSIST(ednsopt < DNS_EDNSOPTIONS); 2117 ednsopts[ednsopt].code = DNS_OPT_SIT; 2118 ednsopts[ednsopt].length = (isc_uint16_t) 2119 dns_adb_getsit(fctx->adb, 2120 query->addrinfo, 2121 sit, sizeof(sit)); 2122 if (ednsopts[ednsopt].length != 0) { 2123 ednsopts[ednsopt].value = sit; 2124 inc_stats(fctx->res, 2125 dns_resstatscounter_sitout); 2126 } else { 2127 compute_cc(query, sit, sizeof(sit)); 2128 ednsopts[ednsopt].value = sit; 2129 ednsopts[ednsopt].length = 8; 2130 inc_stats(fctx->res, 2131 dns_resstatscounter_sitcc); 2132 } 2133 ednsopt++; 2134 } 2135 #endif 2136 query->ednsversion = version; 2137 result = fctx_addopt(fctx->qmessage, version, 2138 udpsize, ednsopts, ednsopt); 2139 if (reqnsid && result == ISC_R_SUCCESS) { 2140 query->options |= DNS_FETCHOPT_WANTNSID; 2141 } else if (result != ISC_R_SUCCESS) { 2142 /* 2143 * We couldn't add the OPT, but we'll press on. 2144 * We're not using EDNS0, so set the NOEDNS0 2145 * bit. 2146 */ 2147 query->options |= DNS_FETCHOPT_NOEDNS0; 2148 query->ednsversion = -1; 2149 udpsize = 0; 2150 } 2151 } else { 2152 /* 2153 * We know this server doesn't like EDNS0, so we 2154 * won't use it. Set the NOEDNS0 bit since we're 2155 * not using EDNS0. 2156 */ 2157 query->options |= DNS_FETCHOPT_NOEDNS0; 2158 query->ednsversion = -1; 2159 } 2160 } else 2161 query->ednsversion = -1; 2162 2163 /* 2164 * Record the UDP EDNS size choosen. 2165 */ 2166 query->udpsize = udpsize; 2167 2168 /* 2169 * If we need EDNS0 to do this query and aren't using it, we lose. 2170 */ 2171 if (NEEDEDNS0(fctx) && (query->options & DNS_FETCHOPT_NOEDNS0) != 0) { 2172 result = DNS_R_SERVFAIL; 2173 goto cleanup_message; 2174 } 2175 2176 if (udpsize > 512U) 2177 add_triededns(fctx, &query->addrinfo->sockaddr); 2178 2179 if (udpsize == 512U) 2180 add_triededns512(fctx, &query->addrinfo->sockaddr); 2181 2182 /* 2183 * Clear CD if EDNS is not in use. 2184 */ 2185 if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) 2186 fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD; 2187 2188 /* 2189 * Add TSIG record tailored to the current recipient. 2190 */ 2191 result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey); 2192 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 2193 goto cleanup_message; 2194 2195 if (tsigkey != NULL) { 2196 result = dns_message_settsigkey(fctx->qmessage, tsigkey); 2197 dns_tsigkey_detach(&tsigkey); 2198 if (result != ISC_R_SUCCESS) 2199 goto cleanup_message; 2200 } 2201 2202 result = dns_message_rendersection(fctx->qmessage, 2203 DNS_SECTION_ADDITIONAL, 0); 2204 if (result != ISC_R_SUCCESS) 2205 goto cleanup_message; 2206 2207 result = dns_message_renderend(fctx->qmessage); 2208 if (result != ISC_R_SUCCESS) 2209 goto cleanup_message; 2210 2211 dns_compress_invalidate(&cctx); 2212 cleanup_cctx = ISC_FALSE; 2213 2214 if (dns_message_gettsigkey(fctx->qmessage) != NULL) { 2215 dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage), 2216 &query->tsigkey); 2217 result = dns_message_getquerytsig(fctx->qmessage, 2218 fctx->res->mctx, 2219 &query->tsig); 2220 if (result != ISC_R_SUCCESS) 2221 goto cleanup_message; 2222 } 2223 2224 /* 2225 * If using TCP, write the length of the message at the beginning 2226 * of the buffer. 2227 */ 2228 if ((query->options & DNS_FETCHOPT_TCP) != 0) { 2229 isc_buffer_usedregion(&query->buffer, &r); 2230 isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t)r.length); 2231 isc_buffer_add(&tcpbuffer, r.length); 2232 } 2233 2234 /* 2235 * We're now done with the query message. 2236 */ 2237 dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER); 2238 2239 if (query->exclusivesocket) 2240 socket = dns_dispatch_getentrysocket(query->dispentry); 2241 else 2242 socket = dns_dispatch_getsocket(query->dispatch); 2243 /* 2244 * Send the query! 2245 */ 2246 if ((query->options & DNS_FETCHOPT_TCP) == 0) { 2247 address = &query->addrinfo->sockaddr; 2248 if (query->exclusivesocket) { 2249 result = isc_socket_connect(socket, address, task, 2250 resquery_udpconnected, 2251 query); 2252 if (result != ISC_R_SUCCESS) 2253 goto cleanup_message; 2254 connecting = ISC_TRUE; 2255 query->connects++; 2256 } 2257 } 2258 isc_buffer_usedregion(buffer, &r); 2259 2260 /* 2261 * XXXRTH Make sure we don't send to ourselves! We should probably 2262 * prune out these addresses when we get them from the ADB. 2263 */ 2264 memset(&query->sendevent, 0, sizeof(query->sendevent)); 2265 ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL, 2266 ISC_SOCKEVENT_SENDDONE, resquery_senddone, query, 2267 NULL, NULL, NULL); 2268 2269 if (query->dscp == -1) { 2270 query->sendevent.attributes &= ~ISC_SOCKEVENTATTR_DSCP; 2271 query->sendevent.dscp = 0; 2272 } else { 2273 query->sendevent.attributes |= ISC_SOCKEVENTATTR_DSCP; 2274 query->sendevent.dscp = query->dscp; 2275 if ((query->options & DNS_FETCHOPT_TCP) != 0) 2276 isc_socket_dscp(socket, query->dscp); 2277 } 2278 2279 result = isc_socket_sendto2(socket, &r, task, address, NULL, 2280 &query->sendevent, 0); 2281 if (result != ISC_R_SUCCESS) { 2282 if (connecting) { 2283 /* 2284 * This query is still connecting. 2285 * Mark it as canceled so that it will just be 2286 * cleaned up when the connected event is received. 2287 * Keep fctx around until the event is processed. 2288 */ 2289 query->fctx->nqueries++; 2290 query->attributes |= RESQUERY_ATTR_CANCELED; 2291 } 2292 goto cleanup_message; 2293 } 2294 2295 query->sends++; 2296 2297 QTRACE("sent"); 2298 2299 return (ISC_R_SUCCESS); 2300 2301 cleanup_message: 2302 if (cleanup_cctx) 2303 dns_compress_invalidate(&cctx); 2304 2305 dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER); 2306 2307 /* 2308 * Stop the dispatcher from listening. 2309 */ 2310 dns_dispatch_removeresponse(&query->dispentry, NULL); 2311 2312 cleanup_temps: 2313 if (qname != NULL) 2314 dns_message_puttempname(fctx->qmessage, &qname); 2315 if (qrdataset != NULL) 2316 dns_message_puttemprdataset(fctx->qmessage, &qrdataset); 2317 2318 return (result); 2319 } 2320 2321 static void 2322 resquery_connected(isc_task_t *task, isc_event_t *event) { 2323 isc_socketevent_t *sevent = (isc_socketevent_t *)event; 2324 resquery_t *query = event->ev_arg; 2325 isc_boolean_t retry = ISC_FALSE; 2326 isc_interval_t interval; 2327 isc_result_t result; 2328 unsigned int attrs; 2329 fetchctx_t *fctx; 2330 2331 REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); 2332 REQUIRE(VALID_QUERY(query)); 2333 2334 QTRACE("connected"); 2335 2336 UNUSED(task); 2337 2338 /* 2339 * XXXRTH 2340 * 2341 * Currently we don't wait for the connect event before retrying 2342 * a query. This means that if we get really behind, we may end 2343 * up doing extra work! 2344 */ 2345 2346 query->connects--; 2347 fctx = query->fctx; 2348 2349 if (RESQUERY_CANCELED(query)) { 2350 /* 2351 * This query was canceled while the connect() was in 2352 * progress. 2353 */ 2354 isc_socket_detach(&query->tcpsocket); 2355 resquery_destroy(&query); 2356 } else { 2357 switch (sevent->result) { 2358 case ISC_R_SUCCESS: 2359 2360 /* 2361 * Extend the idle timer for TCP. 20 seconds 2362 * should be long enough for a TCP connection to be 2363 * established, a single DNS request to be sent, 2364 * and the response received. 2365 */ 2366 isc_interval_set(&interval, 20, 0); 2367 result = fctx_startidletimer(query->fctx, &interval); 2368 if (result != ISC_R_SUCCESS) { 2369 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); 2370 fctx_done(fctx, result, __LINE__); 2371 break; 2372 } 2373 /* 2374 * We are connected. Create a dispatcher and 2375 * send the query. 2376 */ 2377 attrs = 0; 2378 attrs |= DNS_DISPATCHATTR_TCP; 2379 attrs |= DNS_DISPATCHATTR_PRIVATE; 2380 attrs |= DNS_DISPATCHATTR_CONNECTED; 2381 if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == 2382 AF_INET) 2383 attrs |= DNS_DISPATCHATTR_IPV4; 2384 else 2385 attrs |= DNS_DISPATCHATTR_IPV6; 2386 attrs |= DNS_DISPATCHATTR_MAKEQUERY; 2387 2388 result = dns_dispatch_createtcp(query->dispatchmgr, 2389 query->tcpsocket, 2390 query->fctx->res->taskmgr, 2391 4096, 2, 1, 1, 3, attrs, 2392 &query->dispatch); 2393 2394 /* 2395 * Regardless of whether dns_dispatch_create() 2396 * succeeded or not, we don't need our reference 2397 * to the socket anymore. 2398 */ 2399 isc_socket_detach(&query->tcpsocket); 2400 2401 if (result == ISC_R_SUCCESS) 2402 result = resquery_send(query); 2403 2404 if (result != ISC_R_SUCCESS) { 2405 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); 2406 fctx_done(fctx, result, __LINE__); 2407 } 2408 break; 2409 2410 case ISC_R_NETUNREACH: 2411 case ISC_R_HOSTUNREACH: 2412 case ISC_R_CONNREFUSED: 2413 case ISC_R_NOPERM: 2414 case ISC_R_ADDRNOTAVAIL: 2415 case ISC_R_CONNECTIONRESET: 2416 /* 2417 * No route to remote. 2418 */ 2419 isc_socket_detach(&query->tcpsocket); 2420 fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); 2421 retry = ISC_TRUE; 2422 break; 2423 2424 default: 2425 isc_socket_detach(&query->tcpsocket); 2426 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); 2427 break; 2428 } 2429 } 2430 2431 isc_event_free(&event); 2432 2433 if (retry) { 2434 /* 2435 * Behave as if the idle timer has expired. For TCP 2436 * connections this may not actually reflect the latest timer. 2437 */ 2438 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; 2439 result = fctx_stopidletimer(fctx); 2440 if (result != ISC_R_SUCCESS) 2441 fctx_done(fctx, result, __LINE__); 2442 else 2443 fctx_try(fctx, ISC_TRUE, ISC_FALSE); 2444 } 2445 } 2446 2447 static void 2448 fctx_finddone(isc_task_t *task, isc_event_t *event) { 2449 fetchctx_t *fctx; 2450 dns_adbfind_t *find; 2451 dns_resolver_t *res; 2452 isc_boolean_t want_try = ISC_FALSE; 2453 isc_boolean_t want_done = ISC_FALSE; 2454 isc_boolean_t bucket_empty = ISC_FALSE; 2455 unsigned int bucketnum; 2456 isc_boolean_t destroy = ISC_FALSE; 2457 2458 find = event->ev_sender; 2459 fctx = event->ev_arg; 2460 REQUIRE(VALID_FCTX(fctx)); 2461 res = fctx->res; 2462 2463 UNUSED(task); 2464 2465 FCTXTRACE("finddone"); 2466 2467 bucketnum = fctx->bucketnum; 2468 LOCK(&res->buckets[bucketnum].lock); 2469 2470 INSIST(fctx->pending > 0); 2471 fctx->pending--; 2472 2473 if (ADDRWAIT(fctx)) { 2474 /* 2475 * The fetch is waiting for a name to be found. 2476 */ 2477 INSIST(!SHUTTINGDOWN(fctx)); 2478 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; 2479 if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) { 2480 want_try = ISC_TRUE; 2481 } else { 2482 fctx->findfail++; 2483 if (fctx->pending == 0) { 2484 /* 2485 * We've got nothing else to wait for and don't 2486 * know the answer. There's nothing to do but 2487 * fail the fctx. 2488 */ 2489 want_done = ISC_TRUE; 2490 } 2491 } 2492 } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 && 2493 fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { 2494 2495 if (fctx->references == 0) { 2496 bucket_empty = fctx_unlink(fctx); 2497 destroy = ISC_TRUE; 2498 } 2499 } 2500 UNLOCK(&res->buckets[bucketnum].lock); 2501 2502 isc_event_free(&event); 2503 dns_adb_destroyfind(&find); 2504 2505 if (want_try) 2506 fctx_try(fctx, ISC_TRUE, ISC_FALSE); 2507 else if (want_done) 2508 fctx_done(fctx, ISC_R_FAILURE, __LINE__); 2509 else if (destroy) { 2510 fctx_destroy(fctx); 2511 if (bucket_empty) 2512 empty_bucket(res); 2513 } 2514 } 2515 2516 2517 static inline isc_boolean_t 2518 bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) { 2519 isc_sockaddr_t *sa; 2520 2521 for (sa = ISC_LIST_HEAD(fctx->bad); 2522 sa != NULL; 2523 sa = ISC_LIST_NEXT(sa, link)) { 2524 if (isc_sockaddr_equal(sa, address)) 2525 return (ISC_TRUE); 2526 } 2527 2528 return (ISC_FALSE); 2529 } 2530 2531 static inline isc_boolean_t 2532 mark_bad(fetchctx_t *fctx) { 2533 dns_adbfind_t *curr; 2534 dns_adbaddrinfo_t *addrinfo; 2535 isc_boolean_t all_bad = ISC_TRUE; 2536 2537 /* 2538 * Mark all known bad servers, so we don't try to talk to them 2539 * again. 2540 */ 2541 2542 /* 2543 * Mark any bad nameservers. 2544 */ 2545 for (curr = ISC_LIST_HEAD(fctx->finds); 2546 curr != NULL; 2547 curr = ISC_LIST_NEXT(curr, publink)) { 2548 for (addrinfo = ISC_LIST_HEAD(curr->list); 2549 addrinfo != NULL; 2550 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { 2551 if (bad_server(fctx, &addrinfo->sockaddr)) 2552 addrinfo->flags |= FCTX_ADDRINFO_MARK; 2553 else 2554 all_bad = ISC_FALSE; 2555 } 2556 } 2557 2558 /* 2559 * Mark any bad forwarders. 2560 */ 2561 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); 2562 addrinfo != NULL; 2563 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { 2564 if (bad_server(fctx, &addrinfo->sockaddr)) 2565 addrinfo->flags |= FCTX_ADDRINFO_MARK; 2566 else 2567 all_bad = ISC_FALSE; 2568 } 2569 2570 /* 2571 * Mark any bad alternates. 2572 */ 2573 for (curr = ISC_LIST_HEAD(fctx->altfinds); 2574 curr != NULL; 2575 curr = ISC_LIST_NEXT(curr, publink)) { 2576 for (addrinfo = ISC_LIST_HEAD(curr->list); 2577 addrinfo != NULL; 2578 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { 2579 if (bad_server(fctx, &addrinfo->sockaddr)) 2580 addrinfo->flags |= FCTX_ADDRINFO_MARK; 2581 else 2582 all_bad = ISC_FALSE; 2583 } 2584 } 2585 2586 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); 2587 addrinfo != NULL; 2588 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { 2589 if (bad_server(fctx, &addrinfo->sockaddr)) 2590 addrinfo->flags |= FCTX_ADDRINFO_MARK; 2591 else 2592 all_bad = ISC_FALSE; 2593 } 2594 2595 return (all_bad); 2596 } 2597 2598 static void 2599 add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, 2600 badnstype_t badtype) 2601 { 2602 char namebuf[DNS_NAME_FORMATSIZE]; 2603 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 2604 char classbuf[64]; 2605 char typebuf[64]; 2606 char code[64]; 2607 isc_buffer_t b; 2608 isc_sockaddr_t *sa; 2609 const char *spc = ""; 2610 isc_sockaddr_t *address = &addrinfo->sockaddr; 2611 2612 if (reason == DNS_R_LAME) 2613 fctx->lamecount++; 2614 else { 2615 switch (badtype) { 2616 case badns_unreachable: 2617 fctx->neterr++; 2618 break; 2619 case badns_response: 2620 fctx->badresp++; 2621 break; 2622 case badns_validation: 2623 break; /* counted as 'valfail' */ 2624 } 2625 } 2626 2627 if (bad_server(fctx, address)) { 2628 /* 2629 * We already know this server is bad. 2630 */ 2631 return; 2632 } 2633 2634 FCTXTRACE("add_bad"); 2635 2636 sa = isc_mem_get(fctx->mctx, sizeof(*sa)); 2637 if (sa == NULL) 2638 return; 2639 *sa = *address; 2640 ISC_LIST_INITANDAPPEND(fctx->bad, sa, link); 2641 2642 if (reason == DNS_R_LAME) /* already logged */ 2643 return; 2644 2645 if (reason == DNS_R_UNEXPECTEDRCODE && 2646 fctx->rmessage->rcode == dns_rcode_servfail && 2647 ISFORWARDER(addrinfo)) 2648 return; 2649 2650 if (reason == DNS_R_UNEXPECTEDRCODE) { 2651 isc_buffer_init(&b, code, sizeof(code) - 1); 2652 dns_rcode_totext(fctx->rmessage->rcode, &b); 2653 code[isc_buffer_usedlength(&b)] = '\0'; 2654 spc = " "; 2655 } else if (reason == DNS_R_UNEXPECTEDOPCODE) { 2656 isc_buffer_init(&b, code, sizeof(code) - 1); 2657 dns_opcode_totext((dns_opcode_t)fctx->rmessage->opcode, &b); 2658 code[isc_buffer_usedlength(&b)] = '\0'; 2659 spc = " "; 2660 } else { 2661 code[0] = '\0'; 2662 } 2663 dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); 2664 dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf)); 2665 dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf)); 2666 isc_sockaddr_format(address, addrbuf, sizeof(addrbuf)); 2667 isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS, 2668 DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, 2669 "%s%s%s resolving '%s/%s/%s': %s", 2670 code, spc, dns_result_totext(reason), 2671 namebuf, typebuf, classbuf, addrbuf); 2672 } 2673 2674 /* 2675 * Sort addrinfo list by RTT. 2676 */ 2677 static void 2678 sort_adbfind(dns_adbfind_t *find) { 2679 dns_adbaddrinfo_t *best, *curr; 2680 dns_adbaddrinfolist_t sorted; 2681 2682 /* Lame N^2 bubble sort. */ 2683 ISC_LIST_INIT(sorted); 2684 while (!ISC_LIST_EMPTY(find->list)) { 2685 best = ISC_LIST_HEAD(find->list); 2686 curr = ISC_LIST_NEXT(best, publink); 2687 while (curr != NULL) { 2688 if (curr->srtt < best->srtt) 2689 best = curr; 2690 curr = ISC_LIST_NEXT(curr, publink); 2691 } 2692 ISC_LIST_UNLINK(find->list, best, publink); 2693 ISC_LIST_APPEND(sorted, best, publink); 2694 } 2695 find->list = sorted; 2696 } 2697 2698 /* 2699 * Sort a list of finds by server RTT. 2700 */ 2701 static void 2702 sort_finds(dns_adbfindlist_t *findlist) { 2703 dns_adbfind_t *best, *curr; 2704 dns_adbfindlist_t sorted; 2705 dns_adbaddrinfo_t *addrinfo, *bestaddrinfo; 2706 2707 /* Sort each find's addrinfo list by SRTT. */ 2708 for (curr = ISC_LIST_HEAD(*findlist); 2709 curr != NULL; 2710 curr = ISC_LIST_NEXT(curr, publink)) 2711 sort_adbfind(curr); 2712 2713 /* Lame N^2 bubble sort. */ 2714 ISC_LIST_INIT(sorted); 2715 while (!ISC_LIST_EMPTY(*findlist)) { 2716 best = ISC_LIST_HEAD(*findlist); 2717 bestaddrinfo = ISC_LIST_HEAD(best->list); 2718 INSIST(bestaddrinfo != NULL); 2719 curr = ISC_LIST_NEXT(best, publink); 2720 while (curr != NULL) { 2721 addrinfo = ISC_LIST_HEAD(curr->list); 2722 INSIST(addrinfo != NULL); 2723 if (addrinfo->srtt < bestaddrinfo->srtt) { 2724 best = curr; 2725 bestaddrinfo = addrinfo; 2726 } 2727 curr = ISC_LIST_NEXT(curr, publink); 2728 } 2729 ISC_LIST_UNLINK(*findlist, best, publink); 2730 ISC_LIST_APPEND(sorted, best, publink); 2731 } 2732 *findlist = sorted; 2733 } 2734 2735 static void 2736 findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, 2737 unsigned int options, unsigned int flags, isc_stdtime_t now, 2738 isc_boolean_t *need_alternate) 2739 { 2740 dns_adbaddrinfo_t *ai; 2741 dns_adbfind_t *find; 2742 dns_resolver_t *res; 2743 isc_boolean_t unshared; 2744 isc_result_t result; 2745 2746 res = fctx->res; 2747 unshared = ISC_TF((fctx->options & DNS_FETCHOPT_UNSHARED) != 0); 2748 /* 2749 * If this name is a subdomain of the query domain, tell 2750 * the ADB to start looking using zone/hint data. This keeps us 2751 * from getting stuck if the nameserver is beneath the zone cut 2752 * and we don't know its address (e.g. because the A record has 2753 * expired). 2754 */ 2755 if (dns_name_issubdomain(name, &fctx->domain)) 2756 options |= DNS_ADBFIND_STARTATZONE; 2757 options |= DNS_ADBFIND_GLUEOK; 2758 options |= DNS_ADBFIND_HINTOK; 2759 2760 /* 2761 * See what we know about this address. 2762 */ 2763 find = NULL; 2764 result = dns_adb_createfind2(fctx->adb, 2765 res->buckets[fctx->bucketnum].task, 2766 fctx_finddone, fctx, name, 2767 &fctx->name, fctx->type, 2768 options, now, NULL, 2769 res->view->dstport, 2770 fctx->depth + 1, fctx->qc, &find); 2771 if (result != ISC_R_SUCCESS) { 2772 if (result == DNS_R_ALIAS) { 2773 char namebuf[DNS_NAME_FORMATSIZE]; 2774 2775 /* 2776 * XXXRTH Follow the CNAME/DNAME chain? 2777 */ 2778 dns_adb_destroyfind(&find); 2779 fctx->adberr++; 2780 dns_name_format(name, namebuf, sizeof(namebuf)); 2781 isc_log_write(dns_lctx, DNS_LOGCATEGORY_CNAME, 2782 DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, 2783 "skipping nameserver '%s' because it " 2784 "is a CNAME, while resolving '%s'", 2785 namebuf, fctx->info); 2786 } 2787 } else if (!ISC_LIST_EMPTY(find->list)) { 2788 /* 2789 * We have at least some of the addresses for the 2790 * name. 2791 */ 2792 INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0); 2793 if (flags != 0 || port != 0) { 2794 for (ai = ISC_LIST_HEAD(find->list); 2795 ai != NULL; 2796 ai = ISC_LIST_NEXT(ai, publink)) { 2797 ai->flags |= flags; 2798 if (port != 0) 2799 isc_sockaddr_setport(&ai->sockaddr, 2800 port); 2801 } 2802 } 2803 if ((flags & FCTX_ADDRINFO_FORWARDER) != 0) 2804 ISC_LIST_APPEND(fctx->altfinds, find, publink); 2805 else 2806 ISC_LIST_APPEND(fctx->finds, find, publink); 2807 } else { 2808 /* 2809 * We don't know any of the addresses for this 2810 * name. 2811 */ 2812 if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) { 2813 /* 2814 * We're looking for them and will get an 2815 * event about it later. 2816 */ 2817 fctx->pending++; 2818 /* 2819 * Bootstrap. 2820 */ 2821 if (need_alternate != NULL && 2822 !*need_alternate && unshared && 2823 ((res->dispatches4 == NULL && 2824 find->result_v6 != DNS_R_NXDOMAIN) || 2825 (res->dispatches6 == NULL && 2826 find->result_v4 != DNS_R_NXDOMAIN))) 2827 *need_alternate = ISC_TRUE; 2828 } else { 2829 if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0) 2830 fctx->lamecount++; /* cached lame server */ 2831 else 2832 fctx->adberr++; /* unreachable server, etc. */ 2833 2834 /* 2835 * If we know there are no addresses for 2836 * the family we are using then try to add 2837 * an alternative server. 2838 */ 2839 if (need_alternate != NULL && !*need_alternate && 2840 ((res->dispatches4 == NULL && 2841 find->result_v6 == DNS_R_NXRRSET) || 2842 (res->dispatches6 == NULL && 2843 find->result_v4 == DNS_R_NXRRSET))) 2844 *need_alternate = ISC_TRUE; 2845 dns_adb_destroyfind(&find); 2846 } 2847 } 2848 } 2849 2850 static isc_boolean_t 2851 isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) { 2852 int order; 2853 unsigned int nlabels; 2854 dns_namereln_t namereln; 2855 2856 namereln = dns_name_fullcompare(name1, name2, &order, &nlabels); 2857 return (ISC_TF(namereln == dns_namereln_subdomain)); 2858 } 2859 2860 static isc_result_t 2861 fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { 2862 dns_rdata_t rdata = DNS_RDATA_INIT; 2863 isc_result_t result; 2864 dns_resolver_t *res; 2865 isc_stdtime_t now; 2866 unsigned int stdoptions = 0; 2867 dns_forwarder_t *fwd; 2868 dns_adbaddrinfo_t *ai; 2869 isc_boolean_t all_bad; 2870 dns_rdata_ns_t ns; 2871 isc_boolean_t need_alternate = ISC_FALSE; 2872 2873 FCTXTRACE("getaddresses"); 2874 2875 /* 2876 * Don't pound on remote servers. (Failsafe!) 2877 */ 2878 fctx->restarts++; 2879 if (fctx->restarts > 100) { 2880 FCTXTRACE("too many restarts"); 2881 return (DNS_R_SERVFAIL); 2882 } 2883 2884 res = fctx->res; 2885 2886 if (fctx->depth > res->maxdepth) { 2887 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 2888 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), 2889 "too much NS indirection resolving '%s'", 2890 fctx->info); 2891 return (DNS_R_SERVFAIL); 2892 } 2893 2894 /* 2895 * Forwarders. 2896 */ 2897 2898 INSIST(ISC_LIST_EMPTY(fctx->forwaddrs)); 2899 INSIST(ISC_LIST_EMPTY(fctx->altaddrs)); 2900 2901 /* 2902 * If this fctx has forwarders, use them; otherwise use any 2903 * selective forwarders specified in the view; otherwise use the 2904 * resolver's forwarders (if any). 2905 */ 2906 fwd = ISC_LIST_HEAD(fctx->forwarders); 2907 if (fwd == NULL) { 2908 dns_forwarders_t *forwarders = NULL; 2909 dns_name_t *name = &fctx->name; 2910 dns_name_t suffix; 2911 unsigned int labels; 2912 dns_fixedname_t fixed; 2913 dns_name_t *domain; 2914 2915 /* 2916 * DS records are found in the parent server. 2917 * Strip label to get the correct forwarder (if any). 2918 */ 2919 if (dns_rdatatype_atparent(fctx->type) && 2920 dns_name_countlabels(name) > 1) { 2921 dns_name_init(&suffix, NULL); 2922 labels = dns_name_countlabels(name); 2923 dns_name_getlabelsequence(name, 1, labels - 1, &suffix); 2924 name = &suffix; 2925 } 2926 2927 dns_fixedname_init(&fixed); 2928 domain = dns_fixedname_name(&fixed); 2929 result = dns_fwdtable_find2(fctx->res->view->fwdtable, name, 2930 domain, &forwarders); 2931 if (result == ISC_R_SUCCESS) { 2932 fwd = ISC_LIST_HEAD(forwarders->fwdrs); 2933 fctx->fwdpolicy = forwarders->fwdpolicy; 2934 if (fctx->fwdpolicy == dns_fwdpolicy_only && 2935 isstrictsubdomain(domain, &fctx->domain)) { 2936 dns_name_free(&fctx->domain, fctx->mctx); 2937 dns_name_init(&fctx->domain, NULL); 2938 result = dns_name_dup(domain, fctx->mctx, 2939 &fctx->domain); 2940 if (result != ISC_R_SUCCESS) 2941 return (result); 2942 } 2943 } 2944 } 2945 2946 while (fwd != NULL) { 2947 if ((isc_sockaddr_pf(&fwd->addr) == AF_INET && 2948 fctx->res->dispatches4 == NULL) || 2949 (isc_sockaddr_pf(&fwd->addr) == AF_INET6 && 2950 fctx->res->dispatches6 == NULL)) { 2951 fwd = ISC_LIST_NEXT(fwd, link); 2952 continue; 2953 } 2954 ai = NULL; 2955 result = dns_adb_findaddrinfo(fctx->adb, &fwd->addr, &ai, 0); 2956 if (result == ISC_R_SUCCESS) { 2957 dns_adbaddrinfo_t *cur; 2958 ai->flags |= FCTX_ADDRINFO_FORWARDER; 2959 ai->dscp = fwd->dscp; 2960 cur = ISC_LIST_HEAD(fctx->forwaddrs); 2961 while (cur != NULL && cur->srtt < ai->srtt) 2962 cur = ISC_LIST_NEXT(cur, publink); 2963 if (cur != NULL) 2964 ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur, 2965 ai, publink); 2966 else 2967 ISC_LIST_APPEND(fctx->forwaddrs, ai, publink); 2968 } 2969 fwd = ISC_LIST_NEXT(fwd, link); 2970 } 2971 2972 /* 2973 * If the forwarding policy is "only", we don't need the addresses 2974 * of the nameservers. 2975 */ 2976 if (fctx->fwdpolicy == dns_fwdpolicy_only) 2977 goto out; 2978 2979 /* 2980 * Normal nameservers. 2981 */ 2982 2983 stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT; 2984 if (fctx->restarts == 1) { 2985 /* 2986 * To avoid sending out a flood of queries likely to 2987 * result in NXRRSET, we suppress fetches for address 2988 * families we don't have the first time through, 2989 * provided that we have addresses in some family we 2990 * can use. 2991 * 2992 * We don't want to set this option all the time, since 2993 * if fctx->restarts > 1, we've clearly been having trouble 2994 * with the addresses we had, so getting more could help. 2995 */ 2996 stdoptions |= DNS_ADBFIND_AVOIDFETCHES; 2997 } 2998 if (res->dispatches4 != NULL) 2999 stdoptions |= DNS_ADBFIND_INET; 3000 if (res->dispatches6 != NULL) 3001 stdoptions |= DNS_ADBFIND_INET6; 3002 3003 if ((stdoptions & DNS_ADBFIND_ADDRESSMASK) == 0) 3004 return (DNS_R_SERVFAIL); 3005 3006 isc_stdtime_get(&now); 3007 3008 INSIST(ISC_LIST_EMPTY(fctx->finds)); 3009 INSIST(ISC_LIST_EMPTY(fctx->altfinds)); 3010 3011 for (result = dns_rdataset_first(&fctx->nameservers); 3012 result == ISC_R_SUCCESS; 3013 result = dns_rdataset_next(&fctx->nameservers)) 3014 { 3015 dns_rdataset_current(&fctx->nameservers, &rdata); 3016 /* 3017 * Extract the name from the NS record. 3018 */ 3019 result = dns_rdata_tostruct(&rdata, &ns, NULL); 3020 if (result != ISC_R_SUCCESS) 3021 continue; 3022 3023 findname(fctx, &ns.name, 0, stdoptions, 0, now, 3024 &need_alternate); 3025 dns_rdata_reset(&rdata); 3026 dns_rdata_freestruct(&ns); 3027 } 3028 if (result != ISC_R_NOMORE) 3029 return (result); 3030 3031 /* 3032 * Do we need to use 6 to 4? 3033 */ 3034 if (need_alternate) { 3035 int family; 3036 alternate_t *a; 3037 family = (res->dispatches6 != NULL) ? AF_INET6 : AF_INET; 3038 for (a = ISC_LIST_HEAD(fctx->res->alternates); 3039 a != NULL; 3040 a = ISC_LIST_NEXT(a, link)) { 3041 if (!a->isaddress) { 3042 findname(fctx, &a->_u._n.name, a->_u._n.port, 3043 stdoptions, FCTX_ADDRINFO_FORWARDER, 3044 now, NULL); 3045 continue; 3046 } 3047 if (isc_sockaddr_pf(&a->_u.addr) != family) 3048 continue; 3049 ai = NULL; 3050 result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr, 3051 &ai, 0); 3052 if (result == ISC_R_SUCCESS) { 3053 dns_adbaddrinfo_t *cur; 3054 ai->flags |= FCTX_ADDRINFO_FORWARDER; 3055 cur = ISC_LIST_HEAD(fctx->altaddrs); 3056 while (cur != NULL && cur->srtt < ai->srtt) 3057 cur = ISC_LIST_NEXT(cur, publink); 3058 if (cur != NULL) 3059 ISC_LIST_INSERTBEFORE(fctx->altaddrs, 3060 cur, ai, publink); 3061 else 3062 ISC_LIST_APPEND(fctx->altaddrs, ai, 3063 publink); 3064 } 3065 } 3066 } 3067 3068 out: 3069 /* 3070 * Mark all known bad servers. 3071 */ 3072 all_bad = mark_bad(fctx); 3073 3074 /* 3075 * How are we doing? 3076 */ 3077 if (all_bad) { 3078 /* 3079 * We've got no addresses. 3080 */ 3081 if (fctx->pending > 0) { 3082 /* 3083 * We're fetching the addresses, but don't have any 3084 * yet. Tell the caller to wait for an answer. 3085 */ 3086 result = DNS_R_WAIT; 3087 } else { 3088 isc_time_t expire; 3089 isc_interval_t i; 3090 /* 3091 * We've lost completely. We don't know any 3092 * addresses, and the ADB has told us it can't get 3093 * them. 3094 */ 3095 FCTXTRACE("no addresses"); 3096 isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0); 3097 result = isc_time_nowplusinterval(&expire, &i); 3098 if (badcache && 3099 (fctx->type == dns_rdatatype_dnskey || 3100 fctx->type == dns_rdatatype_dlv || 3101 fctx->type == dns_rdatatype_ds) && 3102 result == ISC_R_SUCCESS) 3103 dns_resolver_addbadcache(fctx->res, 3104 &fctx->name, 3105 fctx->type, &expire); 3106 result = ISC_R_FAILURE; 3107 } 3108 } else { 3109 /* 3110 * We've found some addresses. We might still be looking 3111 * for more addresses. 3112 */ 3113 sort_finds(&fctx->finds); 3114 sort_finds(&fctx->altfinds); 3115 result = ISC_R_SUCCESS; 3116 } 3117 3118 return (result); 3119 } 3120 3121 static inline void 3122 possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr) { 3123 isc_netaddr_t na; 3124 char buf[ISC_NETADDR_FORMATSIZE]; 3125 isc_sockaddr_t *sa; 3126 isc_boolean_t aborted = ISC_FALSE; 3127 isc_boolean_t bogus; 3128 dns_acl_t *blackhole; 3129 isc_netaddr_t ipaddr; 3130 dns_peer_t *peer = NULL; 3131 dns_resolver_t *res; 3132 const char *msg = NULL; 3133 3134 sa = &addr->sockaddr; 3135 3136 res = fctx->res; 3137 isc_netaddr_fromsockaddr(&ipaddr, sa); 3138 blackhole = dns_dispatchmgr_getblackhole(res->dispatchmgr); 3139 (void) dns_peerlist_peerbyaddr(res->view->peers, &ipaddr, &peer); 3140 3141 if (blackhole != NULL) { 3142 int match; 3143 3144 if (dns_acl_match(&ipaddr, NULL, blackhole, 3145 &res->view->aclenv, 3146 &match, NULL) == ISC_R_SUCCESS && 3147 match > 0) 3148 aborted = ISC_TRUE; 3149 } 3150 3151 if (peer != NULL && 3152 dns_peer_getbogus(peer, &bogus) == ISC_R_SUCCESS && 3153 bogus) 3154 aborted = ISC_TRUE; 3155 3156 if (aborted) { 3157 addr->flags |= FCTX_ADDRINFO_MARK; 3158 msg = "ignoring blackholed / bogus server: "; 3159 } else if (isc_sockaddr_ismulticast(sa)) { 3160 addr->flags |= FCTX_ADDRINFO_MARK; 3161 msg = "ignoring multicast address: "; 3162 } else if (isc_sockaddr_isexperimental(sa)) { 3163 addr->flags |= FCTX_ADDRINFO_MARK; 3164 msg = "ignoring experimental address: "; 3165 } else if (sa->type.sa.sa_family != AF_INET6) { 3166 return; 3167 } else if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) { 3168 addr->flags |= FCTX_ADDRINFO_MARK; 3169 msg = "ignoring IPv6 mapped IPV4 address: "; 3170 } else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) { 3171 addr->flags |= FCTX_ADDRINFO_MARK; 3172 msg = "ignoring IPv6 compatibility IPV4 address: "; 3173 } else 3174 return; 3175 3176 if (!isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) 3177 return; 3178 3179 isc_netaddr_fromsockaddr(&na, sa); 3180 isc_netaddr_format(&na, buf, sizeof(buf)); 3181 FCTXTRACE2(msg, buf); 3182 } 3183 3184 static inline dns_adbaddrinfo_t * 3185 fctx_nextaddress(fetchctx_t *fctx) { 3186 dns_adbfind_t *find, *start; 3187 dns_adbaddrinfo_t *addrinfo; 3188 dns_adbaddrinfo_t *faddrinfo; 3189 3190 /* 3191 * Return the next untried address, if any. 3192 */ 3193 3194 /* 3195 * Find the first unmarked forwarder (if any). 3196 */ 3197 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); 3198 addrinfo != NULL; 3199 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { 3200 if (!UNMARKED(addrinfo)) 3201 continue; 3202 possibly_mark(fctx, addrinfo); 3203 if (UNMARKED(addrinfo)) { 3204 addrinfo->flags |= FCTX_ADDRINFO_MARK; 3205 fctx->find = NULL; 3206 return (addrinfo); 3207 } 3208 } 3209 3210 /* 3211 * No forwarders. Move to the next find. 3212 */ 3213 3214 fctx->attributes |= FCTX_ATTR_TRIEDFIND; 3215 3216 find = fctx->find; 3217 if (find == NULL) 3218 find = ISC_LIST_HEAD(fctx->finds); 3219 else { 3220 find = ISC_LIST_NEXT(find, publink); 3221 if (find == NULL) 3222 find = ISC_LIST_HEAD(fctx->finds); 3223 } 3224 3225 /* 3226 * Find the first unmarked addrinfo. 3227 */ 3228 addrinfo = NULL; 3229 if (find != NULL) { 3230 start = find; 3231 do { 3232 for (addrinfo = ISC_LIST_HEAD(find->list); 3233 addrinfo != NULL; 3234 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { 3235 if (!UNMARKED(addrinfo)) 3236 continue; 3237 possibly_mark(fctx, addrinfo); 3238 if (UNMARKED(addrinfo)) { 3239 addrinfo->flags |= FCTX_ADDRINFO_MARK; 3240 break; 3241 } 3242 } 3243 if (addrinfo != NULL) 3244 break; 3245 find = ISC_LIST_NEXT(find, publink); 3246 if (find == NULL) 3247 find = ISC_LIST_HEAD(fctx->finds); 3248 } while (find != start); 3249 } 3250 3251 fctx->find = find; 3252 if (addrinfo != NULL) 3253 return (addrinfo); 3254 3255 /* 3256 * No nameservers left. Try alternates. 3257 */ 3258 3259 fctx->attributes |= FCTX_ATTR_TRIEDALT; 3260 3261 find = fctx->altfind; 3262 if (find == NULL) 3263 find = ISC_LIST_HEAD(fctx->altfinds); 3264 else { 3265 find = ISC_LIST_NEXT(find, publink); 3266 if (find == NULL) 3267 find = ISC_LIST_HEAD(fctx->altfinds); 3268 } 3269 3270 /* 3271 * Find the first unmarked addrinfo. 3272 */ 3273 addrinfo = NULL; 3274 if (find != NULL) { 3275 start = find; 3276 do { 3277 for (addrinfo = ISC_LIST_HEAD(find->list); 3278 addrinfo != NULL; 3279 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { 3280 if (!UNMARKED(addrinfo)) 3281 continue; 3282 possibly_mark(fctx, addrinfo); 3283 if (UNMARKED(addrinfo)) { 3284 addrinfo->flags |= FCTX_ADDRINFO_MARK; 3285 break; 3286 } 3287 } 3288 if (addrinfo != NULL) 3289 break; 3290 find = ISC_LIST_NEXT(find, publink); 3291 if (find == NULL) 3292 find = ISC_LIST_HEAD(fctx->altfinds); 3293 } while (find != start); 3294 } 3295 3296 faddrinfo = addrinfo; 3297 3298 /* 3299 * See if we have a better alternate server by address. 3300 */ 3301 3302 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); 3303 addrinfo != NULL; 3304 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { 3305 if (!UNMARKED(addrinfo)) 3306 continue; 3307 possibly_mark(fctx, addrinfo); 3308 if (UNMARKED(addrinfo) && 3309 (faddrinfo == NULL || 3310 addrinfo->srtt < faddrinfo->srtt)) { 3311 if (faddrinfo != NULL) 3312 faddrinfo->flags &= ~FCTX_ADDRINFO_MARK; 3313 addrinfo->flags |= FCTX_ADDRINFO_MARK; 3314 break; 3315 } 3316 } 3317 3318 if (addrinfo == NULL) { 3319 addrinfo = faddrinfo; 3320 fctx->altfind = find; 3321 } 3322 3323 return (addrinfo); 3324 } 3325 3326 static void 3327 fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) { 3328 isc_result_t result; 3329 dns_adbaddrinfo_t *addrinfo; 3330 3331 FCTXTRACE("try"); 3332 3333 REQUIRE(!ADDRWAIT(fctx)); 3334 3335 /* We've already exceeded maximum query count */ 3336 if (isc_counter_used(fctx->qc) > fctx->res->maxqueries) { 3337 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 3338 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), 3339 "exceeded max queries resolving '%s'", 3340 fctx->info); 3341 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 3342 return; 3343 } 3344 3345 addrinfo = fctx_nextaddress(fctx); 3346 if (addrinfo == NULL) { 3347 /* 3348 * We have no more addresses. Start over. 3349 */ 3350 fctx_cancelqueries(fctx, ISC_TRUE); 3351 fctx_cleanupfinds(fctx); 3352 fctx_cleanupaltfinds(fctx); 3353 fctx_cleanupforwaddrs(fctx); 3354 fctx_cleanupaltaddrs(fctx); 3355 result = fctx_getaddresses(fctx, badcache); 3356 if (result == DNS_R_WAIT) { 3357 /* 3358 * Sleep waiting for addresses. 3359 */ 3360 FCTXTRACE("addrwait"); 3361 fctx->attributes |= FCTX_ATTR_ADDRWAIT; 3362 return; 3363 } else if (result != ISC_R_SUCCESS) { 3364 /* 3365 * Something bad happened. 3366 */ 3367 fctx_done(fctx, result, __LINE__); 3368 return; 3369 } 3370 3371 addrinfo = fctx_nextaddress(fctx); 3372 /* 3373 * While we may have addresses from the ADB, they 3374 * might be bad ones. In this case, return SERVFAIL. 3375 */ 3376 if (addrinfo == NULL) { 3377 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 3378 return; 3379 } 3380 } 3381 3382 if (dns_name_countlabels(&fctx->domain) > 2) { 3383 result = isc_counter_increment(fctx->qc); 3384 if (result != ISC_R_SUCCESS) { 3385 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 3386 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), 3387 "exceeded max queries resolving '%s'", 3388 fctx->info); 3389 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 3390 return; 3391 } 3392 } 3393 3394 result = fctx_query(fctx, addrinfo, fctx->options); 3395 if (result != ISC_R_SUCCESS) 3396 fctx_done(fctx, result, __LINE__); 3397 else if (retrying) 3398 inc_stats(fctx->res, dns_resstatscounter_retry); 3399 } 3400 3401 static isc_boolean_t 3402 fctx_unlink(fetchctx_t *fctx) { 3403 dns_resolver_t *res; 3404 unsigned int bucketnum; 3405 3406 /* 3407 * Caller must be holding the bucket lock. 3408 */ 3409 3410 REQUIRE(VALID_FCTX(fctx)); 3411 REQUIRE(fctx->state == fetchstate_done || 3412 fctx->state == fetchstate_init); 3413 REQUIRE(ISC_LIST_EMPTY(fctx->events)); 3414 REQUIRE(ISC_LIST_EMPTY(fctx->queries)); 3415 REQUIRE(ISC_LIST_EMPTY(fctx->finds)); 3416 REQUIRE(ISC_LIST_EMPTY(fctx->altfinds)); 3417 REQUIRE(fctx->pending == 0); 3418 REQUIRE(fctx->references == 0); 3419 REQUIRE(ISC_LIST_EMPTY(fctx->validators)); 3420 3421 FCTXTRACE("unlink"); 3422 3423 res = fctx->res; 3424 bucketnum = fctx->bucketnum; 3425 3426 ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link); 3427 3428 LOCK(&res->nlock); 3429 res->nfctx--; 3430 UNLOCK(&res->nlock); 3431 dec_stats(res, dns_resstatscounter_nfetch); 3432 3433 if (res->buckets[bucketnum].exiting && 3434 ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs)) 3435 return (ISC_TRUE); 3436 3437 return (ISC_FALSE); 3438 } 3439 3440 static void 3441 fctx_destroy(fetchctx_t *fctx) { 3442 isc_sockaddr_t *sa, *next_sa; 3443 struct tried *tried; 3444 3445 REQUIRE(VALID_FCTX(fctx)); 3446 REQUIRE(fctx->state == fetchstate_done || 3447 fctx->state == fetchstate_init); 3448 REQUIRE(ISC_LIST_EMPTY(fctx->events)); 3449 REQUIRE(ISC_LIST_EMPTY(fctx->queries)); 3450 REQUIRE(ISC_LIST_EMPTY(fctx->finds)); 3451 REQUIRE(ISC_LIST_EMPTY(fctx->altfinds)); 3452 REQUIRE(fctx->pending == 0); 3453 REQUIRE(fctx->references == 0); 3454 REQUIRE(ISC_LIST_EMPTY(fctx->validators)); 3455 REQUIRE(!ISC_LINK_LINKED(fctx, link)); 3456 3457 FCTXTRACE("destroy"); 3458 3459 /* 3460 * Free bad. 3461 */ 3462 for (sa = ISC_LIST_HEAD(fctx->bad); 3463 sa != NULL; 3464 sa = next_sa) { 3465 next_sa = ISC_LIST_NEXT(sa, link); 3466 ISC_LIST_UNLINK(fctx->bad, sa, link); 3467 isc_mem_put(fctx->mctx, sa, sizeof(*sa)); 3468 } 3469 3470 for (tried = ISC_LIST_HEAD(fctx->edns); 3471 tried != NULL; 3472 tried = ISC_LIST_HEAD(fctx->edns)) { 3473 ISC_LIST_UNLINK(fctx->edns, tried, link); 3474 isc_mem_put(fctx->mctx, tried, sizeof(*tried)); 3475 } 3476 3477 for (tried = ISC_LIST_HEAD(fctx->edns512); 3478 tried != NULL; 3479 tried = ISC_LIST_HEAD(fctx->edns512)) { 3480 ISC_LIST_UNLINK(fctx->edns512, tried, link); 3481 isc_mem_put(fctx->mctx, tried, sizeof(*tried)); 3482 } 3483 3484 for (sa = ISC_LIST_HEAD(fctx->bad_edns); 3485 sa != NULL; 3486 sa = next_sa) { 3487 next_sa = ISC_LIST_NEXT(sa, link); 3488 ISC_LIST_UNLINK(fctx->bad_edns, sa, link); 3489 isc_mem_put(fctx->mctx, sa, sizeof(*sa)); 3490 } 3491 3492 isc_counter_detach(&fctx->qc); 3493 isc_timer_detach(&fctx->timer); 3494 dns_message_destroy(&fctx->rmessage); 3495 dns_message_destroy(&fctx->qmessage); 3496 if (dns_name_countlabels(&fctx->domain) > 0) 3497 dns_name_free(&fctx->domain, fctx->mctx); 3498 if (dns_rdataset_isassociated(&fctx->nameservers)) 3499 dns_rdataset_disassociate(&fctx->nameservers); 3500 dns_name_free(&fctx->name, fctx->mctx); 3501 dns_db_detach(&fctx->cache); 3502 dns_adb_detach(&fctx->adb); 3503 isc_mem_free(fctx->mctx, fctx->info); 3504 isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx)); 3505 } 3506 3507 /* 3508 * Fetch event handlers. 3509 */ 3510 3511 static void 3512 fctx_timeout(isc_task_t *task, isc_event_t *event) { 3513 fetchctx_t *fctx = event->ev_arg; 3514 isc_timerevent_t *tevent = (isc_timerevent_t *)event; 3515 resquery_t *query; 3516 3517 REQUIRE(VALID_FCTX(fctx)); 3518 3519 UNUSED(task); 3520 3521 FCTXTRACE("timeout"); 3522 3523 inc_stats(fctx->res, dns_resstatscounter_querytimeout); 3524 3525 if (event->ev_type == ISC_TIMEREVENT_LIFE) { 3526 fctx->reason = NULL; 3527 fctx_done(fctx, ISC_R_TIMEDOUT, __LINE__); 3528 } else { 3529 isc_result_t result; 3530 3531 fctx->timeouts++; 3532 fctx->timeout = ISC_TRUE; 3533 /* 3534 * We could cancel the running queries here, or we could let 3535 * them keep going. Since we normally use separate sockets for 3536 * different queries, we adopt the former approach to reduce 3537 * the number of open sockets: cancel the oldest query if it 3538 * expired after the query had started (this is usually the 3539 * case but is not always so, depending on the task schedule 3540 * timing). 3541 */ 3542 query = ISC_LIST_HEAD(fctx->queries); 3543 if (query != NULL && 3544 isc_time_compare(&tevent->due, &query->start) >= 0) { 3545 fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); 3546 } 3547 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; 3548 /* 3549 * Our timer has triggered. Reestablish the fctx lifetime 3550 * timer. 3551 */ 3552 result = fctx_starttimer(fctx); 3553 if (result != ISC_R_SUCCESS) 3554 fctx_done(fctx, result, __LINE__); 3555 else 3556 /* 3557 * Keep trying. 3558 */ 3559 fctx_try(fctx, ISC_TRUE, ISC_FALSE); 3560 } 3561 3562 isc_event_free(&event); 3563 } 3564 3565 static void 3566 fctx_shutdown(fetchctx_t *fctx) { 3567 isc_event_t *cevent; 3568 3569 /* 3570 * Start the shutdown process for fctx, if it isn't already underway. 3571 */ 3572 3573 FCTXTRACE("shutdown"); 3574 3575 /* 3576 * The caller must be holding the appropriate bucket lock. 3577 */ 3578 3579 if (fctx->want_shutdown) 3580 return; 3581 3582 fctx->want_shutdown = ISC_TRUE; 3583 3584 /* 3585 * Unless we're still initializing (in which case the 3586 * control event is still outstanding), we need to post 3587 * the control event to tell the fetch we want it to 3588 * exit. 3589 */ 3590 if (fctx->state != fetchstate_init) { 3591 cevent = &fctx->control_event; 3592 isc_task_send(fctx->res->buckets[fctx->bucketnum].task, 3593 &cevent); 3594 } 3595 } 3596 3597 static void 3598 fctx_doshutdown(isc_task_t *task, isc_event_t *event) { 3599 fetchctx_t *fctx = event->ev_arg; 3600 isc_boolean_t bucket_empty = ISC_FALSE; 3601 dns_resolver_t *res; 3602 unsigned int bucketnum; 3603 dns_validator_t *validator; 3604 isc_boolean_t destroy = ISC_FALSE; 3605 3606 REQUIRE(VALID_FCTX(fctx)); 3607 3608 UNUSED(task); 3609 3610 res = fctx->res; 3611 bucketnum = fctx->bucketnum; 3612 3613 FCTXTRACE("doshutdown"); 3614 3615 /* 3616 * An fctx that is shutting down is no longer in ADDRWAIT mode. 3617 */ 3618 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; 3619 3620 /* 3621 * Cancel all pending validators. Note that this must be done 3622 * without the bucket lock held, since that could cause deadlock. 3623 */ 3624 validator = ISC_LIST_HEAD(fctx->validators); 3625 while (validator != NULL) { 3626 dns_validator_cancel(validator); 3627 validator = ISC_LIST_NEXT(validator, link); 3628 } 3629 3630 if (fctx->nsfetch != NULL) 3631 dns_resolver_cancelfetch(fctx->nsfetch); 3632 3633 /* 3634 * Shut down anything that is still running on behalf of this 3635 * fetch. To avoid deadlock with the ADB, we must do this 3636 * before we lock the bucket lock. 3637 */ 3638 fctx_stopeverything(fctx, ISC_FALSE); 3639 3640 LOCK(&res->buckets[bucketnum].lock); 3641 3642 fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN; 3643 3644 INSIST(fctx->state == fetchstate_active || 3645 fctx->state == fetchstate_done); 3646 INSIST(fctx->want_shutdown); 3647 3648 if (fctx->state != fetchstate_done) { 3649 fctx->state = fetchstate_done; 3650 fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__); 3651 } 3652 3653 if (fctx->references == 0 && fctx->pending == 0 && 3654 fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { 3655 bucket_empty = fctx_unlink(fctx); 3656 destroy = ISC_TRUE; 3657 } 3658 3659 UNLOCK(&res->buckets[bucketnum].lock); 3660 3661 if (destroy) { 3662 fctx_destroy(fctx); 3663 if (bucket_empty) 3664 empty_bucket(res); 3665 } 3666 } 3667 3668 static void 3669 fctx_start(isc_task_t *task, isc_event_t *event) { 3670 fetchctx_t *fctx = event->ev_arg; 3671 isc_boolean_t done = ISC_FALSE, bucket_empty = ISC_FALSE; 3672 dns_resolver_t *res; 3673 unsigned int bucketnum; 3674 isc_boolean_t destroy = ISC_FALSE; 3675 3676 REQUIRE(VALID_FCTX(fctx)); 3677 3678 UNUSED(task); 3679 3680 res = fctx->res; 3681 bucketnum = fctx->bucketnum; 3682 3683 FCTXTRACE("start"); 3684 3685 LOCK(&res->buckets[bucketnum].lock); 3686 3687 INSIST(fctx->state == fetchstate_init); 3688 if (fctx->want_shutdown) { 3689 /* 3690 * We haven't started this fctx yet, and we've been requested 3691 * to shut it down. 3692 */ 3693 fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN; 3694 fctx->state = fetchstate_done; 3695 fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__); 3696 /* 3697 * Since we haven't started, we INSIST that we have no 3698 * pending ADB finds and no pending validations. 3699 */ 3700 INSIST(fctx->pending == 0); 3701 INSIST(fctx->nqueries == 0); 3702 INSIST(ISC_LIST_EMPTY(fctx->validators)); 3703 if (fctx->references == 0) { 3704 /* 3705 * It's now safe to destroy this fctx. 3706 */ 3707 bucket_empty = fctx_unlink(fctx); 3708 destroy = ISC_TRUE; 3709 } 3710 done = ISC_TRUE; 3711 } else { 3712 /* 3713 * Normal fctx startup. 3714 */ 3715 fctx->state = fetchstate_active; 3716 /* 3717 * Reset the control event for later use in shutting down 3718 * the fctx. 3719 */ 3720 ISC_EVENT_INIT(event, sizeof(*event), 0, NULL, 3721 DNS_EVENT_FETCHCONTROL, fctx_doshutdown, fctx, 3722 NULL, NULL, NULL); 3723 } 3724 3725 UNLOCK(&res->buckets[bucketnum].lock); 3726 3727 if (!done) { 3728 isc_result_t result; 3729 3730 INSIST(!destroy); 3731 3732 /* 3733 * All is well. Start working on the fetch. 3734 */ 3735 result = fctx_starttimer(fctx); 3736 if (result != ISC_R_SUCCESS) 3737 fctx_done(fctx, result, __LINE__); 3738 else 3739 fctx_try(fctx, ISC_FALSE, ISC_FALSE); 3740 } else if (destroy) { 3741 fctx_destroy(fctx); 3742 if (bucket_empty) 3743 empty_bucket(res); 3744 } 3745 } 3746 3747 /* 3748 * Fetch Creation, Joining, and Cancelation. 3749 */ 3750 3751 static inline isc_result_t 3752 fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client, 3753 dns_messageid_t id, isc_taskaction_t action, void *arg, 3754 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 3755 dns_fetch_t *fetch) 3756 { 3757 isc_task_t *clone; 3758 dns_fetchevent_t *event; 3759 3760 FCTXTRACE("join"); 3761 3762 /* 3763 * We store the task we're going to send this event to in the 3764 * sender field. We'll make the fetch the sender when we actually 3765 * send the event. 3766 */ 3767 clone = NULL; 3768 isc_task_attach(task, &clone); 3769 event = (dns_fetchevent_t *) 3770 isc_event_allocate(fctx->res->mctx, clone, DNS_EVENT_FETCHDONE, 3771 action, arg, sizeof(*event)); 3772 if (event == NULL) { 3773 isc_task_detach(&clone); 3774 return (ISC_R_NOMEMORY); 3775 } 3776 event->result = DNS_R_SERVFAIL; 3777 event->qtype = fctx->type; 3778 event->db = NULL; 3779 event->node = NULL; 3780 event->rdataset = rdataset; 3781 event->sigrdataset = sigrdataset; 3782 event->fetch = fetch; 3783 event->client = client; 3784 event->id = id; 3785 dns_fixedname_init(&event->foundname); 3786 3787 /* 3788 * Make sure that we can store the sigrdataset in the 3789 * first event if it is needed by any of the events. 3790 */ 3791 if (event->sigrdataset != NULL) 3792 ISC_LIST_PREPEND(fctx->events, event, ev_link); 3793 else 3794 ISC_LIST_APPEND(fctx->events, event, ev_link); 3795 fctx->references++; 3796 fctx->client = client; 3797 3798 fetch->magic = DNS_FETCH_MAGIC; 3799 fetch->private = fctx; 3800 3801 return (ISC_R_SUCCESS); 3802 } 3803 3804 static inline void 3805 log_ns_ttl(fetchctx_t *fctx, const char *where) { 3806 char namebuf[DNS_NAME_FORMATSIZE]; 3807 char domainbuf[DNS_NAME_FORMATSIZE]; 3808 3809 dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); 3810 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); 3811 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 3812 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10), 3813 "log_ns_ttl: fctx %p: %s: %s (in '%s'?): %u %u", 3814 fctx, where, namebuf, domainbuf, 3815 fctx->ns_ttl_ok, fctx->ns_ttl); 3816 } 3817 3818 static isc_result_t 3819 fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, 3820 dns_name_t *domain, dns_rdataset_t *nameservers, 3821 unsigned int options, unsigned int bucketnum, unsigned int depth, 3822 isc_counter_t *qc, fetchctx_t **fctxp) 3823 { 3824 fetchctx_t *fctx; 3825 isc_result_t result; 3826 isc_result_t iresult; 3827 isc_interval_t interval; 3828 dns_fixedname_t fixed; 3829 unsigned int findoptions = 0; 3830 char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE]; 3831 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 3832 dns_name_t suffix; 3833 isc_mem_t *mctx; 3834 3835 /* 3836 * Caller must be holding the lock for bucket number 'bucketnum'. 3837 */ 3838 REQUIRE(fctxp != NULL && *fctxp == NULL); 3839 3840 mctx = res->buckets[bucketnum].mctx; 3841 fctx = isc_mem_get(mctx, sizeof(*fctx)); 3842 if (fctx == NULL) 3843 return (ISC_R_NOMEMORY); 3844 3845 fctx->qc = NULL; 3846 if (qc != NULL) { 3847 isc_counter_attach(qc, &fctx->qc); 3848 } else { 3849 result = isc_counter_create(res->mctx, 3850 res->maxqueries, &fctx->qc); 3851 if (result != ISC_R_SUCCESS) 3852 goto cleanup_fetch; 3853 } 3854 3855 /* 3856 * Make fctx->info point to a copy of a formatted string 3857 * "name/type". 3858 */ 3859 dns_name_format(name, buf, sizeof(buf)); 3860 dns_rdatatype_format(type, typebuf, sizeof(typebuf)); 3861 strcat(buf, "/"); /* checked */ 3862 strcat(buf, typebuf); /* checked */ 3863 fctx->info = isc_mem_strdup(mctx, buf); 3864 if (fctx->info == NULL) { 3865 result = ISC_R_NOMEMORY; 3866 goto cleanup_counter; 3867 } 3868 FCTXTRACE("create"); 3869 dns_name_init(&fctx->name, NULL); 3870 result = dns_name_dup(name, mctx, &fctx->name); 3871 if (result != ISC_R_SUCCESS) 3872 goto cleanup_info; 3873 dns_name_init(&fctx->domain, NULL); 3874 dns_rdataset_init(&fctx->nameservers); 3875 3876 fctx->type = type; 3877 fctx->options = options; 3878 /* 3879 * Note! We do not attach to the task. We are relying on the 3880 * resolver to ensure that this task doesn't go away while we are 3881 * using it. 3882 */ 3883 fctx->res = res; 3884 fctx->references = 0; 3885 fctx->bucketnum = bucketnum; 3886 fctx->state = fetchstate_init; 3887 fctx->want_shutdown = ISC_FALSE; 3888 fctx->cloned = ISC_FALSE; 3889 fctx->depth = depth; 3890 ISC_LIST_INIT(fctx->queries); 3891 ISC_LIST_INIT(fctx->finds); 3892 ISC_LIST_INIT(fctx->altfinds); 3893 ISC_LIST_INIT(fctx->forwaddrs); 3894 ISC_LIST_INIT(fctx->altaddrs); 3895 ISC_LIST_INIT(fctx->forwarders); 3896 fctx->fwdpolicy = dns_fwdpolicy_none; 3897 ISC_LIST_INIT(fctx->bad); 3898 ISC_LIST_INIT(fctx->edns); 3899 ISC_LIST_INIT(fctx->edns512); 3900 ISC_LIST_INIT(fctx->bad_edns); 3901 ISC_LIST_INIT(fctx->validators); 3902 fctx->validator = NULL; 3903 fctx->find = NULL; 3904 fctx->altfind = NULL; 3905 fctx->pending = 0; 3906 fctx->restarts = 0; 3907 fctx->querysent = 0; 3908 fctx->referrals = 0; 3909 TIME_NOW(&fctx->start); 3910 fctx->timeouts = 0; 3911 fctx->lamecount = 0; 3912 fctx->adberr = 0; 3913 fctx->neterr = 0; 3914 fctx->badresp = 0; 3915 fctx->findfail = 0; 3916 fctx->valfail = 0; 3917 fctx->result = ISC_R_FAILURE; 3918 fctx->vresult = ISC_R_SUCCESS; 3919 fctx->exitline = -1; /* sentinel */ 3920 fctx->logged = ISC_FALSE; 3921 fctx->attributes = 0; 3922 fctx->spilled = ISC_FALSE; 3923 fctx->nqueries = 0; 3924 fctx->reason = NULL; 3925 fctx->rand_buf = 0; 3926 fctx->rand_bits = 0; 3927 fctx->timeout = ISC_FALSE; 3928 fctx->addrinfo = NULL; 3929 fctx->client = NULL; 3930 fctx->ns_ttl = 0; 3931 fctx->ns_ttl_ok = ISC_FALSE; 3932 3933 dns_name_init(&fctx->nsname, NULL); 3934 fctx->nsfetch = NULL; 3935 dns_rdataset_init(&fctx->nsrrset); 3936 3937 if (domain == NULL) { 3938 dns_forwarders_t *forwarders = NULL; 3939 unsigned int labels; 3940 dns_name_t *fwdname = name; 3941 3942 /* 3943 * DS records are found in the parent server. 3944 * Strip label to get the correct forwarder (if any). 3945 */ 3946 if (dns_rdatatype_atparent(fctx->type) && 3947 dns_name_countlabels(name) > 1) { 3948 dns_name_init(&suffix, NULL); 3949 labels = dns_name_countlabels(name); 3950 dns_name_getlabelsequence(name, 1, labels - 1, &suffix); 3951 fwdname = &suffix; 3952 } 3953 dns_fixedname_init(&fixed); 3954 domain = dns_fixedname_name(&fixed); 3955 result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname, 3956 domain, &forwarders); 3957 if (result == ISC_R_SUCCESS) 3958 fctx->fwdpolicy = forwarders->fwdpolicy; 3959 3960 if (fctx->fwdpolicy != dns_fwdpolicy_only) { 3961 /* 3962 * The caller didn't supply a query domain and 3963 * nameservers, and we're not in forward-only mode, 3964 * so find the best nameservers to use. 3965 */ 3966 if (dns_rdatatype_atparent(fctx->type)) 3967 findoptions |= DNS_DBFIND_NOEXACT; 3968 result = dns_view_findzonecut(res->view, name, 3969 domain, 0, findoptions, 3970 ISC_TRUE, 3971 &fctx->nameservers, 3972 NULL); 3973 if (result != ISC_R_SUCCESS) 3974 goto cleanup_name; 3975 3976 result = dns_name_dup(domain, mctx, &fctx->domain); 3977 if (result != ISC_R_SUCCESS) { 3978 dns_rdataset_disassociate(&fctx->nameservers); 3979 goto cleanup_name; 3980 } 3981 fctx->ns_ttl = fctx->nameservers.ttl; 3982 fctx->ns_ttl_ok = ISC_TRUE; 3983 } else { 3984 /* 3985 * We're in forward-only mode. Set the query domain. 3986 */ 3987 result = dns_name_dup(domain, mctx, &fctx->domain); 3988 if (result != ISC_R_SUCCESS) 3989 goto cleanup_name; 3990 } 3991 } else { 3992 result = dns_name_dup(domain, mctx, &fctx->domain); 3993 if (result != ISC_R_SUCCESS) 3994 goto cleanup_name; 3995 dns_rdataset_clone(nameservers, &fctx->nameservers); 3996 fctx->ns_ttl = fctx->nameservers.ttl; 3997 fctx->ns_ttl_ok = ISC_TRUE; 3998 } 3999 4000 log_ns_ttl(fctx, "fctx_create"); 4001 4002 INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain)); 4003 4004 fctx->qmessage = NULL; 4005 result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, 4006 &fctx->qmessage); 4007 4008 if (result != ISC_R_SUCCESS) 4009 goto cleanup_domain; 4010 4011 fctx->rmessage = NULL; 4012 result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, 4013 &fctx->rmessage); 4014 4015 if (result != ISC_R_SUCCESS) 4016 goto cleanup_qmessage; 4017 4018 /* 4019 * Compute an expiration time for the entire fetch. 4020 */ 4021 isc_interval_set(&interval, res->query_timeout, 0); 4022 iresult = isc_time_nowplusinterval(&fctx->expires, &interval); 4023 if (iresult != ISC_R_SUCCESS) { 4024 UNEXPECTED_ERROR(__FILE__, __LINE__, 4025 "isc_time_nowplusinterval: %s", 4026 isc_result_totext(iresult)); 4027 result = ISC_R_UNEXPECTED; 4028 goto cleanup_rmessage; 4029 } 4030 4031 /* 4032 * Default retry interval initialization. We set the interval now 4033 * mostly so it won't be uninitialized. It will be set to the 4034 * correct value before a query is issued. 4035 */ 4036 isc_interval_set(&fctx->interval, 2, 0); 4037 4038 /* 4039 * Create an inactive timer. It will be made active when the fetch 4040 * is actually started. 4041 */ 4042 fctx->timer = NULL; 4043 iresult = isc_timer_create(res->timermgr, isc_timertype_inactive, 4044 NULL, NULL, 4045 res->buckets[bucketnum].task, fctx_timeout, 4046 fctx, &fctx->timer); 4047 if (iresult != ISC_R_SUCCESS) { 4048 UNEXPECTED_ERROR(__FILE__, __LINE__, 4049 "isc_timer_create: %s", 4050 isc_result_totext(iresult)); 4051 result = ISC_R_UNEXPECTED; 4052 goto cleanup_rmessage; 4053 } 4054 4055 /* 4056 * Attach to the view's cache and adb. 4057 */ 4058 fctx->cache = NULL; 4059 dns_db_attach(res->view->cachedb, &fctx->cache); 4060 fctx->adb = NULL; 4061 dns_adb_attach(res->view->adb, &fctx->adb); 4062 fctx->mctx = NULL; 4063 isc_mem_attach(mctx, &fctx->mctx); 4064 4065 ISC_LIST_INIT(fctx->events); 4066 ISC_LINK_INIT(fctx, link); 4067 fctx->magic = FCTX_MAGIC; 4068 4069 ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link); 4070 4071 LOCK(&res->nlock); 4072 res->nfctx++; 4073 UNLOCK(&res->nlock); 4074 inc_stats(res, dns_resstatscounter_nfetch); 4075 4076 *fctxp = fctx; 4077 4078 return (ISC_R_SUCCESS); 4079 4080 cleanup_rmessage: 4081 dns_message_destroy(&fctx->rmessage); 4082 4083 cleanup_qmessage: 4084 dns_message_destroy(&fctx->qmessage); 4085 4086 cleanup_domain: 4087 if (dns_name_countlabels(&fctx->domain) > 0) 4088 dns_name_free(&fctx->domain, mctx); 4089 if (dns_rdataset_isassociated(&fctx->nameservers)) 4090 dns_rdataset_disassociate(&fctx->nameservers); 4091 4092 cleanup_name: 4093 dns_name_free(&fctx->name, mctx); 4094 4095 cleanup_info: 4096 isc_mem_free(mctx, fctx->info); 4097 4098 cleanup_counter: 4099 isc_counter_detach(&fctx->qc); 4100 4101 cleanup_fetch: 4102 isc_mem_put(mctx, fctx, sizeof(*fctx)); 4103 4104 return (result); 4105 } 4106 4107 /* 4108 * Handle Responses 4109 */ 4110 static inline isc_boolean_t 4111 is_lame(fetchctx_t *fctx) { 4112 dns_message_t *message = fctx->rmessage; 4113 dns_name_t *name; 4114 dns_rdataset_t *rdataset; 4115 isc_result_t result; 4116 4117 if (message->rcode != dns_rcode_noerror && 4118 message->rcode != dns_rcode_nxdomain) 4119 return (ISC_FALSE); 4120 4121 if (message->counts[DNS_SECTION_ANSWER] != 0) 4122 return (ISC_FALSE); 4123 4124 if (message->counts[DNS_SECTION_AUTHORITY] == 0) 4125 return (ISC_FALSE); 4126 4127 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); 4128 while (result == ISC_R_SUCCESS) { 4129 name = NULL; 4130 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); 4131 for (rdataset = ISC_LIST_HEAD(name->list); 4132 rdataset != NULL; 4133 rdataset = ISC_LIST_NEXT(rdataset, link)) { 4134 dns_namereln_t namereln; 4135 int order; 4136 unsigned int labels; 4137 if (rdataset->type != dns_rdatatype_ns) 4138 continue; 4139 namereln = dns_name_fullcompare(name, &fctx->domain, 4140 &order, &labels); 4141 if (namereln == dns_namereln_equal && 4142 (message->flags & DNS_MESSAGEFLAG_AA) != 0) 4143 return (ISC_FALSE); 4144 if (namereln == dns_namereln_subdomain) 4145 return (ISC_FALSE); 4146 return (ISC_TRUE); 4147 } 4148 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); 4149 } 4150 4151 return (ISC_FALSE); 4152 } 4153 4154 static inline void 4155 log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) { 4156 char namebuf[DNS_NAME_FORMATSIZE]; 4157 char domainbuf[DNS_NAME_FORMATSIZE]; 4158 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 4159 4160 dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); 4161 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); 4162 isc_sockaddr_format(&addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); 4163 isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS, 4164 DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, 4165 "lame server resolving '%s' (in '%s'?): %s", 4166 namebuf, domainbuf, addrbuf); 4167 } 4168 4169 static inline void 4170 log_formerr(fetchctx_t *fctx, const char *format, ...) { 4171 char nsbuf[ISC_SOCKADDR_FORMATSIZE]; 4172 char clbuf[ISC_SOCKADDR_FORMATSIZE]; 4173 const char *clmsg = ""; 4174 char msgbuf[2048]; 4175 va_list args; 4176 4177 va_start(args, format); 4178 vsnprintf(msgbuf, sizeof(msgbuf), format, args); 4179 va_end(args); 4180 4181 isc_sockaddr_format(&fctx->addrinfo->sockaddr, nsbuf, sizeof(nsbuf)); 4182 4183 if (fctx->client != NULL) { 4184 clmsg = " for client "; 4185 isc_sockaddr_format(fctx->client, clbuf, sizeof(clbuf)); 4186 } else { 4187 clbuf[0] = '\0'; 4188 } 4189 4190 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 4191 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, 4192 "DNS format error from %s resolving %s%s%s: %s", 4193 nsbuf, fctx->info, clmsg, clbuf, msgbuf); 4194 } 4195 4196 static inline isc_result_t 4197 same_question(fetchctx_t *fctx) { 4198 isc_result_t result; 4199 dns_message_t *message = fctx->rmessage; 4200 dns_name_t *name; 4201 dns_rdataset_t *rdataset; 4202 4203 /* 4204 * Caller must be holding the fctx lock. 4205 */ 4206 4207 /* 4208 * XXXRTH Currently we support only one question. 4209 */ 4210 if (message->counts[DNS_SECTION_QUESTION] != 1) { 4211 log_formerr(fctx, "too many questions"); 4212 return (DNS_R_FORMERR); 4213 } 4214 4215 result = dns_message_firstname(message, DNS_SECTION_QUESTION); 4216 if (result != ISC_R_SUCCESS) 4217 return (result); 4218 name = NULL; 4219 dns_message_currentname(message, DNS_SECTION_QUESTION, &name); 4220 rdataset = ISC_LIST_HEAD(name->list); 4221 INSIST(rdataset != NULL); 4222 INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); 4223 4224 if (fctx->type != rdataset->type || 4225 fctx->res->rdclass != rdataset->rdclass || 4226 !dns_name_equal(&fctx->name, name)) { 4227 char namebuf[DNS_NAME_FORMATSIZE]; 4228 char class[DNS_RDATACLASS_FORMATSIZE]; 4229 char type[DNS_RDATATYPE_FORMATSIZE]; 4230 4231 dns_name_format(name, namebuf, sizeof(namebuf)); 4232 dns_rdataclass_format(rdataset->rdclass, class, sizeof(class)); 4233 dns_rdatatype_format(rdataset->type, type, sizeof(type)); 4234 log_formerr(fctx, "question section mismatch: got %s/%s/%s", 4235 namebuf, class, type); 4236 return (DNS_R_FORMERR); 4237 } 4238 4239 return (ISC_R_SUCCESS); 4240 } 4241 4242 static void 4243 clone_results(fetchctx_t *fctx) { 4244 dns_fetchevent_t *event, *hevent; 4245 isc_result_t result; 4246 dns_name_t *name, *hname; 4247 4248 FCTXTRACE("clone_results"); 4249 4250 /* 4251 * Set up any other events to have the same data as the first 4252 * event. 4253 * 4254 * Caller must be holding the appropriate lock. 4255 */ 4256 4257 fctx->cloned = ISC_TRUE; 4258 hevent = ISC_LIST_HEAD(fctx->events); 4259 if (hevent == NULL) 4260 return; 4261 hname = dns_fixedname_name(&hevent->foundname); 4262 for (event = ISC_LIST_NEXT(hevent, ev_link); 4263 event != NULL; 4264 event = ISC_LIST_NEXT(event, ev_link)) { 4265 name = dns_fixedname_name(&event->foundname); 4266 result = dns_name_copy(hname, name, NULL); 4267 if (result != ISC_R_SUCCESS) 4268 event->result = result; 4269 else 4270 event->result = hevent->result; 4271 dns_db_attach(hevent->db, &event->db); 4272 dns_db_attachnode(hevent->db, hevent->node, &event->node); 4273 INSIST(hevent->rdataset != NULL); 4274 INSIST(event->rdataset != NULL); 4275 if (dns_rdataset_isassociated(hevent->rdataset)) 4276 dns_rdataset_clone(hevent->rdataset, event->rdataset); 4277 INSIST(! (hevent->sigrdataset == NULL && 4278 event->sigrdataset != NULL)); 4279 if (hevent->sigrdataset != NULL && 4280 dns_rdataset_isassociated(hevent->sigrdataset) && 4281 event->sigrdataset != NULL) 4282 dns_rdataset_clone(hevent->sigrdataset, 4283 event->sigrdataset); 4284 } 4285 } 4286 4287 #define CACHE(r) (((r)->attributes & DNS_RDATASETATTR_CACHE) != 0) 4288 #define ANSWER(r) (((r)->attributes & DNS_RDATASETATTR_ANSWER) != 0) 4289 #define ANSWERSIG(r) (((r)->attributes & DNS_RDATASETATTR_ANSWERSIG) != 0) 4290 #define EXTERNAL(r) (((r)->attributes & DNS_RDATASETATTR_EXTERNAL) != 0) 4291 #define CHAINING(r) (((r)->attributes & DNS_RDATASETATTR_CHAINING) != 0) 4292 #define CHASE(r) (((r)->attributes & DNS_RDATASETATTR_CHASE) != 0) 4293 #define CHECKNAMES(r) (((r)->attributes & DNS_RDATASETATTR_CHECKNAMES) != 0) 4294 4295 4296 /* 4297 * Destroy '*fctx' if it is ready to be destroyed (i.e., if it has 4298 * no references and is no longer waiting for any events). 4299 * 4300 * Requires: 4301 * '*fctx' is shutting down. 4302 * 4303 * Returns: 4304 * true if the resolver is exiting and this is the last fctx in the bucket. 4305 */ 4306 static isc_boolean_t 4307 maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) { 4308 unsigned int bucketnum; 4309 isc_boolean_t bucket_empty = ISC_FALSE; 4310 dns_resolver_t *res = fctx->res; 4311 dns_validator_t *validator, *next_validator; 4312 isc_boolean_t destroy = ISC_FALSE; 4313 4314 REQUIRE(SHUTTINGDOWN(fctx)); 4315 4316 bucketnum = fctx->bucketnum; 4317 if (!locked) 4318 LOCK(&res->buckets[bucketnum].lock); 4319 if (fctx->pending != 0 || fctx->nqueries != 0) 4320 goto unlock; 4321 4322 for (validator = ISC_LIST_HEAD(fctx->validators); 4323 validator != NULL; validator = next_validator) { 4324 next_validator = ISC_LIST_NEXT(validator, link); 4325 dns_validator_cancel(validator); 4326 } 4327 4328 if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) { 4329 bucket_empty = fctx_unlink(fctx); 4330 destroy = ISC_TRUE; 4331 } 4332 unlock: 4333 if (!locked) 4334 UNLOCK(&res->buckets[bucketnum].lock); 4335 if (destroy) 4336 fctx_destroy(fctx); 4337 return (bucket_empty); 4338 } 4339 4340 /* 4341 * The validator has finished. 4342 */ 4343 static void 4344 validated(isc_task_t *task, isc_event_t *event) { 4345 dns_adbaddrinfo_t *addrinfo; 4346 dns_dbnode_t *node = NULL; 4347 dns_dbnode_t *nsnode = NULL; 4348 dns_fetchevent_t *hevent; 4349 dns_name_t *name; 4350 dns_rdataset_t *ardataset = NULL; 4351 dns_rdataset_t *asigrdataset = NULL; 4352 dns_rdataset_t *rdataset; 4353 dns_rdataset_t *sigrdataset; 4354 dns_resolver_t *res; 4355 dns_valarg_t *valarg; 4356 dns_validatorevent_t *vevent; 4357 fetchctx_t *fctx; 4358 isc_boolean_t chaining; 4359 isc_boolean_t negative; 4360 isc_boolean_t sentresponse; 4361 isc_result_t eresult = ISC_R_SUCCESS; 4362 isc_result_t result = ISC_R_SUCCESS; 4363 isc_stdtime_t now; 4364 isc_uint32_t ttl; 4365 unsigned options; 4366 isc_uint32_t bucketnum; 4367 4368 UNUSED(task); /* for now */ 4369 4370 REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE); 4371 valarg = event->ev_arg; 4372 fctx = valarg->fctx; 4373 res = fctx->res; 4374 addrinfo = valarg->addrinfo; 4375 REQUIRE(VALID_FCTX(fctx)); 4376 REQUIRE(!ISC_LIST_EMPTY(fctx->validators)); 4377 4378 vevent = (dns_validatorevent_t *)event; 4379 fctx->vresult = vevent->result; 4380 4381 FCTXTRACE("received validation completion event"); 4382 4383 bucketnum = fctx->bucketnum; 4384 LOCK(&res->buckets[bucketnum].lock); 4385 4386 ISC_LIST_UNLINK(fctx->validators, vevent->validator, link); 4387 fctx->validator = NULL; 4388 4389 /* 4390 * Destroy the validator early so that we can 4391 * destroy the fctx if necessary. 4392 */ 4393 dns_validator_destroy(&vevent->validator); 4394 isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); 4395 4396 negative = ISC_TF(vevent->rdataset == NULL); 4397 4398 sentresponse = ISC_TF((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0); 4399 4400 /* 4401 * If shutting down, ignore the results. Check to see if we're 4402 * done waiting for validator completions and ADB pending events; if 4403 * so, destroy the fctx. 4404 */ 4405 if (SHUTTINGDOWN(fctx) && !sentresponse) { 4406 isc_boolean_t bucket_empty; 4407 bucket_empty = maybe_destroy(fctx, ISC_TRUE); 4408 UNLOCK(&res->buckets[bucketnum].lock); 4409 if (bucket_empty) 4410 empty_bucket(res); 4411 goto cleanup_event; 4412 } 4413 4414 isc_stdtime_get(&now); 4415 4416 /* 4417 * If chaining, we need to make sure that the right result code is 4418 * returned, and that the rdatasets are bound. 4419 */ 4420 if (vevent->result == ISC_R_SUCCESS && 4421 !negative && 4422 vevent->rdataset != NULL && 4423 CHAINING(vevent->rdataset)) 4424 { 4425 if (vevent->rdataset->type == dns_rdatatype_cname) 4426 eresult = DNS_R_CNAME; 4427 else { 4428 INSIST(vevent->rdataset->type == dns_rdatatype_dname); 4429 eresult = DNS_R_DNAME; 4430 } 4431 chaining = ISC_TRUE; 4432 } else 4433 chaining = ISC_FALSE; 4434 4435 /* 4436 * Either we're not shutting down, or we are shutting down but want 4437 * to cache the result anyway (if this was a validation started by 4438 * a query with cd set) 4439 */ 4440 4441 hevent = ISC_LIST_HEAD(fctx->events); 4442 if (hevent != NULL) { 4443 if (!negative && !chaining && 4444 (fctx->type == dns_rdatatype_any || 4445 fctx->type == dns_rdatatype_rrsig || 4446 fctx->type == dns_rdatatype_sig)) { 4447 /* 4448 * Don't bind rdatasets; the caller 4449 * will iterate the node. 4450 */ 4451 } else { 4452 ardataset = hevent->rdataset; 4453 asigrdataset = hevent->sigrdataset; 4454 } 4455 } 4456 4457 if (vevent->result != ISC_R_SUCCESS) { 4458 FCTXTRACE("validation failed"); 4459 inc_stats(res, dns_resstatscounter_valfail); 4460 fctx->valfail++; 4461 fctx->vresult = vevent->result; 4462 if (fctx->vresult != DNS_R_BROKENCHAIN) { 4463 result = ISC_R_NOTFOUND; 4464 if (vevent->rdataset != NULL) 4465 result = dns_db_findnode(fctx->cache, 4466 vevent->name, 4467 ISC_TRUE, &node); 4468 if (result == ISC_R_SUCCESS) 4469 (void)dns_db_deleterdataset(fctx->cache, node, 4470 NULL, 4471 vevent->type, 0); 4472 if (result == ISC_R_SUCCESS && 4473 vevent->sigrdataset != NULL) 4474 (void)dns_db_deleterdataset(fctx->cache, node, 4475 NULL, 4476 dns_rdatatype_rrsig, 4477 vevent->type); 4478 if (result == ISC_R_SUCCESS) 4479 dns_db_detachnode(fctx->cache, &node); 4480 } 4481 if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) { 4482 /* 4483 * Cache the data as pending for later validation. 4484 */ 4485 result = ISC_R_NOTFOUND; 4486 if (vevent->rdataset != NULL) 4487 result = dns_db_findnode(fctx->cache, 4488 vevent->name, 4489 ISC_TRUE, &node); 4490 if (result == ISC_R_SUCCESS) { 4491 (void)dns_db_addrdataset(fctx->cache, node, 4492 NULL, now, 4493 vevent->rdataset, 0, 4494 NULL); 4495 } 4496 if (result == ISC_R_SUCCESS && 4497 vevent->sigrdataset != NULL) 4498 (void)dns_db_addrdataset(fctx->cache, node, 4499 NULL, now, 4500 vevent->sigrdataset, 4501 0, NULL); 4502 if (result == ISC_R_SUCCESS) 4503 dns_db_detachnode(fctx->cache, &node); 4504 } 4505 result = fctx->vresult; 4506 add_bad(fctx, addrinfo, result, badns_validation); 4507 isc_event_free(&event); 4508 UNLOCK(&res->buckets[bucketnum].lock); 4509 INSIST(fctx->validator == NULL); 4510 fctx->validator = ISC_LIST_HEAD(fctx->validators); 4511 if (fctx->validator != NULL) 4512 dns_validator_send(fctx->validator); 4513 else if (sentresponse) 4514 fctx_done(fctx, result, __LINE__); /* Locks bucket. */ 4515 else if (result == DNS_R_BROKENCHAIN) { 4516 isc_result_t tresult; 4517 isc_time_t expire; 4518 isc_interval_t i; 4519 4520 isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0); 4521 tresult = isc_time_nowplusinterval(&expire, &i); 4522 if (negative && 4523 (fctx->type == dns_rdatatype_dnskey || 4524 fctx->type == dns_rdatatype_dlv || 4525 fctx->type == dns_rdatatype_ds) && 4526 tresult == ISC_R_SUCCESS) 4527 dns_resolver_addbadcache(res, &fctx->name, 4528 fctx->type, &expire); 4529 fctx_done(fctx, result, __LINE__); /* Locks bucket. */ 4530 } else 4531 fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */ 4532 return; 4533 } 4534 4535 4536 if (negative) { 4537 dns_rdatatype_t covers; 4538 FCTXTRACE("nonexistence validation OK"); 4539 4540 inc_stats(res, dns_resstatscounter_valnegsuccess); 4541 4542 /* 4543 * Cache DS NXDOMAIN seperately to other types. 4544 */ 4545 if (fctx->rmessage->rcode == dns_rcode_nxdomain && 4546 fctx->type != dns_rdatatype_ds) 4547 covers = dns_rdatatype_any; 4548 else 4549 covers = fctx->type; 4550 4551 result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, 4552 &node); 4553 if (result != ISC_R_SUCCESS) 4554 goto noanswer_response; 4555 4556 /* 4557 * If we are asking for a SOA record set the cache time 4558 * to zero to facilitate locating the containing zone of 4559 * a arbitrary zone. 4560 */ 4561 ttl = res->view->maxncachettl; 4562 if (fctx->type == dns_rdatatype_soa && 4563 covers == dns_rdatatype_any && res->zero_no_soa_ttl) 4564 ttl = 0; 4565 4566 result = ncache_adderesult(fctx->rmessage, fctx->cache, node, 4567 covers, now, ttl, vevent->optout, 4568 vevent->secure, ardataset, &eresult); 4569 if (result != ISC_R_SUCCESS) 4570 goto noanswer_response; 4571 goto answer_response; 4572 } else 4573 inc_stats(res, dns_resstatscounter_valsuccess); 4574 4575 FCTXTRACE("validation OK"); 4576 4577 if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) { 4578 result = dns_rdataset_addnoqname(vevent->rdataset, 4579 vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]); 4580 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4581 INSIST(vevent->sigrdataset != NULL); 4582 vevent->sigrdataset->ttl = vevent->rdataset->ttl; 4583 if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) { 4584 result = dns_rdataset_addclosest(vevent->rdataset, 4585 vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]); 4586 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4587 } 4588 } else if (vevent->rdataset->trust == dns_trust_answer && 4589 vevent->rdataset->type != dns_rdatatype_rrsig) 4590 { 4591 isc_result_t tresult; 4592 dns_name_t *noqname = NULL; 4593 tresult = findnoqname(fctx, vevent->name, 4594 vevent->rdataset->type, &noqname); 4595 if (tresult == ISC_R_SUCCESS && noqname != NULL) { 4596 tresult = dns_rdataset_addnoqname(vevent->rdataset, 4597 noqname); 4598 RUNTIME_CHECK(tresult == ISC_R_SUCCESS); 4599 } 4600 } 4601 4602 /* 4603 * The data was already cached as pending data. 4604 * Re-cache it as secure and bind the cached 4605 * rdatasets to the first event on the fetch 4606 * event list. 4607 */ 4608 result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node); 4609 if (result != ISC_R_SUCCESS) 4610 goto noanswer_response; 4611 4612 options = 0; 4613 if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) 4614 options = DNS_DBADD_PREFETCH; 4615 result = dns_db_addrdataset(fctx->cache, node, NULL, now, 4616 vevent->rdataset, options, ardataset); 4617 if (result != ISC_R_SUCCESS && 4618 result != DNS_R_UNCHANGED) 4619 goto noanswer_response; 4620 if (ardataset != NULL && NEGATIVE(ardataset)) { 4621 if (NXDOMAIN(ardataset)) 4622 eresult = DNS_R_NCACHENXDOMAIN; 4623 else 4624 eresult = DNS_R_NCACHENXRRSET; 4625 } else if (vevent->sigrdataset != NULL) { 4626 result = dns_db_addrdataset(fctx->cache, node, NULL, now, 4627 vevent->sigrdataset, 0, 4628 asigrdataset); 4629 if (result != ISC_R_SUCCESS && 4630 result != DNS_R_UNCHANGED) 4631 goto noanswer_response; 4632 } 4633 4634 if (sentresponse) { 4635 isc_boolean_t bucket_empty = ISC_FALSE; 4636 /* 4637 * If we only deferred the destroy because we wanted to cache 4638 * the data, destroy now. 4639 */ 4640 dns_db_detachnode(fctx->cache, &node); 4641 if (SHUTTINGDOWN(fctx)) 4642 bucket_empty = maybe_destroy(fctx, ISC_TRUE); 4643 UNLOCK(&res->buckets[bucketnum].lock); 4644 if (bucket_empty) 4645 empty_bucket(res); 4646 goto cleanup_event; 4647 } 4648 4649 if (!ISC_LIST_EMPTY(fctx->validators)) { 4650 INSIST(!negative); 4651 INSIST(fctx->type == dns_rdatatype_any || 4652 fctx->type == dns_rdatatype_rrsig || 4653 fctx->type == dns_rdatatype_sig); 4654 /* 4655 * Don't send a response yet - we have 4656 * more rdatasets that still need to 4657 * be validated. 4658 */ 4659 dns_db_detachnode(fctx->cache, &node); 4660 UNLOCK(&res->buckets[bucketnum].lock); 4661 dns_validator_send(ISC_LIST_HEAD(fctx->validators)); 4662 goto cleanup_event; 4663 } 4664 4665 answer_response: 4666 /* 4667 * Cache any NS/NSEC records that happened to be validated. 4668 */ 4669 result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY); 4670 while (result == ISC_R_SUCCESS) { 4671 name = NULL; 4672 dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY, 4673 &name); 4674 for (rdataset = ISC_LIST_HEAD(name->list); 4675 rdataset != NULL; 4676 rdataset = ISC_LIST_NEXT(rdataset, link)) { 4677 if ((rdataset->type != dns_rdatatype_ns && 4678 rdataset->type != dns_rdatatype_nsec) || 4679 rdataset->trust != dns_trust_secure) 4680 continue; 4681 for (sigrdataset = ISC_LIST_HEAD(name->list); 4682 sigrdataset != NULL; 4683 sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { 4684 if (sigrdataset->type != dns_rdatatype_rrsig || 4685 sigrdataset->covers != rdataset->type) 4686 continue; 4687 break; 4688 } 4689 if (sigrdataset == NULL || 4690 sigrdataset->trust != dns_trust_secure) 4691 continue; 4692 result = dns_db_findnode(fctx->cache, name, ISC_TRUE, 4693 &nsnode); 4694 if (result != ISC_R_SUCCESS) 4695 continue; 4696 4697 result = dns_db_addrdataset(fctx->cache, nsnode, NULL, 4698 now, rdataset, 0, NULL); 4699 if (result == ISC_R_SUCCESS) 4700 result = dns_db_addrdataset(fctx->cache, nsnode, 4701 NULL, now, 4702 sigrdataset, 0, 4703 NULL); 4704 dns_db_detachnode(fctx->cache, &nsnode); 4705 if (result != ISC_R_SUCCESS) 4706 continue; 4707 } 4708 result = dns_message_nextname(fctx->rmessage, 4709 DNS_SECTION_AUTHORITY); 4710 } 4711 4712 result = ISC_R_SUCCESS; 4713 4714 /* 4715 * Respond with an answer, positive or negative, 4716 * as opposed to an error. 'node' must be non-NULL. 4717 */ 4718 4719 fctx->attributes |= FCTX_ATTR_HAVEANSWER; 4720 4721 if (hevent != NULL) { 4722 /* 4723 * Negative results must be indicated in event->result. 4724 */ 4725 if (dns_rdataset_isassociated(hevent->rdataset) && 4726 NEGATIVE(hevent->rdataset)) { 4727 INSIST(eresult == DNS_R_NCACHENXDOMAIN || 4728 eresult == DNS_R_NCACHENXRRSET); 4729 } 4730 hevent->result = eresult; 4731 RUNTIME_CHECK(dns_name_copy(vevent->name, 4732 dns_fixedname_name(&hevent->foundname), NULL) 4733 == ISC_R_SUCCESS); 4734 dns_db_attach(fctx->cache, &hevent->db); 4735 dns_db_transfernode(fctx->cache, &node, &hevent->node); 4736 clone_results(fctx); 4737 } 4738 4739 noanswer_response: 4740 if (node != NULL) 4741 dns_db_detachnode(fctx->cache, &node); 4742 4743 UNLOCK(&res->buckets[bucketnum].lock); 4744 fctx_done(fctx, result, __LINE__); /* Locks bucket. */ 4745 4746 cleanup_event: 4747 INSIST(node == NULL); 4748 isc_event_free(&event); 4749 } 4750 4751 static void 4752 fctx_log(void *arg, int level, const char *fmt, ...) { 4753 char msgbuf[2048]; 4754 va_list args; 4755 fetchctx_t *fctx = arg; 4756 4757 va_start(args, fmt); 4758 vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); 4759 va_end(args); 4760 4761 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 4762 DNS_LOGMODULE_RESOLVER, level, 4763 "fctx %p(%s): %s", fctx, fctx->info, msgbuf); 4764 } 4765 4766 static inline isc_result_t 4767 findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type, 4768 dns_name_t **noqnamep) 4769 { 4770 dns_rdataset_t *nrdataset, *next, *sigrdataset; 4771 dns_rdata_rrsig_t rrsig; 4772 isc_result_t result; 4773 unsigned int labels; 4774 dns_section_t section; 4775 dns_name_t *zonename; 4776 dns_fixedname_t fzonename; 4777 dns_name_t *closest; 4778 dns_fixedname_t fclosest; 4779 dns_name_t *nearest; 4780 dns_fixedname_t fnearest; 4781 dns_rdatatype_t found = dns_rdatatype_none; 4782 dns_name_t *noqname = NULL; 4783 4784 FCTXTRACE("findnoqname"); 4785 4786 REQUIRE(noqnamep != NULL && *noqnamep == NULL); 4787 4788 /* 4789 * Find the SIG for this rdataset, if we have it. 4790 */ 4791 for (sigrdataset = ISC_LIST_HEAD(name->list); 4792 sigrdataset != NULL; 4793 sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { 4794 if (sigrdataset->type == dns_rdatatype_rrsig && 4795 sigrdataset->covers == type) 4796 break; 4797 } 4798 4799 if (sigrdataset == NULL) 4800 return (ISC_R_NOTFOUND); 4801 4802 labels = dns_name_countlabels(name); 4803 4804 for (result = dns_rdataset_first(sigrdataset); 4805 result == ISC_R_SUCCESS; 4806 result = dns_rdataset_next(sigrdataset)) { 4807 dns_rdata_t rdata = DNS_RDATA_INIT; 4808 dns_rdataset_current(sigrdataset, &rdata); 4809 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 4810 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4811 /* Wildcard has rrsig.labels < labels - 1. */ 4812 if (rrsig.labels + 1U >= labels) 4813 continue; 4814 break; 4815 } 4816 4817 if (result == ISC_R_NOMORE) 4818 return (ISC_R_NOTFOUND); 4819 if (result != ISC_R_SUCCESS) 4820 return (result); 4821 4822 dns_fixedname_init(&fzonename); 4823 zonename = dns_fixedname_name(&fzonename); 4824 dns_fixedname_init(&fclosest); 4825 closest = dns_fixedname_name(&fclosest); 4826 dns_fixedname_init(&fnearest); 4827 nearest = dns_fixedname_name(&fnearest); 4828 4829 #define NXND(x) ((x) == ISC_R_SUCCESS) 4830 4831 section = DNS_SECTION_AUTHORITY; 4832 for (result = dns_message_firstname(fctx->rmessage, section); 4833 result == ISC_R_SUCCESS; 4834 result = dns_message_nextname(fctx->rmessage, section)) { 4835 dns_name_t *nsec = NULL; 4836 dns_message_currentname(fctx->rmessage, section, &nsec); 4837 for (nrdataset = ISC_LIST_HEAD(nsec->list); 4838 nrdataset != NULL; nrdataset = next) { 4839 isc_boolean_t data = ISC_FALSE, exists = ISC_FALSE; 4840 isc_boolean_t optout = ISC_FALSE, unknown = ISC_FALSE; 4841 isc_boolean_t setclosest = ISC_FALSE; 4842 isc_boolean_t setnearest = ISC_FALSE; 4843 4844 next = ISC_LIST_NEXT(nrdataset, link); 4845 if (nrdataset->type != dns_rdatatype_nsec && 4846 nrdataset->type != dns_rdatatype_nsec3) 4847 continue; 4848 4849 if (nrdataset->type == dns_rdatatype_nsec && 4850 NXND(dns_nsec_noexistnodata(type, name, nsec, 4851 nrdataset, &exists, 4852 &data, NULL, fctx_log, 4853 fctx))) 4854 { 4855 if (!exists) { 4856 noqname = nsec; 4857 found = dns_rdatatype_nsec; 4858 } 4859 } 4860 4861 if (nrdataset->type == dns_rdatatype_nsec3 && 4862 NXND(dns_nsec3_noexistnodata(type, name, nsec, 4863 nrdataset, zonename, 4864 &exists, &data, 4865 &optout, &unknown, 4866 &setclosest, 4867 &setnearest, 4868 closest, nearest, 4869 fctx_log, fctx))) 4870 { 4871 if (!exists && setnearest) { 4872 noqname = nsec; 4873 found = dns_rdatatype_nsec3; 4874 } 4875 } 4876 } 4877 } 4878 if (result == ISC_R_NOMORE) 4879 result = ISC_R_SUCCESS; 4880 if (noqname != NULL) { 4881 for (sigrdataset = ISC_LIST_HEAD(noqname->list); 4882 sigrdataset != NULL; 4883 sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { 4884 if (sigrdataset->type == dns_rdatatype_rrsig && 4885 sigrdataset->covers == found) 4886 break; 4887 } 4888 if (sigrdataset != NULL) 4889 *noqnamep = noqname; 4890 } 4891 return (result); 4892 } 4893 4894 static inline isc_result_t 4895 cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, 4896 isc_stdtime_t now) 4897 { 4898 dns_rdataset_t *rdataset, *sigrdataset; 4899 dns_rdataset_t *addedrdataset, *ardataset, *asigrdataset; 4900 dns_rdataset_t *valrdataset = NULL, *valsigrdataset = NULL; 4901 dns_dbnode_t *node, **anodep; 4902 dns_db_t **adbp; 4903 dns_name_t *aname; 4904 dns_resolver_t *res; 4905 isc_boolean_t need_validation, secure_domain, have_answer; 4906 isc_result_t result, eresult; 4907 dns_fetchevent_t *event; 4908 unsigned int options; 4909 isc_task_t *task; 4910 isc_boolean_t fail; 4911 unsigned int valoptions = 0; 4912 4913 /* 4914 * The appropriate bucket lock must be held. 4915 */ 4916 4917 res = fctx->res; 4918 need_validation = ISC_FALSE; 4919 POST(need_validation); 4920 secure_domain = ISC_FALSE; 4921 have_answer = ISC_FALSE; 4922 eresult = ISC_R_SUCCESS; 4923 task = res->buckets[fctx->bucketnum].task; 4924 4925 /* 4926 * Is DNSSEC validation required for this name? 4927 */ 4928 if (res->view->enablevalidation) { 4929 result = dns_view_issecuredomain(res->view, name, 4930 &secure_domain); 4931 if (result != ISC_R_SUCCESS) 4932 return (result); 4933 4934 if (!secure_domain && res->view->dlv != NULL) { 4935 valoptions = DNS_VALIDATOR_DLV; 4936 secure_domain = ISC_TRUE; 4937 } 4938 } 4939 4940 if ((fctx->options & DNS_FETCHOPT_NOCDFLAG) != 0) 4941 valoptions |= DNS_VALIDATOR_NOCDFLAG; 4942 4943 if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) 4944 need_validation = ISC_FALSE; 4945 else 4946 need_validation = secure_domain; 4947 4948 adbp = NULL; 4949 aname = NULL; 4950 anodep = NULL; 4951 ardataset = NULL; 4952 asigrdataset = NULL; 4953 event = NULL; 4954 if ((name->attributes & DNS_NAMEATTR_ANSWER) != 0 && 4955 !need_validation) { 4956 have_answer = ISC_TRUE; 4957 event = ISC_LIST_HEAD(fctx->events); 4958 if (event != NULL) { 4959 adbp = &event->db; 4960 aname = dns_fixedname_name(&event->foundname); 4961 result = dns_name_copy(name, aname, NULL); 4962 if (result != ISC_R_SUCCESS) 4963 return (result); 4964 anodep = &event->node; 4965 /* 4966 * If this is an ANY, SIG or RRSIG query, we're not 4967 * going to return any rdatasets, unless we encountered 4968 * a CNAME or DNAME as "the answer". In this case, 4969 * we're going to return DNS_R_CNAME or DNS_R_DNAME 4970 * and we must set up the rdatasets. 4971 */ 4972 if ((fctx->type != dns_rdatatype_any && 4973 fctx->type != dns_rdatatype_rrsig && 4974 fctx->type != dns_rdatatype_sig) || 4975 (name->attributes & DNS_NAMEATTR_CHAINING) != 0) { 4976 ardataset = event->rdataset; 4977 asigrdataset = event->sigrdataset; 4978 } 4979 } 4980 } 4981 4982 /* 4983 * Find or create the cache node. 4984 */ 4985 node = NULL; 4986 result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node); 4987 if (result != ISC_R_SUCCESS) 4988 return (result); 4989 4990 /* 4991 * Cache or validate each cacheable rdataset. 4992 */ 4993 fail = ISC_TF((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0); 4994 for (rdataset = ISC_LIST_HEAD(name->list); 4995 rdataset != NULL; 4996 rdataset = ISC_LIST_NEXT(rdataset, link)) { 4997 if (!CACHE(rdataset)) 4998 continue; 4999 if (CHECKNAMES(rdataset)) { 5000 char namebuf[DNS_NAME_FORMATSIZE]; 5001 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 5002 char classbuf[DNS_RDATATYPE_FORMATSIZE]; 5003 5004 dns_name_format(name, namebuf, sizeof(namebuf)); 5005 dns_rdatatype_format(rdataset->type, typebuf, 5006 sizeof(typebuf)); 5007 dns_rdataclass_format(rdataset->rdclass, classbuf, 5008 sizeof(classbuf)); 5009 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 5010 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, 5011 "check-names %s %s/%s/%s", 5012 fail ? "failure" : "warning", 5013 namebuf, typebuf, classbuf); 5014 if (fail) { 5015 if (ANSWER(rdataset)) { 5016 dns_db_detachnode(fctx->cache, &node); 5017 return (DNS_R_BADNAME); 5018 } 5019 continue; 5020 } 5021 } 5022 5023 /* 5024 * Enforce the configure maximum cache TTL. 5025 */ 5026 if (rdataset->ttl > res->view->maxcachettl) 5027 rdataset->ttl = res->view->maxcachettl; 5028 5029 /* 5030 * Mark the rdataset as being prefetch eligible. 5031 */ 5032 if (rdataset->ttl > fctx->res->view->prefetch_eligible) 5033 rdataset->attributes |= DNS_RDATASETATTR_PREFETCH; 5034 5035 /* 5036 * Find the SIG for this rdataset, if we have it. 5037 */ 5038 for (sigrdataset = ISC_LIST_HEAD(name->list); 5039 sigrdataset != NULL; 5040 sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { 5041 if (sigrdataset->type == dns_rdatatype_rrsig && 5042 sigrdataset->covers == rdataset->type) 5043 break; 5044 } 5045 5046 /* 5047 * If this RRset is in a secure domain, is in bailiwick, 5048 * and is not glue, attempt DNSSEC validation. (We do not 5049 * attempt to validate glue or out-of-bailiwick data--even 5050 * though there might be some performance benefit to doing 5051 * so--because it makes it simpler and safer to ensure that 5052 * records from a secure domain are only cached if validated 5053 * within the context of a query to the domain that owns 5054 * them.) 5055 */ 5056 if (secure_domain && rdataset->trust != dns_trust_glue && 5057 !EXTERNAL(rdataset)) { 5058 dns_trust_t trust; 5059 5060 /* 5061 * RRSIGs are validated as part of validating the 5062 * type they cover. 5063 */ 5064 if (rdataset->type == dns_rdatatype_rrsig) 5065 continue; 5066 5067 if (sigrdataset == NULL) { 5068 if (!ANSWER(rdataset) && need_validation) { 5069 /* 5070 * Ignore non-answer rdatasets that 5071 * are missing signatures. 5072 */ 5073 continue; 5074 } 5075 } 5076 5077 /* 5078 * Normalize the rdataset and sigrdataset TTLs. 5079 */ 5080 if (sigrdataset != NULL) { 5081 rdataset->ttl = ISC_MIN(rdataset->ttl, 5082 sigrdataset->ttl); 5083 sigrdataset->ttl = rdataset->ttl; 5084 } 5085 5086 /* 5087 * Mark the rdataset as being prefetch eligible. 5088 */ 5089 if (rdataset->ttl > fctx->res->view->prefetch_eligible) 5090 rdataset->attributes |= DNS_RDATASETATTR_PREFETCH; 5091 5092 5093 /* 5094 * Cache this rdataset/sigrdataset pair as 5095 * pending data. Track whether it was additional 5096 * or not. 5097 */ 5098 if (rdataset->trust == dns_trust_additional) 5099 trust = dns_trust_pending_additional; 5100 else 5101 trust = dns_trust_pending_answer; 5102 5103 rdataset->trust = trust; 5104 if (sigrdataset != NULL) 5105 sigrdataset->trust = trust; 5106 if (!need_validation || !ANSWER(rdataset)) { 5107 options = 0; 5108 if (ANSWER(rdataset) && 5109 rdataset->type != dns_rdatatype_rrsig) { 5110 isc_result_t tresult; 5111 dns_name_t *noqname = NULL; 5112 tresult = findnoqname(fctx, name, 5113 rdataset->type, 5114 &noqname); 5115 if (tresult == ISC_R_SUCCESS && 5116 noqname != NULL) { 5117 tresult = 5118 dns_rdataset_addnoqname( 5119 rdataset, noqname); 5120 RUNTIME_CHECK(tresult == 5121 ISC_R_SUCCESS); 5122 } 5123 } 5124 if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) 5125 options = DNS_DBADD_PREFETCH; 5126 addedrdataset = ardataset; 5127 result = dns_db_addrdataset(fctx->cache, node, 5128 NULL, now, rdataset, 5129 options, 5130 addedrdataset); 5131 if (result == DNS_R_UNCHANGED) { 5132 result = ISC_R_SUCCESS; 5133 if (!need_validation && 5134 ardataset != NULL && 5135 NEGATIVE(ardataset)) { 5136 /* 5137 * The answer in the cache is 5138 * better than the answer we 5139 * found, and is a negative 5140 * cache entry, so we must set 5141 * eresult appropriately. 5142 */ 5143 if (NXDOMAIN(ardataset)) 5144 eresult = 5145 DNS_R_NCACHENXDOMAIN; 5146 else 5147 eresult = 5148 DNS_R_NCACHENXRRSET; 5149 /* 5150 * We have a negative response 5151 * from the cache so don't 5152 * attempt to add the RRSIG 5153 * rrset. 5154 */ 5155 continue; 5156 } 5157 } 5158 if (result != ISC_R_SUCCESS) 5159 break; 5160 if (sigrdataset != NULL) { 5161 addedrdataset = asigrdataset; 5162 result = dns_db_addrdataset(fctx->cache, 5163 node, NULL, now, 5164 sigrdataset, 5165 options, 5166 addedrdataset); 5167 if (result == DNS_R_UNCHANGED) 5168 result = ISC_R_SUCCESS; 5169 if (result != ISC_R_SUCCESS) 5170 break; 5171 } else if (!ANSWER(rdataset)) 5172 continue; 5173 } 5174 5175 if (ANSWER(rdataset) && need_validation) { 5176 if (fctx->type != dns_rdatatype_any && 5177 fctx->type != dns_rdatatype_rrsig && 5178 fctx->type != dns_rdatatype_sig) { 5179 /* 5180 * This is The Answer. We will 5181 * validate it, but first we cache 5182 * the rest of the response - it may 5183 * contain useful keys. 5184 */ 5185 INSIST(valrdataset == NULL && 5186 valsigrdataset == NULL); 5187 valrdataset = rdataset; 5188 valsigrdataset = sigrdataset; 5189 } else { 5190 /* 5191 * This is one of (potentially) 5192 * multiple answers to an ANY 5193 * or SIG query. To keep things 5194 * simple, we just start the 5195 * validator right away rather 5196 * than caching first and 5197 * having to remember which 5198 * rdatasets needed validation. 5199 */ 5200 result = valcreate(fctx, addrinfo, 5201 name, rdataset->type, 5202 rdataset, 5203 sigrdataset, 5204 valoptions, task); 5205 /* 5206 * Defer any further validations. 5207 * This prevents multiple validators 5208 * from manipulating fctx->rmessage 5209 * simultaneously. 5210 */ 5211 valoptions |= DNS_VALIDATOR_DEFER; 5212 } 5213 } else if (CHAINING(rdataset)) { 5214 if (rdataset->type == dns_rdatatype_cname) 5215 eresult = DNS_R_CNAME; 5216 else { 5217 INSIST(rdataset->type == 5218 dns_rdatatype_dname); 5219 eresult = DNS_R_DNAME; 5220 } 5221 } 5222 } else if (!EXTERNAL(rdataset)) { 5223 /* 5224 * It's OK to cache this rdataset now. 5225 */ 5226 if (ANSWER(rdataset)) 5227 addedrdataset = ardataset; 5228 else if (ANSWERSIG(rdataset)) 5229 addedrdataset = asigrdataset; 5230 else 5231 addedrdataset = NULL; 5232 if (CHAINING(rdataset)) { 5233 if (rdataset->type == dns_rdatatype_cname) 5234 eresult = DNS_R_CNAME; 5235 else { 5236 INSIST(rdataset->type == 5237 dns_rdatatype_dname); 5238 eresult = DNS_R_DNAME; 5239 } 5240 } 5241 if (rdataset->trust == dns_trust_glue && 5242 (rdataset->type == dns_rdatatype_ns || 5243 (rdataset->type == dns_rdatatype_rrsig && 5244 rdataset->covers == dns_rdatatype_ns))) { 5245 /* 5246 * If the trust level is 'dns_trust_glue' 5247 * then we are adding data from a referral 5248 * we got while executing the search algorithm. 5249 * New referral data always takes precedence 5250 * over the existing cache contents. 5251 */ 5252 options = DNS_DBADD_FORCE; 5253 } else if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) 5254 options = DNS_DBADD_PREFETCH; 5255 else 5256 options = 0; 5257 5258 if (ANSWER(rdataset) && 5259 rdataset->type != dns_rdatatype_rrsig) { 5260 isc_result_t tresult; 5261 dns_name_t *noqname = NULL; 5262 tresult = findnoqname(fctx, name, 5263 rdataset->type, &noqname); 5264 if (tresult == ISC_R_SUCCESS && 5265 noqname != NULL) { 5266 tresult = dns_rdataset_addnoqname( 5267 rdataset, noqname); 5268 RUNTIME_CHECK(tresult == ISC_R_SUCCESS); 5269 } 5270 } 5271 5272 /* 5273 * Now we can add the rdataset. 5274 */ 5275 result = dns_db_addrdataset(fctx->cache, 5276 node, NULL, now, 5277 rdataset, 5278 options, 5279 addedrdataset); 5280 5281 if (result == DNS_R_UNCHANGED) { 5282 if (ANSWER(rdataset) && 5283 ardataset != NULL && 5284 NEGATIVE(ardataset)) { 5285 /* 5286 * The answer in the cache is better 5287 * than the answer we found, and is 5288 * a negative cache entry, so we 5289 * must set eresult appropriately. 5290 */ 5291 if (NXDOMAIN(ardataset)) 5292 eresult = DNS_R_NCACHENXDOMAIN; 5293 else 5294 eresult = DNS_R_NCACHENXRRSET; 5295 } 5296 result = ISC_R_SUCCESS; 5297 } else if (result != ISC_R_SUCCESS) 5298 break; 5299 } 5300 } 5301 5302 if (valrdataset != NULL) { 5303 dns_rdatatype_t vtype = fctx->type; 5304 if (CHAINING(valrdataset)) { 5305 if (valrdataset->type == dns_rdatatype_cname) 5306 vtype = dns_rdatatype_cname; 5307 else 5308 vtype = dns_rdatatype_dname; 5309 } 5310 result = valcreate(fctx, addrinfo, name, vtype, valrdataset, 5311 valsigrdataset, valoptions, task); 5312 } 5313 5314 if (result == ISC_R_SUCCESS && have_answer) { 5315 fctx->attributes |= FCTX_ATTR_HAVEANSWER; 5316 if (event != NULL) { 5317 /* 5318 * Negative results must be indicated in event->result. 5319 */ 5320 if (dns_rdataset_isassociated(event->rdataset) && 5321 NEGATIVE(event->rdataset)) { 5322 INSIST(eresult == DNS_R_NCACHENXDOMAIN || 5323 eresult == DNS_R_NCACHENXRRSET); 5324 } 5325 event->result = eresult; 5326 dns_db_attach(fctx->cache, adbp); 5327 dns_db_transfernode(fctx->cache, &node, anodep); 5328 clone_results(fctx); 5329 } 5330 } 5331 5332 if (node != NULL) 5333 dns_db_detachnode(fctx->cache, &node); 5334 5335 return (result); 5336 } 5337 5338 static inline isc_result_t 5339 cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) 5340 { 5341 isc_result_t result; 5342 dns_section_t section; 5343 dns_name_t *name; 5344 5345 FCTXTRACE("cache_message"); 5346 5347 fctx->attributes &= ~FCTX_ATTR_WANTCACHE; 5348 5349 LOCK(&fctx->res->buckets[fctx->bucketnum].lock); 5350 5351 for (section = DNS_SECTION_ANSWER; 5352 section <= DNS_SECTION_ADDITIONAL; 5353 section++) { 5354 result = dns_message_firstname(fctx->rmessage, section); 5355 while (result == ISC_R_SUCCESS) { 5356 name = NULL; 5357 dns_message_currentname(fctx->rmessage, section, 5358 &name); 5359 if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) { 5360 result = cache_name(fctx, name, addrinfo, now); 5361 if (result != ISC_R_SUCCESS) 5362 break; 5363 } 5364 result = dns_message_nextname(fctx->rmessage, section); 5365 } 5366 if (result != ISC_R_NOMORE) 5367 break; 5368 } 5369 if (result == ISC_R_NOMORE) 5370 result = ISC_R_SUCCESS; 5371 5372 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); 5373 5374 return (result); 5375 } 5376 5377 /* 5378 * Do what dns_ncache_addoptout() does, and then compute an appropriate eresult. 5379 */ 5380 static isc_result_t 5381 ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, 5382 dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, 5383 isc_boolean_t optout, isc_boolean_t secure, 5384 dns_rdataset_t *ardataset, isc_result_t *eresultp) 5385 { 5386 isc_result_t result; 5387 dns_rdataset_t rdataset; 5388 5389 if (ardataset == NULL) { 5390 dns_rdataset_init(&rdataset); 5391 ardataset = &rdataset; 5392 } 5393 if (secure) 5394 result = dns_ncache_addoptout(message, cache, node, covers, 5395 now, maxttl, optout, ardataset); 5396 else 5397 result = dns_ncache_add(message, cache, node, covers, now, 5398 maxttl, ardataset); 5399 if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) { 5400 /* 5401 * If the cache now contains a negative entry and we 5402 * care about whether it is DNS_R_NCACHENXDOMAIN or 5403 * DNS_R_NCACHENXRRSET then extract it. 5404 */ 5405 if (NEGATIVE(ardataset)) { 5406 /* 5407 * The cache data is a negative cache entry. 5408 */ 5409 if (NXDOMAIN(ardataset)) 5410 *eresultp = DNS_R_NCACHENXDOMAIN; 5411 else 5412 *eresultp = DNS_R_NCACHENXRRSET; 5413 } else { 5414 /* 5415 * Either we don't care about the nature of the 5416 * cache rdataset (because no fetch is interested 5417 * in the outcome), or the cache rdataset is not 5418 * a negative cache entry. Whichever case it is, 5419 * we can return success. 5420 * 5421 * XXXRTH There's a CNAME/DNAME problem here. 5422 */ 5423 *eresultp = ISC_R_SUCCESS; 5424 } 5425 result = ISC_R_SUCCESS; 5426 } 5427 if (ardataset == &rdataset && dns_rdataset_isassociated(ardataset)) 5428 dns_rdataset_disassociate(ardataset); 5429 5430 return (result); 5431 } 5432 5433 static inline isc_result_t 5434 ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, 5435 dns_rdatatype_t covers, isc_stdtime_t now) 5436 { 5437 isc_result_t result, eresult; 5438 dns_name_t *name; 5439 dns_resolver_t *res; 5440 dns_db_t **adbp; 5441 dns_dbnode_t *node, **anodep; 5442 dns_rdataset_t *ardataset; 5443 isc_boolean_t need_validation, secure_domain; 5444 dns_name_t *aname; 5445 dns_fetchevent_t *event; 5446 isc_uint32_t ttl; 5447 unsigned int valoptions = 0; 5448 5449 FCTXTRACE("ncache_message"); 5450 5451 fctx->attributes &= ~FCTX_ATTR_WANTNCACHE; 5452 5453 res = fctx->res; 5454 need_validation = ISC_FALSE; 5455 POST(need_validation); 5456 secure_domain = ISC_FALSE; 5457 eresult = ISC_R_SUCCESS; 5458 name = &fctx->name; 5459 node = NULL; 5460 5461 /* 5462 * XXXMPA remove when we follow cnames and adjust the setting 5463 * of FCTX_ATTR_WANTNCACHE in noanswer_response(). 5464 */ 5465 INSIST(fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0); 5466 5467 /* 5468 * Is DNSSEC validation required for this name? 5469 */ 5470 if (fctx->res->view->enablevalidation) { 5471 result = dns_view_issecuredomain(res->view, name, 5472 &secure_domain); 5473 if (result != ISC_R_SUCCESS) 5474 return (result); 5475 5476 if (!secure_domain && res->view->dlv != NULL) { 5477 valoptions = DNS_VALIDATOR_DLV; 5478 secure_domain = ISC_TRUE; 5479 } 5480 } 5481 5482 if ((fctx->options & DNS_FETCHOPT_NOCDFLAG) != 0) 5483 valoptions |= DNS_VALIDATOR_NOCDFLAG; 5484 5485 if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) 5486 need_validation = ISC_FALSE; 5487 else 5488 need_validation = secure_domain; 5489 5490 if (secure_domain) { 5491 /* 5492 * Mark all rdatasets as pending. 5493 */ 5494 dns_rdataset_t *trdataset; 5495 dns_name_t *tname; 5496 5497 result = dns_message_firstname(fctx->rmessage, 5498 DNS_SECTION_AUTHORITY); 5499 while (result == ISC_R_SUCCESS) { 5500 tname = NULL; 5501 dns_message_currentname(fctx->rmessage, 5502 DNS_SECTION_AUTHORITY, 5503 &tname); 5504 for (trdataset = ISC_LIST_HEAD(tname->list); 5505 trdataset != NULL; 5506 trdataset = ISC_LIST_NEXT(trdataset, link)) 5507 trdataset->trust = dns_trust_pending_answer; 5508 result = dns_message_nextname(fctx->rmessage, 5509 DNS_SECTION_AUTHORITY); 5510 } 5511 if (result != ISC_R_NOMORE) 5512 return (result); 5513 5514 } 5515 5516 if (need_validation) { 5517 /* 5518 * Do negative response validation. 5519 */ 5520 result = valcreate(fctx, addrinfo, name, fctx->type, 5521 NULL, NULL, valoptions, 5522 res->buckets[fctx->bucketnum].task); 5523 /* 5524 * If validation is necessary, return now. Otherwise continue 5525 * to process the message, letting the validation complete 5526 * in its own good time. 5527 */ 5528 return (result); 5529 } 5530 5531 LOCK(&res->buckets[fctx->bucketnum].lock); 5532 5533 adbp = NULL; 5534 aname = NULL; 5535 anodep = NULL; 5536 ardataset = NULL; 5537 if (!HAVE_ANSWER(fctx)) { 5538 event = ISC_LIST_HEAD(fctx->events); 5539 if (event != NULL) { 5540 adbp = &event->db; 5541 aname = dns_fixedname_name(&event->foundname); 5542 result = dns_name_copy(name, aname, NULL); 5543 if (result != ISC_R_SUCCESS) 5544 goto unlock; 5545 anodep = &event->node; 5546 ardataset = event->rdataset; 5547 } 5548 } else 5549 event = NULL; 5550 5551 result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node); 5552 if (result != ISC_R_SUCCESS) 5553 goto unlock; 5554 5555 /* 5556 * If we are asking for a SOA record set the cache time 5557 * to zero to facilitate locating the containing zone of 5558 * a arbitrary zone. 5559 */ 5560 ttl = fctx->res->view->maxncachettl; 5561 if (fctx->type == dns_rdatatype_soa && 5562 covers == dns_rdatatype_any && 5563 fctx->res->zero_no_soa_ttl) 5564 ttl = 0; 5565 5566 result = ncache_adderesult(fctx->rmessage, fctx->cache, node, 5567 covers, now, ttl, ISC_FALSE, 5568 ISC_FALSE, ardataset, &eresult); 5569 if (result != ISC_R_SUCCESS) 5570 goto unlock; 5571 5572 if (!HAVE_ANSWER(fctx)) { 5573 fctx->attributes |= FCTX_ATTR_HAVEANSWER; 5574 if (event != NULL) { 5575 event->result = eresult; 5576 dns_db_attach(fctx->cache, adbp); 5577 dns_db_transfernode(fctx->cache, &node, anodep); 5578 clone_results(fctx); 5579 } 5580 } 5581 5582 unlock: 5583 UNLOCK(&res->buckets[fctx->bucketnum].lock); 5584 5585 if (node != NULL) 5586 dns_db_detachnode(fctx->cache, &node); 5587 5588 return (result); 5589 } 5590 5591 static inline void 5592 mark_related(dns_name_t *name, dns_rdataset_t *rdataset, 5593 isc_boolean_t external, isc_boolean_t gluing) 5594 { 5595 name->attributes |= DNS_NAMEATTR_CACHE; 5596 if (gluing) { 5597 rdataset->trust = dns_trust_glue; 5598 /* 5599 * Glue with 0 TTL causes problems. We force the TTL to 5600 * 1 second to prevent this. 5601 */ 5602 if (rdataset->ttl == 0) 5603 rdataset->ttl = 1; 5604 } else 5605 rdataset->trust = dns_trust_additional; 5606 /* 5607 * Avoid infinite loops by only marking new rdatasets. 5608 */ 5609 if (!CACHE(rdataset)) { 5610 name->attributes |= DNS_NAMEATTR_CHASE; 5611 rdataset->attributes |= DNS_RDATASETATTR_CHASE; 5612 } 5613 rdataset->attributes |= DNS_RDATASETATTR_CACHE; 5614 if (external) 5615 rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL; 5616 } 5617 5618 static isc_result_t 5619 check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type, 5620 dns_section_t section) 5621 { 5622 fetchctx_t *fctx = arg; 5623 isc_result_t result; 5624 dns_name_t *name; 5625 dns_rdataset_t *rdataset; 5626 isc_boolean_t external; 5627 dns_rdatatype_t rtype; 5628 isc_boolean_t gluing; 5629 5630 REQUIRE(VALID_FCTX(fctx)); 5631 5632 #if CHECK_FOR_GLUE_IN_ANSWER 5633 if (section == DNS_SECTION_ANSWER && type != dns_rdatatype_a) 5634 return (ISC_R_SUCCESS); 5635 #endif 5636 5637 if (GLUING(fctx)) 5638 gluing = ISC_TRUE; 5639 else 5640 gluing = ISC_FALSE; 5641 name = NULL; 5642 rdataset = NULL; 5643 result = dns_message_findname(fctx->rmessage, section, addname, 5644 dns_rdatatype_any, 0, &name, NULL); 5645 if (result == ISC_R_SUCCESS) { 5646 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain)); 5647 if (type == dns_rdatatype_a) { 5648 for (rdataset = ISC_LIST_HEAD(name->list); 5649 rdataset != NULL; 5650 rdataset = ISC_LIST_NEXT(rdataset, link)) { 5651 if (rdataset->type == dns_rdatatype_rrsig) 5652 rtype = rdataset->covers; 5653 else 5654 rtype = rdataset->type; 5655 if (rtype == dns_rdatatype_a || 5656 rtype == dns_rdatatype_aaaa) 5657 mark_related(name, rdataset, external, 5658 gluing); 5659 } 5660 } else { 5661 result = dns_message_findtype(name, type, 0, 5662 &rdataset); 5663 if (result == ISC_R_SUCCESS) { 5664 mark_related(name, rdataset, external, gluing); 5665 /* 5666 * Do we have its SIG too? 5667 */ 5668 rdataset = NULL; 5669 result = dns_message_findtype(name, 5670 dns_rdatatype_rrsig, 5671 type, &rdataset); 5672 if (result == ISC_R_SUCCESS) 5673 mark_related(name, rdataset, external, 5674 gluing); 5675 } 5676 } 5677 } 5678 5679 return (ISC_R_SUCCESS); 5680 } 5681 5682 static isc_result_t 5683 check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) { 5684 return (check_section(arg, addname, type, DNS_SECTION_ADDITIONAL)); 5685 } 5686 5687 #ifndef CHECK_FOR_GLUE_IN_ANSWER 5688 #define CHECK_FOR_GLUE_IN_ANSWER 0 5689 #endif 5690 #if CHECK_FOR_GLUE_IN_ANSWER 5691 static isc_result_t 5692 check_answer(void *arg, dns_name_t *addname, dns_rdatatype_t type) { 5693 return (check_section(arg, addname, type, DNS_SECTION_ANSWER)); 5694 } 5695 #endif 5696 5697 static void 5698 chase_additional(fetchctx_t *fctx) { 5699 isc_boolean_t rescan; 5700 dns_section_t section = DNS_SECTION_ADDITIONAL; 5701 isc_result_t result; 5702 5703 again: 5704 rescan = ISC_FALSE; 5705 5706 for (result = dns_message_firstname(fctx->rmessage, section); 5707 result == ISC_R_SUCCESS; 5708 result = dns_message_nextname(fctx->rmessage, section)) { 5709 dns_name_t *name = NULL; 5710 dns_rdataset_t *rdataset; 5711 dns_message_currentname(fctx->rmessage, DNS_SECTION_ADDITIONAL, 5712 &name); 5713 if ((name->attributes & DNS_NAMEATTR_CHASE) == 0) 5714 continue; 5715 name->attributes &= ~DNS_NAMEATTR_CHASE; 5716 for (rdataset = ISC_LIST_HEAD(name->list); 5717 rdataset != NULL; 5718 rdataset = ISC_LIST_NEXT(rdataset, link)) { 5719 if (CHASE(rdataset)) { 5720 rdataset->attributes &= ~DNS_RDATASETATTR_CHASE; 5721 (void)dns_rdataset_additionaldata(rdataset, 5722 check_related, 5723 fctx); 5724 rescan = ISC_TRUE; 5725 } 5726 } 5727 } 5728 if (rescan) 5729 goto again; 5730 } 5731 5732 static inline isc_result_t 5733 cname_target(dns_rdataset_t *rdataset, dns_name_t *tname) { 5734 isc_result_t result; 5735 dns_rdata_t rdata = DNS_RDATA_INIT; 5736 dns_rdata_cname_t cname; 5737 5738 result = dns_rdataset_first(rdataset); 5739 if (result != ISC_R_SUCCESS) 5740 return (result); 5741 dns_rdataset_current(rdataset, &rdata); 5742 result = dns_rdata_tostruct(&rdata, &cname, NULL); 5743 if (result != ISC_R_SUCCESS) 5744 return (result); 5745 dns_name_init(tname, NULL); 5746 dns_name_clone(&cname.cname, tname); 5747 dns_rdata_freestruct(&cname); 5748 5749 return (ISC_R_SUCCESS); 5750 } 5751 5752 static inline isc_result_t 5753 dname_target(fetchctx_t *fctx, dns_rdataset_t *rdataset, dns_name_t *qname, 5754 dns_name_t *oname, dns_fixedname_t *fixeddname) 5755 { 5756 isc_result_t result; 5757 dns_rdata_t rdata = DNS_RDATA_INIT; 5758 unsigned int nlabels; 5759 int order; 5760 dns_namereln_t namereln; 5761 dns_rdata_dname_t dname; 5762 dns_fixedname_t prefix; 5763 5764 /* 5765 * Get the target name of the DNAME. 5766 */ 5767 result = dns_rdataset_first(rdataset); 5768 if (result != ISC_R_SUCCESS) 5769 return (result); 5770 dns_rdataset_current(rdataset, &rdata); 5771 result = dns_rdata_tostruct(&rdata, &dname, NULL); 5772 if (result != ISC_R_SUCCESS) 5773 return (result); 5774 5775 /* 5776 * Get the prefix of qname. 5777 */ 5778 namereln = dns_name_fullcompare(qname, oname, &order, &nlabels); 5779 if (namereln != dns_namereln_subdomain) { 5780 char qbuf[DNS_NAME_FORMATSIZE]; 5781 char obuf[DNS_NAME_FORMATSIZE]; 5782 5783 dns_rdata_freestruct(&dname); 5784 dns_name_format(qname, qbuf, sizeof(qbuf)); 5785 dns_name_format(oname, obuf, sizeof(obuf)); 5786 log_formerr(fctx, "unrelated DNAME in answer: " 5787 "%s is not in %s", qbuf, obuf); 5788 return (DNS_R_FORMERR); 5789 } 5790 dns_fixedname_init(&prefix); 5791 dns_name_split(qname, nlabels, dns_fixedname_name(&prefix), NULL); 5792 dns_fixedname_init(fixeddname); 5793 result = dns_name_concatenate(dns_fixedname_name(&prefix), 5794 &dname.dname, 5795 dns_fixedname_name(fixeddname), NULL); 5796 dns_rdata_freestruct(&dname); 5797 return (result); 5798 } 5799 5800 static isc_boolean_t 5801 is_answeraddress_allowed(dns_view_t *view, dns_name_t *name, 5802 dns_rdataset_t *rdataset) 5803 { 5804 isc_result_t result; 5805 dns_rdata_t rdata = DNS_RDATA_INIT; 5806 struct in_addr ina; 5807 struct in6_addr in6a; 5808 isc_netaddr_t netaddr; 5809 char addrbuf[ISC_NETADDR_FORMATSIZE]; 5810 char namebuf[DNS_NAME_FORMATSIZE]; 5811 char classbuf[64]; 5812 char typebuf[64]; 5813 int match; 5814 5815 /* By default, we allow any addresses. */ 5816 if (view->denyansweracl == NULL) 5817 return (ISC_TRUE); 5818 5819 /* 5820 * If the owner name matches one in the exclusion list, either exactly 5821 * or partially, allow it. 5822 */ 5823 if (view->answeracl_exclude != NULL) { 5824 dns_rbtnode_t *node = NULL; 5825 5826 result = dns_rbt_findnode(view->answeracl_exclude, name, NULL, 5827 &node, NULL, 0, NULL, NULL); 5828 5829 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 5830 return (ISC_TRUE); 5831 } 5832 5833 /* 5834 * Otherwise, search the filter list for a match for each address 5835 * record. If a match is found, the address should be filtered, 5836 * so should the entire answer. 5837 */ 5838 for (result = dns_rdataset_first(rdataset); 5839 result == ISC_R_SUCCESS; 5840 result = dns_rdataset_next(rdataset)) { 5841 dns_rdata_reset(&rdata); 5842 dns_rdataset_current(rdataset, &rdata); 5843 if (rdataset->type == dns_rdatatype_a) { 5844 INSIST(rdata.length == sizeof(ina.s_addr)); 5845 memmove(&ina.s_addr, rdata.data, sizeof(ina.s_addr)); 5846 isc_netaddr_fromin(&netaddr, &ina); 5847 } else { 5848 INSIST(rdata.length == sizeof(in6a.s6_addr)); 5849 memmove(in6a.s6_addr, rdata.data, sizeof(in6a.s6_addr)); 5850 isc_netaddr_fromin6(&netaddr, &in6a); 5851 } 5852 5853 result = dns_acl_match(&netaddr, NULL, view->denyansweracl, 5854 &view->aclenv, &match, NULL); 5855 5856 if (result == ISC_R_SUCCESS && match > 0) { 5857 isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); 5858 dns_name_format(name, namebuf, sizeof(namebuf)); 5859 dns_rdatatype_format(rdataset->type, typebuf, 5860 sizeof(typebuf)); 5861 dns_rdataclass_format(rdataset->rdclass, classbuf, 5862 sizeof(classbuf)); 5863 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 5864 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, 5865 "answer address %s denied for %s/%s/%s", 5866 addrbuf, namebuf, typebuf, classbuf); 5867 return (ISC_FALSE); 5868 } 5869 } 5870 5871 return (ISC_TRUE); 5872 } 5873 5874 static isc_boolean_t 5875 is_answertarget_allowed(dns_view_t *view, dns_name_t *name, 5876 dns_rdatatype_t type, dns_name_t *tname, 5877 dns_name_t *domain) 5878 { 5879 isc_result_t result; 5880 dns_rbtnode_t *node = NULL; 5881 char qnamebuf[DNS_NAME_FORMATSIZE]; 5882 char tnamebuf[DNS_NAME_FORMATSIZE]; 5883 char classbuf[64]; 5884 char typebuf[64]; 5885 5886 /* By default, we allow any target name. */ 5887 if (view->denyanswernames == NULL) 5888 return (ISC_TRUE); 5889 5890 /* 5891 * If the owner name matches one in the exclusion list, either exactly 5892 * or partially, allow it. 5893 */ 5894 if (view->answernames_exclude != NULL) { 5895 result = dns_rbt_findnode(view->answernames_exclude, name, NULL, 5896 &node, NULL, 0, NULL, NULL); 5897 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 5898 return (ISC_TRUE); 5899 } 5900 5901 /* 5902 * If the target name is a subdomain of the search domain, allow it. 5903 */ 5904 if (dns_name_issubdomain(tname, domain)) 5905 return (ISC_TRUE); 5906 5907 /* 5908 * Otherwise, apply filters. 5909 */ 5910 result = dns_rbt_findnode(view->denyanswernames, tname, NULL, &node, 5911 NULL, 0, NULL, NULL); 5912 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 5913 dns_name_format(name, qnamebuf, sizeof(qnamebuf)); 5914 dns_name_format(tname, tnamebuf, sizeof(tnamebuf)); 5915 dns_rdatatype_format(type, typebuf, sizeof(typebuf)); 5916 dns_rdataclass_format(view->rdclass, classbuf, 5917 sizeof(classbuf)); 5918 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 5919 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, 5920 "%s target %s denied for %s/%s", 5921 typebuf, tnamebuf, qnamebuf, classbuf); 5922 return (ISC_FALSE); 5923 } 5924 5925 return (ISC_TRUE); 5926 } 5927 5928 static void 5929 trim_ns_ttl(fetchctx_t *fctx, dns_name_t *name, dns_rdataset_t *rdataset) { 5930 char ns_namebuf[DNS_NAME_FORMATSIZE]; 5931 char namebuf[DNS_NAME_FORMATSIZE]; 5932 char tbuf[DNS_RDATATYPE_FORMATSIZE]; 5933 5934 if (fctx->ns_ttl_ok && rdataset->ttl > fctx->ns_ttl) { 5935 dns_name_format(name, ns_namebuf, sizeof(ns_namebuf)); 5936 dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); 5937 dns_rdatatype_format(fctx->type, tbuf, sizeof(tbuf)); 5938 5939 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 5940 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10), 5941 "fctx %p: trimming ttl of %s/NS for %s/%s: " 5942 "%u -> %u", fctx, ns_namebuf, namebuf, tbuf, 5943 rdataset->ttl, fctx->ns_ttl); 5944 rdataset->ttl = fctx->ns_ttl; 5945 } 5946 } 5947 5948 /* 5949 * Handle a no-answer response (NXDOMAIN, NXRRSET, or referral). 5950 * If look_in_options has LOOK_FOR_NS_IN_ANSWER then we look in the answer 5951 * section for the NS RRset if the query type is NS; if it has 5952 * LOOK_FOR_GLUE_IN_ANSWER we look for glue incorrectly returned in the answer 5953 * section for A and AAAA queries. 5954 */ 5955 #define LOOK_FOR_NS_IN_ANSWER 0x1 5956 #define LOOK_FOR_GLUE_IN_ANSWER 0x2 5957 5958 static isc_result_t 5959 noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, 5960 unsigned int look_in_options) 5961 { 5962 isc_result_t result; 5963 dns_message_t *message; 5964 dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name, *save_name; 5965 dns_rdataset_t *rdataset, *ns_rdataset; 5966 isc_boolean_t aa, negative_response; 5967 dns_rdatatype_t type, save_type; 5968 dns_section_t section; 5969 5970 FCTXTRACE("noanswer_response"); 5971 5972 if ((look_in_options & LOOK_FOR_NS_IN_ANSWER) != 0) { 5973 INSIST(fctx->type == dns_rdatatype_ns); 5974 section = DNS_SECTION_ANSWER; 5975 } else 5976 section = DNS_SECTION_AUTHORITY; 5977 5978 message = fctx->rmessage; 5979 5980 /* 5981 * Setup qname. 5982 */ 5983 if (oqname == NULL) { 5984 /* 5985 * We have a normal, non-chained negative response or 5986 * referral. 5987 */ 5988 if ((message->flags & DNS_MESSAGEFLAG_AA) != 0) 5989 aa = ISC_TRUE; 5990 else 5991 aa = ISC_FALSE; 5992 qname = &fctx->name; 5993 } else { 5994 /* 5995 * We're being invoked by answer_response() after it has 5996 * followed a CNAME/DNAME chain. 5997 */ 5998 qname = oqname; 5999 aa = ISC_FALSE; 6000 /* 6001 * If the current qname is not a subdomain of the query 6002 * domain, there's no point in looking at the authority 6003 * section without doing DNSSEC validation. 6004 * 6005 * Until we do that validation, we'll just return success 6006 * in this case. 6007 */ 6008 if (!dns_name_issubdomain(qname, &fctx->domain)) 6009 return (ISC_R_SUCCESS); 6010 } 6011 6012 /* 6013 * We have to figure out if this is a negative response, or a 6014 * referral. 6015 */ 6016 6017 /* 6018 * Sometimes we can tell if its a negative response by looking at 6019 * the message header. 6020 */ 6021 negative_response = ISC_FALSE; 6022 if (message->rcode == dns_rcode_nxdomain || 6023 (message->counts[DNS_SECTION_ANSWER] == 0 && 6024 message->counts[DNS_SECTION_AUTHORITY] == 0)) 6025 negative_response = ISC_TRUE; 6026 6027 /* 6028 * Process the authority section. 6029 */ 6030 ns_name = NULL; 6031 ns_rdataset = NULL; 6032 soa_name = NULL; 6033 ds_name = NULL; 6034 save_name = NULL; 6035 save_type = dns_rdatatype_none; 6036 result = dns_message_firstname(message, section); 6037 while (result == ISC_R_SUCCESS) { 6038 name = NULL; 6039 dns_message_currentname(message, section, &name); 6040 if (dns_name_issubdomain(name, &fctx->domain)) { 6041 /* 6042 * Look for NS/SOA RRsets first. 6043 */ 6044 for (rdataset = ISC_LIST_HEAD(name->list); 6045 rdataset != NULL; 6046 rdataset = ISC_LIST_NEXT(rdataset, link)) { 6047 type = rdataset->type; 6048 if (type == dns_rdatatype_rrsig) 6049 type = rdataset->covers; 6050 if (((type == dns_rdatatype_ns || 6051 type == dns_rdatatype_soa) && 6052 !dns_name_issubdomain(qname, name))) { 6053 char qbuf[DNS_NAME_FORMATSIZE]; 6054 char nbuf[DNS_NAME_FORMATSIZE]; 6055 char tbuf[DNS_RDATATYPE_FORMATSIZE]; 6056 dns_rdatatype_format(type, tbuf, 6057 sizeof(tbuf)); 6058 dns_name_format(name, nbuf, 6059 sizeof(nbuf)); 6060 dns_name_format(qname, qbuf, 6061 sizeof(qbuf)); 6062 log_formerr(fctx, 6063 "unrelated %s %s in " 6064 "%s authority section", 6065 tbuf, nbuf, qbuf); 6066 goto nextname; 6067 } 6068 if (type == dns_rdatatype_ns) { 6069 /* 6070 * NS or RRSIG NS. 6071 * 6072 * Only one set of NS RRs is allowed. 6073 */ 6074 if (rdataset->type == 6075 dns_rdatatype_ns) { 6076 if (ns_name != NULL && 6077 name != ns_name) { 6078 log_formerr(fctx, 6079 "multiple NS " 6080 "RRsets in " 6081 "authority " 6082 "section"); 6083 return (DNS_R_FORMERR); 6084 } 6085 ns_name = name; 6086 ns_rdataset = rdataset; 6087 } 6088 name->attributes |= 6089 DNS_NAMEATTR_CACHE; 6090 rdataset->attributes |= 6091 DNS_RDATASETATTR_CACHE; 6092 rdataset->trust = dns_trust_glue; 6093 } 6094 if (type == dns_rdatatype_soa) { 6095 /* 6096 * SOA, or RRSIG SOA. 6097 * 6098 * Only one SOA is allowed. 6099 */ 6100 if (rdataset->type == 6101 dns_rdatatype_soa) { 6102 if (soa_name != NULL && 6103 name != soa_name) { 6104 log_formerr(fctx, 6105 "multiple SOA " 6106 "RRs in " 6107 "authority " 6108 "section"); 6109 return (DNS_R_FORMERR); 6110 } 6111 soa_name = name; 6112 } 6113 name->attributes |= 6114 DNS_NAMEATTR_NCACHE; 6115 rdataset->attributes |= 6116 DNS_RDATASETATTR_NCACHE; 6117 if (aa) 6118 rdataset->trust = 6119 dns_trust_authauthority; 6120 else if (ISFORWARDER(fctx->addrinfo)) 6121 rdataset->trust = 6122 dns_trust_answer; 6123 else 6124 rdataset->trust = 6125 dns_trust_additional; 6126 } 6127 } 6128 } 6129 nextname: 6130 result = dns_message_nextname(message, section); 6131 if (result == ISC_R_NOMORE) 6132 break; 6133 else if (result != ISC_R_SUCCESS) 6134 return (result); 6135 } 6136 6137 log_ns_ttl(fctx, "noanswer_response"); 6138 6139 if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) && 6140 !dns_name_equal(ns_name, dns_rootname)) 6141 trim_ns_ttl(fctx, ns_name, ns_rdataset); 6142 6143 /* 6144 * A negative response has a SOA record (Type 2) 6145 * and a optional NS RRset (Type 1) or it has neither 6146 * a SOA or a NS RRset (Type 3, handled above) or 6147 * rcode is NXDOMAIN (handled above) in which case 6148 * the NS RRset is allowed (Type 4). 6149 */ 6150 if (soa_name != NULL) 6151 negative_response = ISC_TRUE; 6152 6153 result = dns_message_firstname(message, section); 6154 while (result == ISC_R_SUCCESS) { 6155 name = NULL; 6156 dns_message_currentname(message, section, &name); 6157 if (dns_name_issubdomain(name, &fctx->domain)) { 6158 for (rdataset = ISC_LIST_HEAD(name->list); 6159 rdataset != NULL; 6160 rdataset = ISC_LIST_NEXT(rdataset, link)) { 6161 type = rdataset->type; 6162 if (type == dns_rdatatype_rrsig) 6163 type = rdataset->covers; 6164 if (type == dns_rdatatype_nsec || 6165 type == dns_rdatatype_nsec3) { 6166 /* 6167 * NSEC or RRSIG NSEC. 6168 */ 6169 if (negative_response) { 6170 name->attributes |= 6171 DNS_NAMEATTR_NCACHE; 6172 rdataset->attributes |= 6173 DNS_RDATASETATTR_NCACHE; 6174 } else if (type == dns_rdatatype_nsec) { 6175 name->attributes |= 6176 DNS_NAMEATTR_CACHE; 6177 rdataset->attributes |= 6178 DNS_RDATASETATTR_CACHE; 6179 } 6180 if (aa) 6181 rdataset->trust = 6182 dns_trust_authauthority; 6183 else if (ISFORWARDER(fctx->addrinfo)) 6184 rdataset->trust = 6185 dns_trust_answer; 6186 else 6187 rdataset->trust = 6188 dns_trust_additional; 6189 /* 6190 * No additional data needs to be 6191 * marked. 6192 */ 6193 } else if (type == dns_rdatatype_ds) { 6194 /* 6195 * DS or SIG DS. 6196 * 6197 * These should only be here if 6198 * this is a referral, and there 6199 * should only be one DS RRset. 6200 */ 6201 if (ns_name == NULL) { 6202 log_formerr(fctx, 6203 "DS with no " 6204 "referral"); 6205 return (DNS_R_FORMERR); 6206 } 6207 if (rdataset->type == 6208 dns_rdatatype_ds) { 6209 if (ds_name != NULL && 6210 name != ds_name) { 6211 log_formerr(fctx, 6212 "DS doesn't " 6213 "match " 6214 "referral " 6215 "(NS)"); 6216 return (DNS_R_FORMERR); 6217 } 6218 ds_name = name; 6219 } 6220 name->attributes |= 6221 DNS_NAMEATTR_CACHE; 6222 rdataset->attributes |= 6223 DNS_RDATASETATTR_CACHE; 6224 if (aa) 6225 rdataset->trust = 6226 dns_trust_authauthority; 6227 else if (ISFORWARDER(fctx->addrinfo)) 6228 rdataset->trust = 6229 dns_trust_answer; 6230 else 6231 rdataset->trust = 6232 dns_trust_additional; 6233 } 6234 } 6235 } else { 6236 save_name = name; 6237 save_type = ISC_LIST_HEAD(name->list)->type; 6238 } 6239 result = dns_message_nextname(message, section); 6240 if (result == ISC_R_NOMORE) 6241 break; 6242 else if (result != ISC_R_SUCCESS) 6243 return (result); 6244 } 6245 6246 /* 6247 * Trigger lookups for DNS nameservers. 6248 */ 6249 if (negative_response && message->rcode == dns_rcode_noerror && 6250 fctx->type == dns_rdatatype_ds && soa_name != NULL && 6251 dns_name_equal(soa_name, qname) && 6252 !dns_name_equal(qname, dns_rootname)) 6253 return (DNS_R_CHASEDSSERVERS); 6254 6255 /* 6256 * Did we find anything? 6257 */ 6258 if (!negative_response && ns_name == NULL) { 6259 /* 6260 * Nope. 6261 */ 6262 if (oqname != NULL) { 6263 /* 6264 * We've already got a partial CNAME/DNAME chain, 6265 * and haven't found else anything useful here, but 6266 * no error has occurred since we have an answer. 6267 */ 6268 return (ISC_R_SUCCESS); 6269 } else { 6270 /* 6271 * The responder is insane. 6272 */ 6273 if (save_name == NULL) { 6274 log_formerr(fctx, "invalid response"); 6275 return (DNS_R_FORMERR); 6276 } 6277 if (!dns_name_issubdomain(save_name, &fctx->domain)) { 6278 char nbuf[DNS_NAME_FORMATSIZE]; 6279 char dbuf[DNS_NAME_FORMATSIZE]; 6280 char tbuf[DNS_RDATATYPE_FORMATSIZE]; 6281 6282 dns_rdatatype_format(save_type, tbuf, 6283 sizeof(tbuf)); 6284 dns_name_format(save_name, nbuf, sizeof(nbuf)); 6285 dns_name_format(&fctx->domain, dbuf, 6286 sizeof(dbuf)); 6287 6288 log_formerr(fctx, "Name %s (%s) not subdomain" 6289 " of zone %s -- invalid response", 6290 nbuf, tbuf, dbuf); 6291 } else { 6292 log_formerr(fctx, "invalid response"); 6293 } 6294 return (DNS_R_FORMERR); 6295 } 6296 } 6297 6298 /* 6299 * If we found both NS and SOA, they should be the same name. 6300 */ 6301 if (ns_name != NULL && soa_name != NULL && ns_name != soa_name) { 6302 log_formerr(fctx, "NS/SOA mismatch"); 6303 return (DNS_R_FORMERR); 6304 } 6305 6306 /* 6307 * Do we have a referral? (We only want to follow a referral if 6308 * we're not following a chain.) 6309 */ 6310 if (!negative_response && ns_name != NULL && oqname == NULL) { 6311 /* 6312 * We already know ns_name is a subdomain of fctx->domain. 6313 * If ns_name is equal to fctx->domain, we're not making 6314 * progress. We return DNS_R_FORMERR so that we'll keep 6315 * trying other servers. 6316 */ 6317 if (dns_name_equal(ns_name, &fctx->domain)) { 6318 log_formerr(fctx, "non-improving referral"); 6319 return (DNS_R_FORMERR); 6320 } 6321 6322 /* 6323 * If the referral name is not a parent of the query 6324 * name, consider the responder insane. 6325 */ 6326 if (! dns_name_issubdomain(&fctx->name, ns_name)) { 6327 /* Logged twice */ 6328 log_formerr(fctx, "referral to non-parent"); 6329 FCTXTRACE("referral to non-parent"); 6330 return (DNS_R_FORMERR); 6331 } 6332 6333 /* 6334 * Mark any additional data related to this rdataset. 6335 * It's important that we do this before we change the 6336 * query domain. 6337 */ 6338 INSIST(ns_rdataset != NULL); 6339 fctx->attributes |= FCTX_ATTR_GLUING; 6340 (void)dns_rdataset_additionaldata(ns_rdataset, check_related, 6341 fctx); 6342 #if CHECK_FOR_GLUE_IN_ANSWER 6343 /* 6344 * Look in the answer section for "glue" that is incorrectly 6345 * returned as a answer. This is needed if the server also 6346 * minimizes the response size by not adding records to the 6347 * additional section that are in the answer section or if 6348 * the record gets dropped due to message size constraints. 6349 */ 6350 if ((look_in_options & LOOK_FOR_GLUE_IN_ANSWER) != 0 && 6351 (fctx->type == dns_rdatatype_aaaa || 6352 fctx->type == dns_rdatatype_a)) 6353 (void)dns_rdataset_additionaldata(ns_rdataset, 6354 check_answer, fctx); 6355 #endif 6356 fctx->attributes &= ~FCTX_ATTR_GLUING; 6357 /* 6358 * NS rdatasets with 0 TTL cause problems. 6359 * dns_view_findzonecut() will not find them when we 6360 * try to follow the referral, and we'll SERVFAIL 6361 * because the best nameservers are now above QDOMAIN. 6362 * We force the TTL to 1 second to prevent this. 6363 */ 6364 if (ns_rdataset->ttl == 0) 6365 ns_rdataset->ttl = 1; 6366 /* 6367 * Set the current query domain to the referral name. 6368 * 6369 * XXXRTH We should check if we're in forward-only mode, and 6370 * if so we should bail out. 6371 */ 6372 INSIST(dns_name_countlabels(&fctx->domain) > 0); 6373 dns_name_free(&fctx->domain, fctx->mctx); 6374 if (dns_rdataset_isassociated(&fctx->nameservers)) 6375 dns_rdataset_disassociate(&fctx->nameservers); 6376 dns_name_init(&fctx->domain, NULL); 6377 result = dns_name_dup(ns_name, fctx->mctx, &fctx->domain); 6378 if (result != ISC_R_SUCCESS) 6379 return (result); 6380 fctx->attributes |= FCTX_ATTR_WANTCACHE; 6381 fctx->ns_ttl_ok = ISC_FALSE; 6382 log_ns_ttl(fctx, "DELEGATION"); 6383 return (DNS_R_DELEGATION); 6384 } 6385 6386 /* 6387 * Since we're not doing a referral, we don't want to cache any 6388 * NS RRs we may have found. 6389 */ 6390 if (ns_name != NULL) 6391 ns_name->attributes &= ~DNS_NAMEATTR_CACHE; 6392 6393 if (negative_response && oqname == NULL) 6394 fctx->attributes |= FCTX_ATTR_WANTNCACHE; 6395 6396 return (ISC_R_SUCCESS); 6397 } 6398 6399 static isc_result_t 6400 answer_response(fetchctx_t *fctx) { 6401 isc_result_t result; 6402 dns_message_t *message; 6403 dns_name_t *name, *qname, tname, *ns_name; 6404 dns_rdataset_t *rdataset, *ns_rdataset; 6405 isc_boolean_t done, external, chaining, aa, found, want_chaining; 6406 isc_boolean_t have_answer, found_cname, found_type, wanted_chaining; 6407 unsigned int aflag; 6408 dns_rdatatype_t type; 6409 dns_fixedname_t dname, fqname; 6410 dns_view_t *view; 6411 6412 FCTXTRACE("answer_response"); 6413 6414 message = fctx->rmessage; 6415 6416 /* 6417 * Examine the answer section, marking those rdatasets which are 6418 * part of the answer and should be cached. 6419 */ 6420 6421 done = ISC_FALSE; 6422 found_cname = ISC_FALSE; 6423 found_type = ISC_FALSE; 6424 chaining = ISC_FALSE; 6425 have_answer = ISC_FALSE; 6426 want_chaining = ISC_FALSE; 6427 POST(want_chaining); 6428 if ((message->flags & DNS_MESSAGEFLAG_AA) != 0) 6429 aa = ISC_TRUE; 6430 else 6431 aa = ISC_FALSE; 6432 qname = &fctx->name; 6433 type = fctx->type; 6434 view = fctx->res->view; 6435 result = dns_message_firstname(message, DNS_SECTION_ANSWER); 6436 while (!done && result == ISC_R_SUCCESS) { 6437 name = NULL; 6438 dns_message_currentname(message, DNS_SECTION_ANSWER, &name); 6439 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain)); 6440 if (dns_name_equal(name, qname)) { 6441 wanted_chaining = ISC_FALSE; 6442 for (rdataset = ISC_LIST_HEAD(name->list); 6443 rdataset != NULL; 6444 rdataset = ISC_LIST_NEXT(rdataset, link)) { 6445 found = ISC_FALSE; 6446 want_chaining = ISC_FALSE; 6447 aflag = 0; 6448 if (rdataset->type == dns_rdatatype_nsec3) { 6449 /* 6450 * NSEC3 records are not allowed to 6451 * appear in the answer section. 6452 */ 6453 log_formerr(fctx, "NSEC3 in answer"); 6454 return (DNS_R_FORMERR); 6455 } 6456 6457 /* 6458 * Apply filters, if given, on answers to reject 6459 * a malicious attempt of rebinding. 6460 */ 6461 if ((rdataset->type == dns_rdatatype_a || 6462 rdataset->type == dns_rdatatype_aaaa) && 6463 !is_answeraddress_allowed(view, name, 6464 rdataset)) { 6465 return (DNS_R_SERVFAIL); 6466 } 6467 6468 if (rdataset->type == type && !found_cname) { 6469 /* 6470 * We've found an ordinary answer. 6471 */ 6472 found = ISC_TRUE; 6473 found_type = ISC_TRUE; 6474 done = ISC_TRUE; 6475 aflag = DNS_RDATASETATTR_ANSWER; 6476 } else if (type == dns_rdatatype_any) { 6477 /* 6478 * We've found an answer matching 6479 * an ANY query. There may be 6480 * more. 6481 */ 6482 found = ISC_TRUE; 6483 aflag = DNS_RDATASETATTR_ANSWER; 6484 } else if (rdataset->type == dns_rdatatype_rrsig 6485 && rdataset->covers == type 6486 && !found_cname) { 6487 /* 6488 * We've found a signature that 6489 * covers the type we're looking for. 6490 */ 6491 found = ISC_TRUE; 6492 found_type = ISC_TRUE; 6493 aflag = DNS_RDATASETATTR_ANSWERSIG; 6494 } else if (rdataset->type == 6495 dns_rdatatype_cname 6496 && !found_type) { 6497 /* 6498 * We're looking for something else, 6499 * but we found a CNAME. 6500 * 6501 * Getting a CNAME response for some 6502 * query types is an error, see 6503 * RFC 4035, Section 2.5. 6504 */ 6505 if (type == dns_rdatatype_rrsig || 6506 type == dns_rdatatype_key || 6507 type == dns_rdatatype_nsec) { 6508 char buf[DNS_RDATATYPE_FORMATSIZE]; 6509 dns_rdatatype_format(fctx->type, 6510 buf, sizeof(buf)); 6511 log_formerr(fctx, 6512 "CNAME response " 6513 "for %s RR", buf); 6514 return (DNS_R_FORMERR); 6515 } 6516 found = ISC_TRUE; 6517 found_cname = ISC_TRUE; 6518 want_chaining = ISC_TRUE; 6519 aflag = DNS_RDATASETATTR_ANSWER; 6520 result = cname_target(rdataset, 6521 &tname); 6522 if (result != ISC_R_SUCCESS) 6523 return (result); 6524 /* Apply filters on the target name. */ 6525 if (!is_answertarget_allowed(view, 6526 name, 6527 rdataset->type, 6528 &tname, 6529 &fctx->domain)) { 6530 return (DNS_R_SERVFAIL); 6531 } 6532 } else if (rdataset->type == dns_rdatatype_rrsig 6533 && rdataset->covers == 6534 dns_rdatatype_cname 6535 && !found_type) { 6536 /* 6537 * We're looking for something else, 6538 * but we found a SIG CNAME. 6539 */ 6540 found = ISC_TRUE; 6541 found_cname = ISC_TRUE; 6542 aflag = DNS_RDATASETATTR_ANSWERSIG; 6543 } 6544 6545 if (found) { 6546 /* 6547 * We've found an answer to our 6548 * question. 6549 */ 6550 name->attributes |= 6551 DNS_NAMEATTR_CACHE; 6552 rdataset->attributes |= 6553 DNS_RDATASETATTR_CACHE; 6554 rdataset->trust = dns_trust_answer; 6555 if (!chaining) { 6556 /* 6557 * This data is "the" answer 6558 * to our question only if 6559 * we're not chaining (i.e. 6560 * if we haven't followed 6561 * a CNAME or DNAME). 6562 */ 6563 INSIST(!external); 6564 if (aflag == 6565 DNS_RDATASETATTR_ANSWER) 6566 have_answer = ISC_TRUE; 6567 name->attributes |= 6568 DNS_NAMEATTR_ANSWER; 6569 rdataset->attributes |= aflag; 6570 if (aa) 6571 rdataset->trust = 6572 dns_trust_authanswer; 6573 } else if (external) { 6574 /* 6575 * This data is outside of 6576 * our query domain, and 6577 * may not be cached. 6578 */ 6579 rdataset->attributes |= 6580 DNS_RDATASETATTR_EXTERNAL; 6581 } 6582 6583 /* 6584 * Mark any additional data related 6585 * to this rdataset. 6586 */ 6587 (void)dns_rdataset_additionaldata( 6588 rdataset, 6589 check_related, 6590 fctx); 6591 6592 /* 6593 * CNAME chaining. 6594 */ 6595 if (want_chaining) { 6596 wanted_chaining = ISC_TRUE; 6597 name->attributes |= 6598 DNS_NAMEATTR_CHAINING; 6599 rdataset->attributes |= 6600 DNS_RDATASETATTR_CHAINING; 6601 qname = &tname; 6602 } 6603 } 6604 /* 6605 * We could add an "else" clause here and 6606 * log that we're ignoring this rdataset. 6607 */ 6608 } 6609 /* 6610 * If wanted_chaining is true, we've done 6611 * some chaining as the result of processing 6612 * this node, and thus we need to set 6613 * chaining to true. 6614 * 6615 * We don't set chaining inside of the 6616 * rdataset loop because doing that would 6617 * cause us to ignore the signatures of 6618 * CNAMEs. 6619 */ 6620 if (wanted_chaining) 6621 chaining = ISC_TRUE; 6622 } else { 6623 /* 6624 * Look for a DNAME (or its SIG). Anything else is 6625 * ignored. 6626 */ 6627 wanted_chaining = ISC_FALSE; 6628 for (rdataset = ISC_LIST_HEAD(name->list); 6629 rdataset != NULL; 6630 rdataset = ISC_LIST_NEXT(rdataset, link)) { 6631 isc_boolean_t found_dname = ISC_FALSE; 6632 dns_name_t *dname_name; 6633 6634 found = ISC_FALSE; 6635 aflag = 0; 6636 if (rdataset->type == dns_rdatatype_dname) { 6637 /* 6638 * We're looking for something else, 6639 * but we found a DNAME. 6640 * 6641 * If we're not chaining, then the 6642 * DNAME should not be external. 6643 */ 6644 if (!chaining && external) { 6645 log_formerr(fctx, 6646 "external DNAME"); 6647 return (DNS_R_FORMERR); 6648 } 6649 found = ISC_TRUE; 6650 want_chaining = ISC_TRUE; 6651 POST(want_chaining); 6652 aflag = DNS_RDATASETATTR_ANSWER; 6653 result = dname_target(fctx, rdataset, 6654 qname, name, 6655 &dname); 6656 if (result == ISC_R_NOSPACE) { 6657 /* 6658 * We can't construct the 6659 * DNAME target. Do not 6660 * try to continue. 6661 */ 6662 want_chaining = ISC_FALSE; 6663 POST(want_chaining); 6664 } else if (result != ISC_R_SUCCESS) 6665 return (result); 6666 else 6667 found_dname = ISC_TRUE; 6668 6669 dname_name = dns_fixedname_name(&dname); 6670 if (!is_answertarget_allowed(view, 6671 qname, 6672 rdataset->type, 6673 dname_name, 6674 &fctx->domain)) { 6675 return (DNS_R_SERVFAIL); 6676 } 6677 } else if (rdataset->type == dns_rdatatype_rrsig 6678 && rdataset->covers == 6679 dns_rdatatype_dname) { 6680 /* 6681 * We've found a signature that 6682 * covers the DNAME. 6683 */ 6684 found = ISC_TRUE; 6685 aflag = DNS_RDATASETATTR_ANSWERSIG; 6686 } 6687 6688 if (found) { 6689 /* 6690 * We've found an answer to our 6691 * question. 6692 */ 6693 name->attributes |= 6694 DNS_NAMEATTR_CACHE; 6695 rdataset->attributes |= 6696 DNS_RDATASETATTR_CACHE; 6697 rdataset->trust = dns_trust_answer; 6698 if (!chaining) { 6699 /* 6700 * This data is "the" answer 6701 * to our question only if 6702 * we're not chaining. 6703 */ 6704 INSIST(!external); 6705 if (aflag == 6706 DNS_RDATASETATTR_ANSWER) 6707 have_answer = ISC_TRUE; 6708 name->attributes |= 6709 DNS_NAMEATTR_ANSWER; 6710 rdataset->attributes |= aflag; 6711 if (aa) 6712 rdataset->trust = 6713 dns_trust_authanswer; 6714 } else if (external) { 6715 rdataset->attributes |= 6716 DNS_RDATASETATTR_EXTERNAL; 6717 } 6718 6719 /* 6720 * DNAME chaining. 6721 */ 6722 if (found_dname) { 6723 /* 6724 * Copy the dname into the 6725 * qname fixed name. 6726 * 6727 * Although we check for 6728 * failure of the copy 6729 * operation, in practice it 6730 * should never fail since 6731 * we already know that the 6732 * result fits in a fixedname. 6733 */ 6734 dns_fixedname_init(&fqname); 6735 result = dns_name_copy( 6736 dns_fixedname_name(&dname), 6737 dns_fixedname_name(&fqname), 6738 NULL); 6739 if (result != ISC_R_SUCCESS) 6740 return (result); 6741 wanted_chaining = ISC_TRUE; 6742 name->attributes |= 6743 DNS_NAMEATTR_CHAINING; 6744 rdataset->attributes |= 6745 DNS_RDATASETATTR_CHAINING; 6746 qname = dns_fixedname_name( 6747 &fqname); 6748 } 6749 } 6750 } 6751 if (wanted_chaining) 6752 chaining = ISC_TRUE; 6753 } 6754 result = dns_message_nextname(message, DNS_SECTION_ANSWER); 6755 } 6756 if (result == ISC_R_NOMORE) 6757 result = ISC_R_SUCCESS; 6758 if (result != ISC_R_SUCCESS) 6759 return (result); 6760 6761 /* 6762 * We should have found an answer. 6763 */ 6764 if (!have_answer) { 6765 log_formerr(fctx, "reply has no answer"); 6766 return (DNS_R_FORMERR); 6767 } 6768 6769 /* 6770 * This response is now potentially cacheable. 6771 */ 6772 fctx->attributes |= FCTX_ATTR_WANTCACHE; 6773 6774 /* 6775 * Did chaining end before we got the final answer? 6776 */ 6777 if (chaining) { 6778 /* 6779 * Yes. This may be a negative reply, so hand off 6780 * authority section processing to the noanswer code. 6781 * If it isn't a noanswer response, no harm will be 6782 * done. 6783 */ 6784 return (noanswer_response(fctx, qname, 0)); 6785 } 6786 6787 /* 6788 * We didn't end with an incomplete chain, so the rcode should be 6789 * "no error". 6790 */ 6791 if (message->rcode != dns_rcode_noerror) { 6792 log_formerr(fctx, "CNAME/DNAME chain complete, but RCODE " 6793 "indicates error"); 6794 return (DNS_R_FORMERR); 6795 } 6796 6797 /* 6798 * Examine the authority section (if there is one). 6799 * 6800 * We expect there to be only one owner name for all the rdatasets 6801 * in this section, and we expect that it is not external. 6802 */ 6803 done = ISC_FALSE; 6804 ns_name = NULL; 6805 ns_rdataset = NULL; 6806 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); 6807 while (!done && result == ISC_R_SUCCESS) { 6808 name = NULL; 6809 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); 6810 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain)); 6811 if (!external) { 6812 /* 6813 * We expect to find NS or SIG NS rdatasets, and 6814 * nothing else. 6815 */ 6816 for (rdataset = ISC_LIST_HEAD(name->list); 6817 rdataset != NULL; 6818 rdataset = ISC_LIST_NEXT(rdataset, link)) { 6819 if (rdataset->type == dns_rdatatype_ns || 6820 (rdataset->type == dns_rdatatype_rrsig && 6821 rdataset->covers == dns_rdatatype_ns)) { 6822 name->attributes |= 6823 DNS_NAMEATTR_CACHE; 6824 rdataset->attributes |= 6825 DNS_RDATASETATTR_CACHE; 6826 if (aa && !chaining) 6827 rdataset->trust = 6828 dns_trust_authauthority; 6829 else 6830 rdataset->trust = 6831 dns_trust_additional; 6832 6833 if (rdataset->type == dns_rdatatype_ns) { 6834 ns_name = name; 6835 ns_rdataset = rdataset; 6836 } 6837 /* 6838 * Mark any additional data related 6839 * to this rdataset. 6840 */ 6841 (void)dns_rdataset_additionaldata( 6842 rdataset, 6843 check_related, 6844 fctx); 6845 done = ISC_TRUE; 6846 } 6847 } 6848 } 6849 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); 6850 } 6851 if (result == ISC_R_NOMORE) 6852 result = ISC_R_SUCCESS; 6853 6854 log_ns_ttl(fctx, "answer_response"); 6855 6856 if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) && 6857 !dns_name_equal(ns_name, dns_rootname)) 6858 trim_ns_ttl(fctx, ns_name, ns_rdataset); 6859 6860 return (result); 6861 } 6862 6863 static isc_boolean_t 6864 fctx_decreference(fetchctx_t *fctx) { 6865 isc_boolean_t bucket_empty = ISC_FALSE; 6866 6867 INSIST(fctx->references > 0); 6868 fctx->references--; 6869 if (fctx->references == 0) { 6870 /* 6871 * No one cares about the result of this fetch anymore. 6872 */ 6873 if (fctx->pending == 0 && fctx->nqueries == 0 && 6874 ISC_LIST_EMPTY(fctx->validators) && SHUTTINGDOWN(fctx)) { 6875 /* 6876 * This fctx is already shutdown; we were just 6877 * waiting for the last reference to go away. 6878 */ 6879 bucket_empty = fctx_unlink(fctx); 6880 fctx_destroy(fctx); 6881 } else { 6882 /* 6883 * Initiate shutdown. 6884 */ 6885 fctx_shutdown(fctx); 6886 } 6887 } 6888 return (bucket_empty); 6889 } 6890 6891 static void 6892 resume_dslookup(isc_task_t *task, isc_event_t *event) { 6893 dns_fetchevent_t *fevent; 6894 dns_resolver_t *res; 6895 fetchctx_t *fctx; 6896 isc_result_t result; 6897 isc_boolean_t bucket_empty; 6898 isc_boolean_t locked = ISC_FALSE; 6899 unsigned int bucketnum; 6900 dns_rdataset_t nameservers; 6901 dns_fixedname_t fixed; 6902 dns_name_t *domain; 6903 6904 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); 6905 fevent = (dns_fetchevent_t *)event; 6906 fctx = event->ev_arg; 6907 REQUIRE(VALID_FCTX(fctx)); 6908 res = fctx->res; 6909 6910 UNUSED(task); 6911 FCTXTRACE("resume_dslookup"); 6912 6913 if (fevent->node != NULL) 6914 dns_db_detachnode(fevent->db, &fevent->node); 6915 if (fevent->db != NULL) 6916 dns_db_detach(&fevent->db); 6917 6918 dns_rdataset_init(&nameservers); 6919 6920 bucketnum = fctx->bucketnum; 6921 if (fevent->result == ISC_R_CANCELED) { 6922 dns_resolver_destroyfetch(&fctx->nsfetch); 6923 fctx_done(fctx, ISC_R_CANCELED, __LINE__); 6924 } else if (fevent->result == ISC_R_SUCCESS) { 6925 6926 FCTXTRACE("resuming DS lookup"); 6927 6928 dns_resolver_destroyfetch(&fctx->nsfetch); 6929 if (dns_rdataset_isassociated(&fctx->nameservers)) 6930 dns_rdataset_disassociate(&fctx->nameservers); 6931 dns_rdataset_clone(fevent->rdataset, &fctx->nameservers); 6932 fctx->ns_ttl = fctx->nameservers.ttl; 6933 fctx->ns_ttl_ok = ISC_TRUE; 6934 log_ns_ttl(fctx, "resume_dslookup"); 6935 dns_name_free(&fctx->domain, fctx->mctx); 6936 dns_name_init(&fctx->domain, NULL); 6937 result = dns_name_dup(&fctx->nsname, fctx->mctx, &fctx->domain); 6938 if (result != ISC_R_SUCCESS) { 6939 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 6940 goto cleanup; 6941 } 6942 /* 6943 * Try again. 6944 */ 6945 fctx_try(fctx, ISC_TRUE, ISC_FALSE); 6946 } else { 6947 unsigned int n; 6948 dns_rdataset_t *nsrdataset = NULL; 6949 6950 /* 6951 * Retrieve state from fctx->nsfetch before we destroy it. 6952 */ 6953 dns_fixedname_init(&fixed); 6954 domain = dns_fixedname_name(&fixed); 6955 dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL); 6956 if (dns_name_equal(&fctx->nsname, domain)) { 6957 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 6958 dns_resolver_destroyfetch(&fctx->nsfetch); 6959 goto cleanup; 6960 } 6961 if (dns_rdataset_isassociated( 6962 &fctx->nsfetch->private->nameservers)) { 6963 dns_rdataset_clone( 6964 &fctx->nsfetch->private->nameservers, 6965 &nameservers); 6966 nsrdataset = &nameservers; 6967 } else 6968 domain = NULL; 6969 dns_resolver_destroyfetch(&fctx->nsfetch); 6970 n = dns_name_countlabels(&fctx->nsname); 6971 dns_name_getlabelsequence(&fctx->nsname, 1, n - 1, 6972 &fctx->nsname); 6973 6974 if (dns_rdataset_isassociated(fevent->rdataset)) 6975 dns_rdataset_disassociate(fevent->rdataset); 6976 FCTXTRACE("continuing to look for parent's NS records"); 6977 result = dns_resolver_createfetch(fctx->res, &fctx->nsname, 6978 dns_rdatatype_ns, domain, 6979 nsrdataset, NULL, 6980 fctx->options, task, 6981 resume_dslookup, fctx, 6982 &fctx->nsrrset, NULL, 6983 &fctx->nsfetch); 6984 if (result != ISC_R_SUCCESS) 6985 fctx_done(fctx, result, __LINE__); 6986 else { 6987 LOCK(&res->buckets[bucketnum].lock); 6988 locked = ISC_TRUE; 6989 fctx->references++; 6990 } 6991 } 6992 6993 cleanup: 6994 if (dns_rdataset_isassociated(&nameservers)) 6995 dns_rdataset_disassociate(&nameservers); 6996 if (dns_rdataset_isassociated(fevent->rdataset)) 6997 dns_rdataset_disassociate(fevent->rdataset); 6998 INSIST(fevent->sigrdataset == NULL); 6999 isc_event_free(&event); 7000 if (!locked) 7001 LOCK(&res->buckets[bucketnum].lock); 7002 bucket_empty = fctx_decreference(fctx); 7003 UNLOCK(&res->buckets[bucketnum].lock); 7004 if (bucket_empty) 7005 empty_bucket(res); 7006 } 7007 7008 static inline void 7009 checknamessection(dns_message_t *message, dns_section_t section) { 7010 isc_result_t result; 7011 dns_name_t *name; 7012 dns_rdata_t rdata = DNS_RDATA_INIT; 7013 dns_rdataset_t *rdataset; 7014 7015 for (result = dns_message_firstname(message, section); 7016 result == ISC_R_SUCCESS; 7017 result = dns_message_nextname(message, section)) 7018 { 7019 name = NULL; 7020 dns_message_currentname(message, section, &name); 7021 for (rdataset = ISC_LIST_HEAD(name->list); 7022 rdataset != NULL; 7023 rdataset = ISC_LIST_NEXT(rdataset, link)) { 7024 for (result = dns_rdataset_first(rdataset); 7025 result == ISC_R_SUCCESS; 7026 result = dns_rdataset_next(rdataset)) { 7027 dns_rdataset_current(rdataset, &rdata); 7028 if (!dns_rdata_checkowner(name, rdata.rdclass, 7029 rdata.type, 7030 ISC_FALSE) || 7031 !dns_rdata_checknames(&rdata, name, NULL)) 7032 { 7033 rdataset->attributes |= 7034 DNS_RDATASETATTR_CHECKNAMES; 7035 } 7036 dns_rdata_reset(&rdata); 7037 } 7038 } 7039 } 7040 } 7041 7042 static void 7043 checknames(dns_message_t *message) { 7044 7045 checknamessection(message, DNS_SECTION_ANSWER); 7046 checknamessection(message, DNS_SECTION_AUTHORITY); 7047 checknamessection(message, DNS_SECTION_ADDITIONAL); 7048 } 7049 7050 /* 7051 * Log server NSID at log level 'level' 7052 */ 7053 static void 7054 log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, 7055 int level, isc_mem_t *mctx) 7056 { 7057 static const char hex[17] = "0123456789abcdef"; 7058 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 7059 isc_uint16_t buflen, i; 7060 unsigned char *p, *nsid; 7061 unsigned char *buf = NULL, *pbuf = NULL; 7062 7063 /* Allocate buffer for storing hex version of the NSID */ 7064 buflen = (isc_uint16_t)nsid_len * 2 + 1; 7065 buf = isc_mem_get(mctx, buflen); 7066 if (buf == NULL) 7067 goto cleanup; 7068 pbuf = isc_mem_get(mctx, nsid_len + 1); 7069 if (pbuf == NULL) 7070 goto cleanup; 7071 7072 /* Convert to hex */ 7073 p = buf; 7074 nsid = isc_buffer_current(opt); 7075 for (i = 0; i < nsid_len; i++) { 7076 *p++ = hex[(nsid[i] >> 4) & 0xf]; 7077 *p++ = hex[nsid[i] & 0xf]; 7078 } 7079 *p = '\0'; 7080 7081 /* Make printable version */ 7082 p = pbuf; 7083 for (i = 0; i < nsid_len; i++) { 7084 if (isprint(nsid[i])) 7085 *p++ = nsid[i]; 7086 else 7087 *p++ = '.'; 7088 } 7089 *p = '\0'; 7090 7091 isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, 7092 sizeof(addrbuf)); 7093 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 7094 DNS_LOGMODULE_RESOLVER, level, 7095 "received NSID %s (\"%s\") from %s", buf, pbuf, addrbuf); 7096 cleanup: 7097 if (pbuf != NULL) 7098 isc_mem_put(mctx, pbuf, nsid_len + 1); 7099 if (buf != NULL) 7100 isc_mem_put(mctx, buf, buflen); 7101 } 7102 7103 static isc_boolean_t 7104 iscname(fetchctx_t *fctx) { 7105 isc_result_t result; 7106 7107 result = dns_message_findname(fctx->rmessage, DNS_SECTION_ANSWER, 7108 &fctx->name, dns_rdatatype_cname, 0, 7109 NULL, NULL); 7110 return (result == ISC_R_SUCCESS ? ISC_TRUE : ISC_FALSE); 7111 } 7112 7113 static isc_boolean_t 7114 betterreferral(fetchctx_t *fctx) { 7115 isc_result_t result; 7116 dns_name_t *name; 7117 dns_rdataset_t *rdataset; 7118 dns_message_t *message = fctx->rmessage; 7119 7120 for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); 7121 result == ISC_R_SUCCESS; 7122 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY)) { 7123 name = NULL; 7124 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); 7125 if (!isstrictsubdomain(name, &fctx->domain)) 7126 continue; 7127 for (rdataset = ISC_LIST_HEAD(name->list); 7128 rdataset != NULL; 7129 rdataset = ISC_LIST_NEXT(rdataset, link)) 7130 if (rdataset->type == dns_rdatatype_ns) 7131 return (ISC_TRUE); 7132 } 7133 return (ISC_FALSE); 7134 } 7135 7136 static void 7137 process_opt(resquery_t *query, dns_rdataset_t *opt) { 7138 dns_rdata_t rdata; 7139 isc_buffer_t optbuf; 7140 isc_result_t result; 7141 isc_uint16_t optcode; 7142 isc_uint16_t optlen; 7143 #ifdef ISC_PLATFORM_USESIT 7144 unsigned char *sit; 7145 dns_adbaddrinfo_t *addrinfo; 7146 unsigned char cookie[8]; 7147 #endif 7148 7149 result = dns_rdataset_first(opt); 7150 if (result == ISC_R_SUCCESS) { 7151 dns_rdata_init(&rdata); 7152 dns_rdataset_current(opt, &rdata); 7153 isc_buffer_init(&optbuf, rdata.data, rdata.length); 7154 isc_buffer_add(&optbuf, rdata.length); 7155 while (isc_buffer_remaininglength(&optbuf) >= 4) { 7156 optcode = isc_buffer_getuint16(&optbuf); 7157 optlen = isc_buffer_getuint16(&optbuf); 7158 INSIST(optlen <= isc_buffer_remaininglength(&optbuf)); 7159 switch (optcode) { 7160 case DNS_OPT_NSID: 7161 if (query->options & DNS_FETCHOPT_WANTNSID) 7162 log_nsid(&optbuf, optlen, query, 7163 ISC_LOG_DEBUG(3), 7164 query->fctx->res->mctx); 7165 isc_buffer_forward(&optbuf, optlen); 7166 break; 7167 #ifdef ISC_PLATFORM_USESIT 7168 case DNS_OPT_SIT: 7169 sit = isc_buffer_current(&optbuf); 7170 compute_cc(query, cookie, sizeof(cookie)); 7171 INSIST(query->fctx->rmessage->sitbad == 0 && 7172 query->fctx->rmessage->sitok == 0); 7173 if (optlen >= 8U && 7174 memcmp(cookie, sit, 8) == 0) { 7175 query->fctx->rmessage->sitok = 1; 7176 inc_stats(query->fctx->res, 7177 dns_resstatscounter_sitok); 7178 addrinfo = query->addrinfo; 7179 dns_adb_setsit(query->fctx->adb, 7180 addrinfo, sit, optlen); 7181 } else 7182 query->fctx->rmessage->sitbad = 1; 7183 isc_buffer_forward(&optbuf, optlen); 7184 inc_stats(query->fctx->res, 7185 dns_resstatscounter_sitin); 7186 break; 7187 #endif 7188 default: 7189 isc_buffer_forward(&optbuf, optlen); 7190 break; 7191 } 7192 } 7193 INSIST(isc_buffer_remaininglength(&optbuf) == 0U); 7194 } 7195 } 7196 7197 static void 7198 resquery_response(isc_task_t *task, isc_event_t *event) { 7199 isc_result_t result = ISC_R_SUCCESS; 7200 resquery_t *query = event->ev_arg; 7201 dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event; 7202 isc_boolean_t keep_trying, get_nameservers, resend; 7203 isc_boolean_t truncated; 7204 dns_message_t *message; 7205 dns_rdataset_t *opt; 7206 fetchctx_t *fctx; 7207 dns_name_t *fname; 7208 dns_fixedname_t foundname; 7209 isc_stdtime_t now; 7210 isc_time_t tnow, *finish; 7211 dns_adbaddrinfo_t *addrinfo; 7212 unsigned int options; 7213 unsigned int findoptions; 7214 isc_result_t broken_server; 7215 badnstype_t broken_type = badns_response; 7216 isc_boolean_t no_response; 7217 7218 REQUIRE(VALID_QUERY(query)); 7219 fctx = query->fctx; 7220 options = query->options; 7221 REQUIRE(VALID_FCTX(fctx)); 7222 REQUIRE(event->ev_type == DNS_EVENT_DISPATCH); 7223 7224 QTRACE("response"); 7225 7226 if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET) 7227 inc_stats(fctx->res, dns_resstatscounter_responsev4); 7228 else 7229 inc_stats(fctx->res, dns_resstatscounter_responsev6); 7230 7231 (void)isc_timer_touch(fctx->timer); 7232 7233 keep_trying = ISC_FALSE; 7234 broken_server = ISC_R_SUCCESS; 7235 get_nameservers = ISC_FALSE; 7236 resend = ISC_FALSE; 7237 truncated = ISC_FALSE; 7238 finish = NULL; 7239 no_response = ISC_FALSE; 7240 7241 if (fctx->res->exiting) { 7242 result = ISC_R_SHUTTINGDOWN; 7243 goto done; 7244 } 7245 7246 fctx->timeouts = 0; 7247 fctx->timeout = ISC_FALSE; 7248 fctx->addrinfo = query->addrinfo; 7249 7250 /* 7251 * XXXRTH We should really get the current time just once. We 7252 * need a routine to convert from an isc_time_t to an 7253 * isc_stdtime_t. 7254 */ 7255 TIME_NOW(&tnow); 7256 finish = &tnow; 7257 isc_stdtime_get(&now); 7258 7259 /* 7260 * Did the dispatcher have a problem? 7261 */ 7262 if (devent->result != ISC_R_SUCCESS) { 7263 if (devent->result == ISC_R_EOF && 7264 (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { 7265 /* 7266 * The problem might be that they 7267 * don't understand EDNS0. Turn it 7268 * off and try again. 7269 */ 7270 options |= DNS_FETCHOPT_NOEDNS0; 7271 resend = ISC_TRUE; 7272 add_bad_edns(fctx, &query->addrinfo->sockaddr); 7273 } else { 7274 /* 7275 * There's no hope for this query. 7276 */ 7277 keep_trying = ISC_TRUE; 7278 7279 /* 7280 * If this is a network error on an exclusive query 7281 * socket, mark the server as bad so that we won't try 7282 * it for this fetch again. Also adjust finish and 7283 * no_response so that we penalize this address in SRTT 7284 * adjustment later. 7285 */ 7286 if (query->exclusivesocket && 7287 (devent->result == ISC_R_HOSTUNREACH || 7288 devent->result == ISC_R_NETUNREACH || 7289 devent->result == ISC_R_CONNREFUSED || 7290 devent->result == ISC_R_CANCELED)) { 7291 broken_server = devent->result; 7292 broken_type = badns_unreachable; 7293 finish = NULL; 7294 no_response = ISC_TRUE; 7295 } 7296 } 7297 goto done; 7298 } 7299 7300 message = fctx->rmessage; 7301 7302 if (query->tsig != NULL) { 7303 result = dns_message_setquerytsig(message, query->tsig); 7304 if (result != ISC_R_SUCCESS) 7305 goto done; 7306 } 7307 7308 if (query->tsigkey) { 7309 result = dns_message_settsigkey(message, query->tsigkey); 7310 if (result != ISC_R_SUCCESS) 7311 goto done; 7312 } 7313 7314 if ((options & DNS_FETCHOPT_TCP) == 0) { 7315 if ((options & DNS_FETCHOPT_NOEDNS0) == 0) 7316 dns_adb_setudpsize(fctx->adb, query->addrinfo, 7317 isc_buffer_usedlength(&devent->buffer)); 7318 else 7319 dns_adb_plainresponse(fctx->adb, query->addrinfo); 7320 } 7321 result = dns_message_parse(message, &devent->buffer, 0); 7322 if (result != ISC_R_SUCCESS) { 7323 switch (result) { 7324 case ISC_R_UNEXPECTEDEND: 7325 if (!message->question_ok || 7326 (message->flags & DNS_MESSAGEFLAG_TC) == 0 || 7327 (options & DNS_FETCHOPT_TCP) != 0) { 7328 /* 7329 * Either the message ended prematurely, 7330 * and/or wasn't marked as being truncated, 7331 * and/or this is a response to a query we 7332 * sent over TCP. In all of these cases, 7333 * something is wrong with the remote 7334 * server and we don't want to retry using 7335 * TCP. 7336 */ 7337 if ((query->options & DNS_FETCHOPT_NOEDNS0) 7338 == 0) { 7339 /* 7340 * The problem might be that they 7341 * don't understand EDNS0. Turn it 7342 * off and try again. 7343 */ 7344 options |= DNS_FETCHOPT_NOEDNS0; 7345 resend = ISC_TRUE; 7346 add_bad_edns(fctx, 7347 &query->addrinfo->sockaddr); 7348 inc_stats(fctx->res, 7349 dns_resstatscounter_edns0fail); 7350 } else { 7351 broken_server = result; 7352 keep_trying = ISC_TRUE; 7353 } 7354 goto done; 7355 } 7356 /* 7357 * We defer retrying via TCP for a bit so we can 7358 * check out this message further. 7359 */ 7360 truncated = ISC_TRUE; 7361 break; 7362 case DNS_R_FORMERR: 7363 if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { 7364 /* 7365 * The problem might be that they 7366 * don't understand EDNS0. Turn it 7367 * off and try again. 7368 */ 7369 options |= DNS_FETCHOPT_NOEDNS0; 7370 resend = ISC_TRUE; 7371 add_bad_edns(fctx, &query->addrinfo->sockaddr); 7372 inc_stats(fctx->res, 7373 dns_resstatscounter_edns0fail); 7374 } else { 7375 broken_server = DNS_R_UNEXPECTEDRCODE; 7376 keep_trying = ISC_TRUE; 7377 } 7378 goto done; 7379 default: 7380 /* 7381 * Something bad has happened. 7382 */ 7383 goto done; 7384 } 7385 } 7386 7387 /* 7388 * Log the incoming packet. 7389 */ 7390 dns_message_logfmtpacket(message, "received packet:\n", 7391 DNS_LOGCATEGORY_RESOLVER, 7392 DNS_LOGMODULE_PACKETS, 7393 &dns_master_style_comment, 7394 ISC_LOG_DEBUG(10), 7395 fctx->res->mctx); 7396 /* 7397 * Process receive opt record. 7398 */ 7399 opt = dns_message_getopt(message); 7400 if (opt != NULL) 7401 process_opt(query, opt); 7402 7403 #ifdef notyet 7404 #ifdef ISC_PLATFORM_USESIT 7405 if (message->sitbad) { 7406 /* 7407 * If the SIT is bad assume it is a attack and retry. 7408 */ 7409 resend = ISC_TRUE; 7410 /* XXXMPA log it */ 7411 goto done; 7412 } 7413 #endif 7414 #endif 7415 7416 /* 7417 * If the message is signed, check the signature. If not, this 7418 * returns success anyway. 7419 */ 7420 result = dns_message_checksig(message, fctx->res->view); 7421 if (result != ISC_R_SUCCESS) 7422 goto done; 7423 7424 /* 7425 * The dispatcher should ensure we only get responses with QR set. 7426 */ 7427 INSIST((message->flags & DNS_MESSAGEFLAG_QR) != 0); 7428 /* 7429 * INSIST() that the message comes from the place we sent it to, 7430 * since the dispatch code should ensure this. 7431 * 7432 * INSIST() that the message id is correct (this should also be 7433 * ensured by the dispatch code). 7434 */ 7435 7436 /* 7437 * We have an affirmative response to the query and we have 7438 * previously got a response from this server which indicated 7439 * EDNS may not be supported so we can now cache the lack of 7440 * EDNS support. 7441 */ 7442 if (opt == NULL && !EDNSOK(query->addrinfo) && 7443 (message->rcode == dns_rcode_noerror || 7444 message->rcode == dns_rcode_nxdomain || 7445 message->rcode == dns_rcode_refused || 7446 message->rcode == dns_rcode_yxdomain) && 7447 bad_edns(fctx, &query->addrinfo->sockaddr)) { 7448 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 7449 char buf[4096], addrbuf[ISC_SOCKADDR_FORMATSIZE]; 7450 isc_sockaddr_format(&query->addrinfo->sockaddr, 7451 addrbuf, sizeof(addrbuf)); 7452 snprintf(buf, sizeof(buf), 7453 "received packet from %s (bad edns):\n", 7454 addrbuf); 7455 dns_message_logpacket(message, buf, 7456 DNS_LOGCATEGORY_RESOLVER, 7457 DNS_LOGMODULE_RESOLVER, 7458 ISC_LOG_DEBUG(3), fctx->res->mctx); 7459 } 7460 dns_adb_changeflags(fctx->adb, query->addrinfo, 7461 DNS_FETCHOPT_NOEDNS0, 7462 DNS_FETCHOPT_NOEDNS0); 7463 } else if (opt == NULL && (message->flags & DNS_MESSAGEFLAG_TC) == 0 && 7464 !EDNSOK(query->addrinfo) && 7465 (message->rcode == dns_rcode_noerror || 7466 message->rcode == dns_rcode_nxdomain) && 7467 (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { 7468 /* 7469 * We didn't get a OPT record in response to a EDNS query. 7470 * 7471 * Old versions of named incorrectly drop the OPT record 7472 * when there is a signed, truncated response so we check 7473 * that TC is not set. 7474 * 7475 * Record that the server is not talking EDNS. While this 7476 * should be safe to do for any rcode we limit it to NOERROR 7477 * and NXDOMAIN. 7478 */ 7479 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 7480 char buf[4096], addrbuf[ISC_SOCKADDR_FORMATSIZE]; 7481 isc_sockaddr_format(&query->addrinfo->sockaddr, 7482 addrbuf, sizeof(addrbuf)); 7483 snprintf(buf, sizeof(buf), 7484 "received packet from %s (no opt):\n", 7485 addrbuf); 7486 dns_message_logpacket(message, buf, 7487 DNS_LOGCATEGORY_RESOLVER, 7488 DNS_LOGMODULE_RESOLVER, 7489 ISC_LOG_DEBUG(3), fctx->res->mctx); 7490 } 7491 dns_adb_changeflags(fctx->adb, query->addrinfo, 7492 DNS_FETCHOPT_NOEDNS0, 7493 DNS_FETCHOPT_NOEDNS0); 7494 } 7495 7496 /* 7497 * If we get a non error EDNS response record the fact so we 7498 * won't fallback to plain DNS in the future for this server. 7499 */ 7500 if (opt != NULL && !EDNSOK(query->addrinfo) && 7501 (query->options & DNS_FETCHOPT_NOEDNS0) == 0 && 7502 (message->rcode == dns_rcode_noerror || 7503 message->rcode == dns_rcode_nxdomain || 7504 message->rcode == dns_rcode_refused || 7505 message->rcode == dns_rcode_yxdomain)) { 7506 dns_adb_changeflags(fctx->adb, query->addrinfo, 7507 FCTX_ADDRINFO_EDNSOK, 7508 FCTX_ADDRINFO_EDNSOK); 7509 } 7510 7511 /* 7512 * Deal with truncated responses by retrying using TCP. 7513 */ 7514 if ((message->flags & DNS_MESSAGEFLAG_TC) != 0) 7515 truncated = ISC_TRUE; 7516 7517 if (truncated) { 7518 inc_stats(fctx->res, dns_resstatscounter_truncated); 7519 if ((options & DNS_FETCHOPT_TCP) != 0) { 7520 broken_server = DNS_R_TRUNCATEDTCP; 7521 keep_trying = ISC_TRUE; 7522 } else { 7523 options |= DNS_FETCHOPT_TCP; 7524 resend = ISC_TRUE; 7525 } 7526 goto done; 7527 } 7528 7529 /* 7530 * Is it a query response? 7531 */ 7532 if (message->opcode != dns_opcode_query) { 7533 /* XXXRTH Log */ 7534 broken_server = DNS_R_UNEXPECTEDOPCODE; 7535 keep_trying = ISC_TRUE; 7536 goto done; 7537 } 7538 7539 /* 7540 * Update statistics about erroneous responses. 7541 */ 7542 if (message->rcode != dns_rcode_noerror) { 7543 switch (message->rcode) { 7544 case dns_rcode_nxdomain: 7545 inc_stats(fctx->res, dns_resstatscounter_nxdomain); 7546 break; 7547 case dns_rcode_servfail: 7548 inc_stats(fctx->res, dns_resstatscounter_servfail); 7549 break; 7550 case dns_rcode_formerr: 7551 inc_stats(fctx->res, dns_resstatscounter_formerr); 7552 break; 7553 case dns_rcode_refused: 7554 inc_stats(fctx->res, dns_resstatscounter_refused); 7555 break; 7556 case dns_rcode_badvers: 7557 inc_stats(fctx->res, dns_resstatscounter_badvers); 7558 break; 7559 default: 7560 inc_stats(fctx->res, dns_resstatscounter_othererror); 7561 break; 7562 } 7563 } 7564 7565 /* 7566 * Is the remote server broken, or does it dislike us? 7567 */ 7568 if (message->rcode != dns_rcode_noerror && 7569 message->rcode != dns_rcode_nxdomain) { 7570 #ifdef ISC_PLATFORM_USESIT 7571 unsigned char sit[64]; 7572 7573 /* 7574 * Some servers do not ignore unknown EDNS options. 7575 */ 7576 if (!NOSIT(query->addrinfo) && 7577 (message->rcode == dns_rcode_formerr || 7578 message->rcode == dns_rcode_notimp || 7579 message->rcode == dns_rcode_refused) && 7580 dns_adb_getsit(fctx->adb, query->addrinfo, 7581 sit, sizeof(sit)) == 0U) { 7582 dns_adb_changeflags(fctx->adb, query->addrinfo, 7583 FCTX_ADDRINFO_NOSIT, 7584 FCTX_ADDRINFO_NOSIT); 7585 resend = ISC_TRUE; 7586 } else 7587 #endif 7588 if (((message->rcode == dns_rcode_formerr || 7589 message->rcode == dns_rcode_notimp) || 7590 (message->rcode == dns_rcode_servfail && 7591 dns_message_getopt(message) == NULL)) && 7592 (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { 7593 /* 7594 * It's very likely they don't like EDNS0. 7595 * If the response code is SERVFAIL, also check if the 7596 * response contains an OPT RR and don't cache the 7597 * failure since it can be returned for various other 7598 * reasons. 7599 * 7600 * XXXRTH We should check if the question 7601 * we're asking requires EDNS0, and 7602 * if so, we should bail out. 7603 */ 7604 options |= DNS_FETCHOPT_NOEDNS0; 7605 resend = ISC_TRUE; 7606 /* 7607 * Remember that they may not like EDNS0. 7608 */ 7609 add_bad_edns(fctx, &query->addrinfo->sockaddr); 7610 inc_stats(fctx->res, dns_resstatscounter_edns0fail); 7611 } else if (message->rcode == dns_rcode_formerr) { 7612 if (ISFORWARDER(query->addrinfo)) { 7613 /* 7614 * This forwarder doesn't understand us, 7615 * but other forwarders might. Keep trying. 7616 */ 7617 broken_server = DNS_R_REMOTEFORMERR; 7618 keep_trying = ISC_TRUE; 7619 } else { 7620 /* 7621 * The server doesn't understand us. Since 7622 * all servers for a zone need similar 7623 * capabilities, we assume that we will get 7624 * FORMERR from all servers, and thus we 7625 * cannot make any more progress with this 7626 * fetch. 7627 */ 7628 log_formerr(fctx, "server sent FORMERR"); 7629 result = DNS_R_FORMERR; 7630 } 7631 } else if (message->rcode == dns_rcode_yxdomain) { 7632 /* 7633 * DNAME mapping failed because the new name 7634 * was too long. There's no chance of success 7635 * for this fetch. 7636 */ 7637 result = DNS_R_YXDOMAIN; 7638 } else if (message->rcode == dns_rcode_badvers) { 7639 unsigned int flags, mask; 7640 unsigned int version; 7641 #ifdef ISC_PLATFORM_USESIT 7642 /* 7643 * Some servers return BADVERS to unknown 7644 * EDNS options. This cannot be long term 7645 * strategy. Do not disable SIT if we have 7646 * already have received a SIT from this 7647 * server. 7648 */ 7649 if (dns_adb_getsit(fctx->adb, query->addrinfo, 7650 sit, sizeof(sit)) == 0U) { 7651 dns_adb_changeflags(fctx->adb, query->addrinfo, 7652 FCTX_ADDRINFO_NOSIT, 7653 FCTX_ADDRINFO_NOSIT); 7654 } 7655 #endif 7656 7657 resend = ISC_TRUE; 7658 INSIST(opt != NULL); 7659 version = (opt->ttl >> 16) & 0xff; 7660 flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) | 7661 DNS_FETCHOPT_EDNSVERSIONSET; 7662 mask = DNS_FETCHOPT_EDNSVERSIONMASK | 7663 DNS_FETCHOPT_EDNSVERSIONSET; 7664 /* 7665 * Record that we got a good EDNS response. 7666 */ 7667 if (query->ednsversion > (int)version && 7668 !EDNSOK(query->addrinfo)) { 7669 dns_adb_changeflags(fctx->adb, query->addrinfo, 7670 FCTX_ADDRINFO_EDNSOK, 7671 FCTX_ADDRINFO_EDNSOK); 7672 } 7673 /* 7674 * Record the supported EDNS version. 7675 */ 7676 switch (version) { 7677 case 0: 7678 dns_adb_changeflags(fctx->adb, query->addrinfo, 7679 flags, mask); 7680 break; 7681 default: 7682 broken_server = DNS_R_BADVERS; 7683 keep_trying = ISC_TRUE; 7684 break; 7685 } 7686 } else { 7687 /* 7688 * XXXRTH log. 7689 */ 7690 broken_server = DNS_R_UNEXPECTEDRCODE; 7691 INSIST(broken_server != ISC_R_SUCCESS); 7692 keep_trying = ISC_TRUE; 7693 } 7694 goto done; 7695 } 7696 7697 /* 7698 * Is the question the same as the one we asked? 7699 */ 7700 result = same_question(fctx); 7701 if (result != ISC_R_SUCCESS) { 7702 /* XXXRTH Log */ 7703 if (result == DNS_R_FORMERR) 7704 keep_trying = ISC_TRUE; 7705 goto done; 7706 } 7707 7708 /* 7709 * Is the server lame? 7710 */ 7711 if (fctx->res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) && 7712 is_lame(fctx)) { 7713 inc_stats(fctx->res, dns_resstatscounter_lame); 7714 log_lame(fctx, query->addrinfo); 7715 result = dns_adb_marklame(fctx->adb, query->addrinfo, 7716 &fctx->name, fctx->type, 7717 now + fctx->res->lame_ttl); 7718 if (result != ISC_R_SUCCESS) 7719 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 7720 DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR, 7721 "could not mark server as lame: %s", 7722 isc_result_totext(result)); 7723 broken_server = DNS_R_LAME; 7724 keep_trying = ISC_TRUE; 7725 goto done; 7726 } 7727 7728 /* 7729 * Enforce delegations only zones like NET and COM. 7730 */ 7731 if (!ISFORWARDER(query->addrinfo) && 7732 dns_view_isdelegationonly(fctx->res->view, &fctx->domain) && 7733 !dns_name_equal(&fctx->domain, &fctx->name) && 7734 fix_mustbedelegationornxdomain(message, fctx)) { 7735 char namebuf[DNS_NAME_FORMATSIZE]; 7736 char domainbuf[DNS_NAME_FORMATSIZE]; 7737 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 7738 char classbuf[64]; 7739 char typebuf[64]; 7740 7741 dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); 7742 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); 7743 dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf)); 7744 dns_rdataclass_format(fctx->res->rdclass, classbuf, 7745 sizeof(classbuf)); 7746 isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, 7747 sizeof(addrbuf)); 7748 7749 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DELEGATION_ONLY, 7750 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, 7751 "enforced delegation-only for '%s' (%s/%s/%s) " 7752 "from %s", 7753 domainbuf, namebuf, typebuf, classbuf, addrbuf); 7754 } 7755 7756 if ((fctx->res->options & DNS_RESOLVER_CHECKNAMES) != 0) 7757 checknames(message); 7758 7759 /* 7760 * Clear cache bits. 7761 */ 7762 fctx->attributes &= ~(FCTX_ATTR_WANTNCACHE | FCTX_ATTR_WANTCACHE); 7763 7764 /* 7765 * Did we get any answers? 7766 */ 7767 if (message->counts[DNS_SECTION_ANSWER] > 0 && 7768 (message->rcode == dns_rcode_noerror || 7769 message->rcode == dns_rcode_nxdomain)) { 7770 /* 7771 * [normal case] 7772 * We've got answers. If it has an authoritative answer or an 7773 * answer from a forwarder, we're done. 7774 */ 7775 if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 || 7776 ISFORWARDER(query->addrinfo)) 7777 result = answer_response(fctx); 7778 else if (iscname(fctx) && 7779 fctx->type != dns_rdatatype_any && 7780 fctx->type != dns_rdatatype_cname) { 7781 /* 7782 * A BIND8 server could return a non-authoritative 7783 * answer when a CNAME is followed. We should treat 7784 * it as a valid answer. 7785 */ 7786 result = answer_response(fctx); 7787 } else if (fctx->type != dns_rdatatype_ns && 7788 !betterreferral(fctx)) { 7789 /* 7790 * Lame response !!!. 7791 */ 7792 result = answer_response(fctx); 7793 } else { 7794 if (fctx->type == dns_rdatatype_ns) { 7795 /* 7796 * A BIND 8 server could incorrectly return a 7797 * non-authoritative answer to an NS query 7798 * instead of a referral. Since this answer 7799 * lacks the SIGs necessary to do DNSSEC 7800 * validation, we must invoke the following 7801 * special kludge to treat it as a referral. 7802 */ 7803 result = noanswer_response(fctx, NULL, 7804 LOOK_FOR_NS_IN_ANSWER); 7805 } else { 7806 /* 7807 * Some other servers may still somehow include 7808 * an answer when it should return a referral 7809 * with an empty answer. Check to see if we can 7810 * treat this as a referral by ignoring the 7811 * answer. Further more, there may be an 7812 * implementation that moves A/AAAA glue records 7813 * to the answer section for that type of 7814 * delegation when the query is for that glue 7815 * record. LOOK_FOR_GLUE_IN_ANSWER will handle 7816 * such a corner case. 7817 */ 7818 result = noanswer_response(fctx, NULL, 7819 LOOK_FOR_GLUE_IN_ANSWER); 7820 } 7821 if (result != DNS_R_DELEGATION) { 7822 /* 7823 * At this point, AA is not set, the response 7824 * is not a referral, and the server is not a 7825 * forwarder. It is technically lame and it's 7826 * easier to treat it as such than to figure out 7827 * some more elaborate course of action. 7828 */ 7829 broken_server = DNS_R_LAME; 7830 keep_trying = ISC_TRUE; 7831 goto done; 7832 } 7833 goto force_referral; 7834 } 7835 if (result != ISC_R_SUCCESS) { 7836 if (result == DNS_R_FORMERR) 7837 keep_trying = ISC_TRUE; 7838 goto done; 7839 } 7840 } else if (message->counts[DNS_SECTION_AUTHORITY] > 0 || 7841 message->rcode == dns_rcode_noerror || 7842 message->rcode == dns_rcode_nxdomain) { 7843 /* 7844 * NXDOMAIN, NXRDATASET, or referral. 7845 */ 7846 result = noanswer_response(fctx, NULL, 0); 7847 switch (result) { 7848 case ISC_R_SUCCESS: 7849 case DNS_R_CHASEDSSERVERS: 7850 break; 7851 case DNS_R_DELEGATION: 7852 force_referral: 7853 /* 7854 * We don't have the answer, but we know a better 7855 * place to look. 7856 */ 7857 get_nameservers = ISC_TRUE; 7858 keep_trying = ISC_TRUE; 7859 /* 7860 * We have a new set of name servers, and it 7861 * has not experienced any restarts yet. 7862 */ 7863 fctx->restarts = 0; 7864 7865 /* 7866 * Update local statistics counters collected for each 7867 * new zone. 7868 */ 7869 fctx->referrals++; 7870 fctx->querysent = 0; 7871 fctx->lamecount = 0; 7872 fctx->neterr = 0; 7873 fctx->badresp = 0; 7874 fctx->adberr = 0; 7875 7876 result = ISC_R_SUCCESS; 7877 break; 7878 default: 7879 /* 7880 * Something has gone wrong. 7881 */ 7882 if (result == DNS_R_FORMERR) 7883 keep_trying = ISC_TRUE; 7884 goto done; 7885 } 7886 } else { 7887 /* 7888 * The server is insane. 7889 */ 7890 /* XXXRTH Log */ 7891 broken_server = DNS_R_UNEXPECTEDRCODE; 7892 keep_trying = ISC_TRUE; 7893 goto done; 7894 } 7895 7896 /* 7897 * Follow additional section data chains. 7898 */ 7899 chase_additional(fctx); 7900 7901 /* 7902 * Cache the cacheable parts of the message. This may also cause 7903 * work to be queued to the DNSSEC validator. 7904 */ 7905 if (WANTCACHE(fctx)) { 7906 result = cache_message(fctx, query->addrinfo, now); 7907 if (result != ISC_R_SUCCESS) 7908 goto done; 7909 } 7910 7911 /* 7912 * Ncache the negatively cacheable parts of the message. This may 7913 * also cause work to be queued to the DNSSEC validator. 7914 */ 7915 if (WANTNCACHE(fctx)) { 7916 dns_rdatatype_t covers; 7917 7918 /* 7919 * Cache DS NXDOMAIN seperately to other types. 7920 */ 7921 if (message->rcode == dns_rcode_nxdomain && 7922 fctx->type != dns_rdatatype_ds) 7923 covers = dns_rdatatype_any; 7924 else 7925 covers = fctx->type; 7926 7927 /* 7928 * Cache any negative cache entries in the message. 7929 */ 7930 result = ncache_message(fctx, query->addrinfo, covers, now); 7931 } 7932 7933 done: 7934 /* 7935 * Remember the query's addrinfo, in case we need to mark the 7936 * server as broken. 7937 */ 7938 addrinfo = query->addrinfo; 7939 7940 /* 7941 * Cancel the query. 7942 * 7943 * XXXRTH Don't cancel the query if waiting for validation? 7944 */ 7945 fctx_cancelquery(&query, &devent, finish, no_response); 7946 7947 if (keep_trying) { 7948 if (result == DNS_R_FORMERR) 7949 broken_server = DNS_R_FORMERR; 7950 if (broken_server != ISC_R_SUCCESS) { 7951 /* 7952 * Add this server to the list of bad servers for 7953 * this fctx. 7954 */ 7955 add_bad(fctx, addrinfo, broken_server, broken_type); 7956 } 7957 7958 if (get_nameservers) { 7959 dns_name_t *name; 7960 dns_fixedname_init(&foundname); 7961 fname = dns_fixedname_name(&foundname); 7962 if (result != ISC_R_SUCCESS) { 7963 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 7964 return; 7965 } 7966 findoptions = 0; 7967 if (dns_rdatatype_atparent(fctx->type)) 7968 findoptions |= DNS_DBFIND_NOEXACT; 7969 if ((options & DNS_FETCHOPT_UNSHARED) == 0) 7970 name = &fctx->name; 7971 else 7972 name = &fctx->domain; 7973 result = dns_view_findzonecut(fctx->res->view, 7974 name, fname, 7975 now, findoptions, 7976 ISC_TRUE, 7977 &fctx->nameservers, 7978 NULL); 7979 if (result != ISC_R_SUCCESS) { 7980 FCTXTRACE("couldn't find a zonecut"); 7981 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 7982 return; 7983 } 7984 if (!dns_name_issubdomain(fname, &fctx->domain)) { 7985 /* 7986 * The best nameservers are now above our 7987 * QDOMAIN. 7988 */ 7989 FCTXTRACE("nameservers now above QDOMAIN"); 7990 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 7991 return; 7992 } 7993 dns_name_free(&fctx->domain, fctx->mctx); 7994 dns_name_init(&fctx->domain, NULL); 7995 result = dns_name_dup(fname, fctx->mctx, &fctx->domain); 7996 if (result != ISC_R_SUCCESS) { 7997 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); 7998 return; 7999 } 8000 fctx->ns_ttl = fctx->nameservers.ttl; 8001 fctx->ns_ttl_ok = ISC_TRUE; 8002 fctx_cancelqueries(fctx, ISC_TRUE); 8003 fctx_cleanupfinds(fctx); 8004 fctx_cleanupaltfinds(fctx); 8005 fctx_cleanupforwaddrs(fctx); 8006 fctx_cleanupaltaddrs(fctx); 8007 } 8008 /* 8009 * Try again. 8010 */ 8011 fctx_try(fctx, !get_nameservers, ISC_FALSE); 8012 } else if (resend) { 8013 /* 8014 * Resend (probably with changed options). 8015 */ 8016 FCTXTRACE("resend"); 8017 inc_stats(fctx->res, dns_resstatscounter_retry); 8018 result = fctx_query(fctx, addrinfo, options); 8019 if (result != ISC_R_SUCCESS) 8020 fctx_done(fctx, result, __LINE__); 8021 } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) { 8022 /* 8023 * All has gone well so far, but we are waiting for the 8024 * DNSSEC validator to validate the answer. 8025 */ 8026 FCTXTRACE("wait for validator"); 8027 fctx_cancelqueries(fctx, ISC_TRUE); 8028 /* 8029 * We must not retransmit while the validator is working; 8030 * it has references to the current rmessage. 8031 */ 8032 result = fctx_stopidletimer(fctx); 8033 if (result != ISC_R_SUCCESS) 8034 fctx_done(fctx, result, __LINE__); 8035 } else if (result == DNS_R_CHASEDSSERVERS) { 8036 unsigned int n; 8037 add_bad(fctx, addrinfo, result, broken_type); 8038 fctx_cancelqueries(fctx, ISC_TRUE); 8039 fctx_cleanupfinds(fctx); 8040 fctx_cleanupforwaddrs(fctx); 8041 8042 n = dns_name_countlabels(&fctx->name); 8043 dns_name_getlabelsequence(&fctx->name, 1, n - 1, &fctx->nsname); 8044 8045 FCTXTRACE("suspending DS lookup to find parent's NS records"); 8046 8047 result = dns_resolver_createfetch(fctx->res, &fctx->nsname, 8048 dns_rdatatype_ns, 8049 NULL, NULL, NULL, 8050 fctx->options, task, 8051 resume_dslookup, fctx, 8052 &fctx->nsrrset, NULL, 8053 &fctx->nsfetch); 8054 if (result != ISC_R_SUCCESS) 8055 fctx_done(fctx, result, __LINE__); 8056 else { 8057 LOCK(&fctx->res->buckets[fctx->bucketnum].lock); 8058 fctx->references++; 8059 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); 8060 result = fctx_stopidletimer(fctx); 8061 if (result != ISC_R_SUCCESS) 8062 fctx_done(fctx, result, __LINE__); 8063 } 8064 } else { 8065 /* 8066 * We're done. 8067 */ 8068 fctx_done(fctx, result, __LINE__); 8069 } 8070 } 8071 8072 8073 /*** 8074 *** Resolver Methods 8075 ***/ 8076 static void 8077 destroy_badcache(dns_resolver_t *res) { 8078 dns_badcache_t *bad, *next; 8079 unsigned int i; 8080 8081 if (res->badcache != NULL) { 8082 for (i = 0; i < res->badhash; i++) 8083 for (bad = res->badcache[i]; bad != NULL; 8084 bad = next) { 8085 next = bad->next; 8086 isc_mem_put(res->mctx, bad, sizeof(*bad) + 8087 bad->name.length); 8088 res->badcount--; 8089 } 8090 isc_mem_put(res->mctx, res->badcache, 8091 sizeof(*res->badcache) * res->badhash); 8092 res->badcache = NULL; 8093 res->badhash = 0; 8094 INSIST(res->badcount == 0); 8095 } 8096 } 8097 8098 static void 8099 destroy(dns_resolver_t *res) { 8100 unsigned int i; 8101 alternate_t *a; 8102 8103 REQUIRE(res->references == 0); 8104 REQUIRE(!res->priming); 8105 REQUIRE(res->primefetch == NULL); 8106 8107 RTRACE("destroy"); 8108 8109 INSIST(res->nfctx == 0); 8110 8111 DESTROYLOCK(&res->primelock); 8112 DESTROYLOCK(&res->nlock); 8113 DESTROYLOCK(&res->lock); 8114 for (i = 0; i < res->nbuckets; i++) { 8115 INSIST(ISC_LIST_EMPTY(res->buckets[i].fctxs)); 8116 isc_task_shutdown(res->buckets[i].task); 8117 isc_task_detach(&res->buckets[i].task); 8118 DESTROYLOCK(&res->buckets[i].lock); 8119 isc_mem_detach(&res->buckets[i].mctx); 8120 } 8121 isc_mem_put(res->mctx, res->buckets, 8122 res->nbuckets * sizeof(fctxbucket_t)); 8123 if (res->dispatches4 != NULL) 8124 dns_dispatchset_destroy(&res->dispatches4); 8125 if (res->dispatches6 != NULL) 8126 dns_dispatchset_destroy(&res->dispatches6); 8127 while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) { 8128 ISC_LIST_UNLINK(res->alternates, a, link); 8129 if (!a->isaddress) 8130 dns_name_free(&a->_u._n.name, res->mctx); 8131 isc_mem_put(res->mctx, a, sizeof(*a)); 8132 } 8133 dns_resolver_reset_algorithms(res); 8134 dns_resolver_reset_ds_digests(res); 8135 destroy_badcache(res); 8136 dns_resolver_resetmustbesecure(res); 8137 #if USE_ALGLOCK 8138 isc_rwlock_destroy(&res->alglock); 8139 #endif 8140 #if USE_MBSLOCK 8141 isc_rwlock_destroy(&res->mbslock); 8142 #endif 8143 isc_timer_detach(&res->spillattimer); 8144 res->magic = 0; 8145 isc_mem_put(res->mctx, res, sizeof(*res)); 8146 } 8147 8148 static void 8149 send_shutdown_events(dns_resolver_t *res) { 8150 isc_event_t *event, *next_event; 8151 isc_task_t *etask; 8152 8153 /* 8154 * Caller must be holding the resolver lock. 8155 */ 8156 8157 for (event = ISC_LIST_HEAD(res->whenshutdown); 8158 event != NULL; 8159 event = next_event) { 8160 next_event = ISC_LIST_NEXT(event, ev_link); 8161 ISC_LIST_UNLINK(res->whenshutdown, event, ev_link); 8162 etask = event->ev_sender; 8163 event->ev_sender = res; 8164 isc_task_sendanddetach(&etask, &event); 8165 } 8166 } 8167 8168 static void 8169 empty_bucket(dns_resolver_t *res) { 8170 RTRACE("empty_bucket"); 8171 8172 LOCK(&res->lock); 8173 8174 INSIST(res->activebuckets > 0); 8175 res->activebuckets--; 8176 if (res->activebuckets == 0) 8177 send_shutdown_events(res); 8178 8179 UNLOCK(&res->lock); 8180 } 8181 8182 static void 8183 spillattimer_countdown(isc_task_t *task, isc_event_t *event) { 8184 dns_resolver_t *res = event->ev_arg; 8185 isc_result_t result; 8186 unsigned int count; 8187 isc_boolean_t logit = ISC_FALSE; 8188 8189 REQUIRE(VALID_RESOLVER(res)); 8190 8191 UNUSED(task); 8192 8193 LOCK(&res->lock); 8194 INSIST(!res->exiting); 8195 if (res->spillat > res->spillatmin) { 8196 res->spillat--; 8197 logit = ISC_TRUE; 8198 } 8199 if (res->spillat <= res->spillatmin) { 8200 result = isc_timer_reset(res->spillattimer, 8201 isc_timertype_inactive, NULL, 8202 NULL, ISC_TRUE); 8203 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8204 } 8205 count = res->spillat; 8206 UNLOCK(&res->lock); 8207 if (logit) 8208 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 8209 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, 8210 "clients-per-query decreased to %u", count); 8211 8212 isc_event_free(&event); 8213 } 8214 8215 isc_result_t 8216 dns_resolver_create(dns_view_t *view, 8217 isc_taskmgr_t *taskmgr, 8218 unsigned int ntasks, unsigned int ndisp, 8219 isc_socketmgr_t *socketmgr, 8220 isc_timermgr_t *timermgr, 8221 unsigned int options, 8222 dns_dispatchmgr_t *dispatchmgr, 8223 dns_dispatch_t *dispatchv4, 8224 dns_dispatch_t *dispatchv6, 8225 dns_resolver_t **resp) 8226 { 8227 dns_resolver_t *res; 8228 isc_result_t result = ISC_R_SUCCESS; 8229 unsigned int i, buckets_created = 0; 8230 isc_task_t *task = NULL; 8231 char name[16]; 8232 unsigned dispattr; 8233 8234 /* 8235 * Create a resolver. 8236 */ 8237 8238 REQUIRE(DNS_VIEW_VALID(view)); 8239 REQUIRE(ntasks > 0); 8240 REQUIRE(ndisp > 0); 8241 REQUIRE(resp != NULL && *resp == NULL); 8242 REQUIRE(dispatchmgr != NULL); 8243 REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL); 8244 8245 res = isc_mem_get(view->mctx, sizeof(*res)); 8246 if (res == NULL) 8247 return (ISC_R_NOMEMORY); 8248 RTRACE("create"); 8249 res->mctx = view->mctx; 8250 res->rdclass = view->rdclass; 8251 res->socketmgr = socketmgr; 8252 res->timermgr = timermgr; 8253 res->taskmgr = taskmgr; 8254 res->dispatchmgr = dispatchmgr; 8255 res->view = view; 8256 res->options = options; 8257 res->lame_ttl = 0; 8258 ISC_LIST_INIT(res->alternates); 8259 res->udpsize = RECV_BUFFER_SIZE; 8260 res->algorithms = NULL; 8261 res->digests = NULL; 8262 res->badcache = NULL; 8263 res->badcount = 0; 8264 res->badhash = 0; 8265 res->badsweep = 0; 8266 res->mustbesecure = NULL; 8267 res->spillatmin = res->spillat = 10; 8268 res->spillatmax = 100; 8269 res->spillattimer = NULL; 8270 res->zero_no_soa_ttl = ISC_FALSE; 8271 res->query_timeout = DEFAULT_QUERY_TIMEOUT; 8272 res->maxdepth = DEFAULT_RECURSION_DEPTH; 8273 res->maxqueries = DEFAULT_MAX_QUERIES; 8274 res->nbuckets = ntasks; 8275 if (view->resstats != NULL) 8276 isc_stats_set(view->resstats, ntasks, 8277 dns_resstatscounter_buckets); 8278 res->activebuckets = ntasks; 8279 res->buckets = isc_mem_get(view->mctx, 8280 ntasks * sizeof(fctxbucket_t)); 8281 if (res->buckets == NULL) { 8282 result = ISC_R_NOMEMORY; 8283 goto cleanup_res; 8284 } 8285 for (i = 0; i < ntasks; i++) { 8286 result = isc_mutex_init(&res->buckets[i].lock); 8287 if (result != ISC_R_SUCCESS) 8288 goto cleanup_buckets; 8289 res->buckets[i].task = NULL; 8290 result = isc_task_create(taskmgr, 0, &res->buckets[i].task); 8291 if (result != ISC_R_SUCCESS) { 8292 DESTROYLOCK(&res->buckets[i].lock); 8293 goto cleanup_buckets; 8294 } 8295 res->buckets[i].mctx = NULL; 8296 snprintf(name, sizeof(name), "res%u", i); 8297 #ifdef ISC_PLATFORM_USETHREADS 8298 /* 8299 * Use a separate memory context for each bucket to reduce 8300 * contention among multiple threads. Do this only when 8301 * enabling threads because it will be require more memory. 8302 */ 8303 result = isc_mem_create(0, 0, &res->buckets[i].mctx); 8304 if (result != ISC_R_SUCCESS) { 8305 isc_task_detach(&res->buckets[i].task); 8306 DESTROYLOCK(&res->buckets[i].lock); 8307 goto cleanup_buckets; 8308 } 8309 isc_mem_setname(res->buckets[i].mctx, name, NULL); 8310 #else 8311 isc_mem_attach(view->mctx, &res->buckets[i].mctx); 8312 #endif 8313 isc_task_setname(res->buckets[i].task, name, res); 8314 ISC_LIST_INIT(res->buckets[i].fctxs); 8315 res->buckets[i].exiting = ISC_FALSE; 8316 buckets_created++; 8317 } 8318 8319 res->dispatches4 = NULL; 8320 if (dispatchv4 != NULL) { 8321 dns_dispatchset_create(view->mctx, socketmgr, taskmgr, 8322 dispatchv4, &res->dispatches4, ndisp); 8323 dispattr = dns_dispatch_getattributes(dispatchv4); 8324 res->exclusivev4 = 8325 ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0); 8326 } 8327 8328 res->dispatches6 = NULL; 8329 if (dispatchv6 != NULL) { 8330 dns_dispatchset_create(view->mctx, socketmgr, taskmgr, 8331 dispatchv6, &res->dispatches6, ndisp); 8332 dispattr = dns_dispatch_getattributes(dispatchv6); 8333 res->exclusivev6 = 8334 ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0); 8335 } 8336 8337 res->querydscp4 = -1; 8338 res->querydscp6 = -1; 8339 res->references = 1; 8340 res->exiting = ISC_FALSE; 8341 res->frozen = ISC_FALSE; 8342 ISC_LIST_INIT(res->whenshutdown); 8343 res->priming = ISC_FALSE; 8344 res->primefetch = NULL; 8345 res->nfctx = 0; 8346 8347 result = isc_mutex_init(&res->lock); 8348 if (result != ISC_R_SUCCESS) 8349 goto cleanup_dispatches; 8350 8351 result = isc_mutex_init(&res->nlock); 8352 if (result != ISC_R_SUCCESS) 8353 goto cleanup_lock; 8354 8355 result = isc_mutex_init(&res->primelock); 8356 if (result != ISC_R_SUCCESS) 8357 goto cleanup_nlock; 8358 8359 task = NULL; 8360 result = isc_task_create(taskmgr, 0, &task); 8361 if (result != ISC_R_SUCCESS) 8362 goto cleanup_primelock; 8363 8364 result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, 8365 task, spillattimer_countdown, res, 8366 &res->spillattimer); 8367 isc_task_detach(&task); 8368 if (result != ISC_R_SUCCESS) 8369 goto cleanup_primelock; 8370 8371 #if USE_ALGLOCK 8372 result = isc_rwlock_init(&res->alglock, 0, 0); 8373 if (result != ISC_R_SUCCESS) 8374 goto cleanup_spillattimer; 8375 #endif 8376 #if USE_MBSLOCK 8377 result = isc_rwlock_init(&res->mbslock, 0, 0); 8378 if (result != ISC_R_SUCCESS) 8379 goto cleanup_alglock; 8380 #endif 8381 8382 res->magic = RES_MAGIC; 8383 8384 *resp = res; 8385 8386 return (ISC_R_SUCCESS); 8387 8388 #if USE_MBSLOCK 8389 cleanup_alglock: 8390 #if USE_ALGLOCK 8391 isc_rwlock_destroy(&res->alglock); 8392 #endif 8393 #endif 8394 #if USE_ALGLOCK || USE_MBSLOCK 8395 cleanup_spillattimer: 8396 isc_timer_detach(&res->spillattimer); 8397 #endif 8398 8399 cleanup_primelock: 8400 DESTROYLOCK(&res->primelock); 8401 8402 cleanup_nlock: 8403 DESTROYLOCK(&res->nlock); 8404 8405 cleanup_lock: 8406 DESTROYLOCK(&res->lock); 8407 8408 cleanup_dispatches: 8409 if (res->dispatches6 != NULL) 8410 dns_dispatchset_destroy(&res->dispatches6); 8411 if (res->dispatches4 != NULL) 8412 dns_dispatchset_destroy(&res->dispatches4); 8413 8414 cleanup_buckets: 8415 for (i = 0; i < buckets_created; i++) { 8416 isc_mem_detach(&res->buckets[i].mctx); 8417 DESTROYLOCK(&res->buckets[i].lock); 8418 isc_task_shutdown(res->buckets[i].task); 8419 isc_task_detach(&res->buckets[i].task); 8420 } 8421 isc_mem_put(view->mctx, res->buckets, 8422 res->nbuckets * sizeof(fctxbucket_t)); 8423 8424 cleanup_res: 8425 isc_mem_put(view->mctx, res, sizeof(*res)); 8426 8427 return (result); 8428 } 8429 8430 static void 8431 prime_done(isc_task_t *task, isc_event_t *event) { 8432 dns_resolver_t *res; 8433 dns_fetchevent_t *fevent; 8434 dns_fetch_t *fetch; 8435 dns_db_t *db = NULL; 8436 8437 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); 8438 fevent = (dns_fetchevent_t *)event; 8439 res = event->ev_arg; 8440 REQUIRE(VALID_RESOLVER(res)); 8441 8442 UNUSED(task); 8443 8444 LOCK(&res->lock); 8445 8446 INSIST(res->priming); 8447 res->priming = ISC_FALSE; 8448 LOCK(&res->primelock); 8449 fetch = res->primefetch; 8450 res->primefetch = NULL; 8451 UNLOCK(&res->primelock); 8452 8453 UNLOCK(&res->lock); 8454 8455 if (fevent->result == ISC_R_SUCCESS && 8456 res->view->cache != NULL && res->view->hints != NULL) { 8457 dns_cache_attachdb(res->view->cache, &db); 8458 dns_root_checkhints(res->view, res->view->hints, db); 8459 dns_db_detach(&db); 8460 } 8461 8462 if (fevent->node != NULL) 8463 dns_db_detachnode(fevent->db, &fevent->node); 8464 if (fevent->db != NULL) 8465 dns_db_detach(&fevent->db); 8466 if (dns_rdataset_isassociated(fevent->rdataset)) 8467 dns_rdataset_disassociate(fevent->rdataset); 8468 INSIST(fevent->sigrdataset == NULL); 8469 8470 isc_mem_put(res->mctx, fevent->rdataset, sizeof(*fevent->rdataset)); 8471 8472 isc_event_free(&event); 8473 dns_resolver_destroyfetch(&fetch); 8474 } 8475 8476 void 8477 dns_resolver_prime(dns_resolver_t *res) { 8478 isc_boolean_t want_priming = ISC_FALSE; 8479 dns_rdataset_t *rdataset; 8480 isc_result_t result; 8481 8482 REQUIRE(VALID_RESOLVER(res)); 8483 REQUIRE(res->frozen); 8484 8485 RTRACE("dns_resolver_prime"); 8486 8487 LOCK(&res->lock); 8488 8489 if (!res->exiting && !res->priming) { 8490 INSIST(res->primefetch == NULL); 8491 res->priming = ISC_TRUE; 8492 want_priming = ISC_TRUE; 8493 } 8494 8495 UNLOCK(&res->lock); 8496 8497 if (want_priming) { 8498 /* 8499 * To avoid any possible recursive locking problems, we 8500 * start the priming fetch like any other fetch, and holding 8501 * no resolver locks. No one else will try to start it 8502 * because we're the ones who set res->priming to true. 8503 * Any other callers of dns_resolver_prime() while we're 8504 * running will see that res->priming is already true and 8505 * do nothing. 8506 */ 8507 RTRACE("priming"); 8508 rdataset = isc_mem_get(res->mctx, sizeof(*rdataset)); 8509 if (rdataset == NULL) { 8510 LOCK(&res->lock); 8511 INSIST(res->priming); 8512 INSIST(res->primefetch == NULL); 8513 res->priming = ISC_FALSE; 8514 UNLOCK(&res->lock); 8515 return; 8516 } 8517 dns_rdataset_init(rdataset); 8518 LOCK(&res->primelock); 8519 result = dns_resolver_createfetch(res, dns_rootname, 8520 dns_rdatatype_ns, 8521 NULL, NULL, NULL, 0, 8522 res->buckets[0].task, 8523 prime_done, 8524 res, rdataset, NULL, 8525 &res->primefetch); 8526 UNLOCK(&res->primelock); 8527 if (result != ISC_R_SUCCESS) { 8528 LOCK(&res->lock); 8529 INSIST(res->priming); 8530 res->priming = ISC_FALSE; 8531 UNLOCK(&res->lock); 8532 } 8533 } 8534 } 8535 8536 void 8537 dns_resolver_freeze(dns_resolver_t *res) { 8538 /* 8539 * Freeze resolver. 8540 */ 8541 8542 REQUIRE(VALID_RESOLVER(res)); 8543 8544 res->frozen = ISC_TRUE; 8545 } 8546 8547 void 8548 dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) { 8549 REQUIRE(VALID_RESOLVER(source)); 8550 REQUIRE(targetp != NULL && *targetp == NULL); 8551 8552 RRTRACE(source, "attach"); 8553 LOCK(&source->lock); 8554 REQUIRE(!source->exiting); 8555 8556 INSIST(source->references > 0); 8557 source->references++; 8558 INSIST(source->references != 0); 8559 UNLOCK(&source->lock); 8560 8561 *targetp = source; 8562 } 8563 8564 void 8565 dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task, 8566 isc_event_t **eventp) 8567 { 8568 isc_task_t *clone; 8569 isc_event_t *event; 8570 8571 REQUIRE(VALID_RESOLVER(res)); 8572 REQUIRE(eventp != NULL); 8573 8574 event = *eventp; 8575 *eventp = NULL; 8576 8577 LOCK(&res->lock); 8578 8579 if (res->exiting && res->activebuckets == 0) { 8580 /* 8581 * We're already shutdown. Send the event. 8582 */ 8583 event->ev_sender = res; 8584 isc_task_send(task, &event); 8585 } else { 8586 clone = NULL; 8587 isc_task_attach(task, &clone); 8588 event->ev_sender = clone; 8589 ISC_LIST_APPEND(res->whenshutdown, event, ev_link); 8590 } 8591 8592 UNLOCK(&res->lock); 8593 } 8594 8595 void 8596 dns_resolver_shutdown(dns_resolver_t *res) { 8597 unsigned int i; 8598 fetchctx_t *fctx; 8599 isc_result_t result; 8600 8601 REQUIRE(VALID_RESOLVER(res)); 8602 8603 RTRACE("shutdown"); 8604 8605 LOCK(&res->lock); 8606 8607 if (!res->exiting) { 8608 RTRACE("exiting"); 8609 res->exiting = ISC_TRUE; 8610 8611 for (i = 0; i < res->nbuckets; i++) { 8612 LOCK(&res->buckets[i].lock); 8613 for (fctx = ISC_LIST_HEAD(res->buckets[i].fctxs); 8614 fctx != NULL; 8615 fctx = ISC_LIST_NEXT(fctx, link)) 8616 fctx_shutdown(fctx); 8617 if (res->dispatches4 != NULL && !res->exclusivev4) { 8618 dns_dispatchset_cancelall(res->dispatches4, 8619 res->buckets[i].task); 8620 } 8621 if (res->dispatches6 != NULL && !res->exclusivev6) { 8622 dns_dispatchset_cancelall(res->dispatches6, 8623 res->buckets[i].task); 8624 } 8625 res->buckets[i].exiting = ISC_TRUE; 8626 if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) { 8627 INSIST(res->activebuckets > 0); 8628 res->activebuckets--; 8629 } 8630 UNLOCK(&res->buckets[i].lock); 8631 } 8632 if (res->activebuckets == 0) 8633 send_shutdown_events(res); 8634 result = isc_timer_reset(res->spillattimer, 8635 isc_timertype_inactive, NULL, 8636 NULL, ISC_TRUE); 8637 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8638 } 8639 8640 UNLOCK(&res->lock); 8641 } 8642 8643 void 8644 dns_resolver_detach(dns_resolver_t **resp) { 8645 dns_resolver_t *res; 8646 isc_boolean_t need_destroy = ISC_FALSE; 8647 8648 REQUIRE(resp != NULL); 8649 res = *resp; 8650 REQUIRE(VALID_RESOLVER(res)); 8651 8652 RTRACE("detach"); 8653 8654 LOCK(&res->lock); 8655 8656 INSIST(res->references > 0); 8657 res->references--; 8658 if (res->references == 0) { 8659 INSIST(res->exiting && res->activebuckets == 0); 8660 need_destroy = ISC_TRUE; 8661 } 8662 8663 UNLOCK(&res->lock); 8664 8665 if (need_destroy) 8666 destroy(res); 8667 8668 *resp = NULL; 8669 } 8670 8671 static inline isc_boolean_t 8672 fctx_match(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type, 8673 unsigned int options) 8674 { 8675 /* 8676 * Don't match fetch contexts that are shutting down. 8677 */ 8678 if (fctx->cloned || fctx->state == fetchstate_done || 8679 ISC_LIST_EMPTY(fctx->events)) 8680 return (ISC_FALSE); 8681 8682 if (fctx->type != type || fctx->options != options) 8683 return (ISC_FALSE); 8684 return (dns_name_equal(&fctx->name, name)); 8685 } 8686 8687 static inline void 8688 log_fetch(dns_name_t *name, dns_rdatatype_t type) { 8689 char namebuf[DNS_NAME_FORMATSIZE]; 8690 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 8691 int level = ISC_LOG_DEBUG(1); 8692 8693 if (! isc_log_wouldlog(dns_lctx, level)) 8694 return; 8695 8696 dns_name_format(name, namebuf, sizeof(namebuf)); 8697 dns_rdatatype_format(type, typebuf, sizeof(typebuf)); 8698 8699 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, 8700 DNS_LOGMODULE_RESOLVER, level, 8701 "fetch: %s/%s", namebuf, typebuf); 8702 } 8703 8704 isc_result_t 8705 dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, 8706 dns_rdatatype_t type, 8707 dns_name_t *domain, dns_rdataset_t *nameservers, 8708 dns_forwarders_t *forwarders, 8709 unsigned int options, isc_task_t *task, 8710 isc_taskaction_t action, void *arg, 8711 dns_rdataset_t *rdataset, 8712 dns_rdataset_t *sigrdataset, 8713 dns_fetch_t **fetchp) 8714 { 8715 return (dns_resolver_createfetch3(res, name, type, domain, 8716 nameservers, forwarders, NULL, 0, 8717 options, 0, NULL, task, action, arg, 8718 rdataset, sigrdataset, fetchp)); 8719 } 8720 8721 isc_result_t 8722 dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, 8723 dns_rdatatype_t type, 8724 dns_name_t *domain, dns_rdataset_t *nameservers, 8725 dns_forwarders_t *forwarders, 8726 isc_sockaddr_t *client, dns_messageid_t id, 8727 unsigned int options, isc_task_t *task, 8728 isc_taskaction_t action, void *arg, 8729 dns_rdataset_t *rdataset, 8730 dns_rdataset_t *sigrdataset, 8731 dns_fetch_t **fetchp) 8732 { 8733 return (dns_resolver_createfetch3(res, name, type, domain, 8734 nameservers, forwarders, client, id, 8735 options, 0, NULL, task, action, arg, 8736 rdataset, sigrdataset, fetchp)); 8737 } 8738 8739 isc_result_t 8740 dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, 8741 dns_rdatatype_t type, 8742 dns_name_t *domain, dns_rdataset_t *nameservers, 8743 dns_forwarders_t *forwarders, 8744 isc_sockaddr_t *client, dns_messageid_t id, 8745 unsigned int options, unsigned int depth, 8746 isc_counter_t *qc, isc_task_t *task, 8747 isc_taskaction_t action, void *arg, 8748 dns_rdataset_t *rdataset, 8749 dns_rdataset_t *sigrdataset, 8750 dns_fetch_t **fetchp) 8751 { 8752 dns_fetch_t *fetch; 8753 fetchctx_t *fctx = NULL; 8754 isc_result_t result = ISC_R_SUCCESS; 8755 unsigned int bucketnum; 8756 isc_boolean_t new_fctx = ISC_FALSE; 8757 isc_event_t *event; 8758 unsigned int count = 0; 8759 unsigned int spillat; 8760 unsigned int spillatmin; 8761 isc_boolean_t destroy = ISC_FALSE; 8762 8763 UNUSED(forwarders); 8764 8765 REQUIRE(VALID_RESOLVER(res)); 8766 REQUIRE(res->frozen); 8767 /* XXXRTH Check for meta type */ 8768 if (domain != NULL) { 8769 REQUIRE(DNS_RDATASET_VALID(nameservers)); 8770 REQUIRE(nameservers->type == dns_rdatatype_ns); 8771 } else 8772 REQUIRE(nameservers == NULL); 8773 REQUIRE(forwarders == NULL); 8774 REQUIRE(!dns_rdataset_isassociated(rdataset)); 8775 REQUIRE(sigrdataset == NULL || 8776 !dns_rdataset_isassociated(sigrdataset)); 8777 REQUIRE(fetchp != NULL && *fetchp == NULL); 8778 8779 log_fetch(name, type); 8780 8781 /* 8782 * XXXRTH use a mempool? 8783 */ 8784 fetch = isc_mem_get(res->mctx, sizeof(*fetch)); 8785 if (fetch == NULL) 8786 return (ISC_R_NOMEMORY); 8787 fetch->mctx = NULL; 8788 isc_mem_attach(res->mctx, &fetch->mctx); 8789 8790 bucketnum = dns_name_fullhash(name, ISC_FALSE) % res->nbuckets; 8791 8792 LOCK(&res->lock); 8793 spillat = res->spillat; 8794 spillatmin = res->spillatmin; 8795 UNLOCK(&res->lock); 8796 LOCK(&res->buckets[bucketnum].lock); 8797 8798 if (res->buckets[bucketnum].exiting) { 8799 result = ISC_R_SHUTTINGDOWN; 8800 goto unlock; 8801 } 8802 8803 if ((options & DNS_FETCHOPT_UNSHARED) == 0) { 8804 for (fctx = ISC_LIST_HEAD(res->buckets[bucketnum].fctxs); 8805 fctx != NULL; 8806 fctx = ISC_LIST_NEXT(fctx, link)) { 8807 if (fctx_match(fctx, name, type, options)) 8808 break; 8809 } 8810 } 8811 8812 /* 8813 * Is this a duplicate? 8814 */ 8815 if (fctx != NULL && client != NULL) { 8816 dns_fetchevent_t *fevent; 8817 for (fevent = ISC_LIST_HEAD(fctx->events); 8818 fevent != NULL; 8819 fevent = ISC_LIST_NEXT(fevent, ev_link)) { 8820 if (fevent->client != NULL && fevent->id == id && 8821 isc_sockaddr_equal(fevent->client, client)) { 8822 result = DNS_R_DUPLICATE; 8823 goto unlock; 8824 } 8825 count++; 8826 } 8827 } 8828 if (count >= spillatmin && spillatmin != 0) { 8829 INSIST(fctx != NULL); 8830 if (count >= spillat) 8831 fctx->spilled = ISC_TRUE; 8832 if (fctx->spilled) { 8833 result = DNS_R_DROP; 8834 goto unlock; 8835 } 8836 } 8837 8838 if (fctx == NULL) { 8839 result = fctx_create(res, name, type, domain, nameservers, 8840 options, bucketnum, depth, qc, &fctx); 8841 if (result != ISC_R_SUCCESS) 8842 goto unlock; 8843 new_fctx = ISC_TRUE; 8844 } else if (fctx->depth > depth) 8845 fctx->depth = depth; 8846 8847 result = fctx_join(fctx, task, client, id, action, arg, 8848 rdataset, sigrdataset, fetch); 8849 if (new_fctx) { 8850 if (result == ISC_R_SUCCESS) { 8851 /* 8852 * Launch this fctx. 8853 */ 8854 event = &fctx->control_event; 8855 ISC_EVENT_INIT(event, sizeof(*event), 0, NULL, 8856 DNS_EVENT_FETCHCONTROL, 8857 fctx_start, fctx, NULL, 8858 NULL, NULL); 8859 isc_task_send(res->buckets[bucketnum].task, &event); 8860 } else { 8861 /* 8862 * We don't care about the result of fctx_unlink() 8863 * since we know we're not exiting. 8864 */ 8865 (void)fctx_unlink(fctx); 8866 destroy = ISC_TRUE; 8867 } 8868 } 8869 8870 unlock: 8871 UNLOCK(&res->buckets[bucketnum].lock); 8872 8873 if (destroy) 8874 fctx_destroy(fctx); 8875 8876 if (result == ISC_R_SUCCESS) { 8877 FTRACE("created"); 8878 *fetchp = fetch; 8879 } else 8880 isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch)); 8881 8882 return (result); 8883 } 8884 8885 void 8886 dns_resolver_cancelfetch(dns_fetch_t *fetch) { 8887 fetchctx_t *fctx; 8888 dns_resolver_t *res; 8889 dns_fetchevent_t *event, *next_event; 8890 isc_task_t *etask; 8891 8892 REQUIRE(DNS_FETCH_VALID(fetch)); 8893 fctx = fetch->private; 8894 REQUIRE(VALID_FCTX(fctx)); 8895 res = fctx->res; 8896 8897 FTRACE("cancelfetch"); 8898 8899 LOCK(&res->buckets[fctx->bucketnum].lock); 8900 8901 /* 8902 * Find the completion event for this fetch (as opposed 8903 * to those for other fetches that have joined the same 8904 * fctx) and send it with result = ISC_R_CANCELED. 8905 */ 8906 event = NULL; 8907 if (fctx->state != fetchstate_done) { 8908 for (event = ISC_LIST_HEAD(fctx->events); 8909 event != NULL; 8910 event = next_event) { 8911 next_event = ISC_LIST_NEXT(event, ev_link); 8912 if (event->fetch == fetch) { 8913 ISC_LIST_UNLINK(fctx->events, event, ev_link); 8914 break; 8915 } 8916 } 8917 } 8918 if (event != NULL) { 8919 etask = event->ev_sender; 8920 event->ev_sender = fctx; 8921 event->result = ISC_R_CANCELED; 8922 isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event)); 8923 } 8924 /* 8925 * The fctx continues running even if no fetches remain; 8926 * the answer is still cached. 8927 */ 8928 8929 UNLOCK(&res->buckets[fctx->bucketnum].lock); 8930 } 8931 8932 void 8933 dns_resolver_destroyfetch(dns_fetch_t **fetchp) { 8934 dns_fetch_t *fetch; 8935 dns_resolver_t *res; 8936 dns_fetchevent_t *event, *next_event; 8937 fetchctx_t *fctx; 8938 unsigned int bucketnum; 8939 isc_boolean_t bucket_empty; 8940 8941 REQUIRE(fetchp != NULL); 8942 fetch = *fetchp; 8943 REQUIRE(DNS_FETCH_VALID(fetch)); 8944 fctx = fetch->private; 8945 REQUIRE(VALID_FCTX(fctx)); 8946 res = fctx->res; 8947 8948 FTRACE("destroyfetch"); 8949 8950 bucketnum = fctx->bucketnum; 8951 LOCK(&res->buckets[bucketnum].lock); 8952 8953 /* 8954 * Sanity check: the caller should have gotten its event before 8955 * trying to destroy the fetch. 8956 */ 8957 event = NULL; 8958 if (fctx->state != fetchstate_done) { 8959 for (event = ISC_LIST_HEAD(fctx->events); 8960 event != NULL; 8961 event = next_event) { 8962 next_event = ISC_LIST_NEXT(event, ev_link); 8963 RUNTIME_CHECK(event->fetch != fetch); 8964 } 8965 } 8966 8967 bucket_empty = fctx_decreference(fctx); 8968 8969 UNLOCK(&res->buckets[bucketnum].lock); 8970 8971 isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch)); 8972 *fetchp = NULL; 8973 8974 if (bucket_empty) 8975 empty_bucket(res); 8976 } 8977 8978 void 8979 dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx, 8980 isc_logcategory_t *category, isc_logmodule_t *module, 8981 int level, isc_boolean_t duplicateok) 8982 { 8983 fetchctx_t *fctx; 8984 dns_resolver_t *res; 8985 char domainbuf[DNS_NAME_FORMATSIZE]; 8986 8987 REQUIRE(DNS_FETCH_VALID(fetch)); 8988 fctx = fetch->private; 8989 REQUIRE(VALID_FCTX(fctx)); 8990 res = fctx->res; 8991 8992 LOCK(&res->buckets[fctx->bucketnum].lock); 8993 8994 INSIST(fctx->exitline >= 0); 8995 if (!fctx->logged || duplicateok) { 8996 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); 8997 isc_log_write(lctx, category, module, level, 8998 "fetch completed at %s:%d for %s in " 8999 "%" ISC_PRINT_QUADFORMAT "u." 9000 "%06" ISC_PRINT_QUADFORMAT "u: %s/%s " 9001 "[domain:%s,referral:%u,restart:%u,qrysent:%u," 9002 "timeout:%u,lame:%u,neterr:%u,badresp:%u," 9003 "adberr:%u,findfail:%u,valfail:%u]", 9004 __FILE__, fctx->exitline, fctx->info, 9005 fctx->duration / US_PER_SEC, 9006 fctx->duration % US_PER_SEC, 9007 isc_result_totext(fctx->result), 9008 isc_result_totext(fctx->vresult), domainbuf, 9009 fctx->referrals, fctx->restarts, 9010 fctx->querysent, fctx->timeouts, fctx->lamecount, 9011 fctx->neterr, fctx->badresp, fctx->adberr, 9012 fctx->findfail, fctx->valfail); 9013 fctx->logged = ISC_TRUE; 9014 } 9015 9016 UNLOCK(&res->buckets[fctx->bucketnum].lock); 9017 } 9018 9019 dns_dispatchmgr_t * 9020 dns_resolver_dispatchmgr(dns_resolver_t *resolver) { 9021 REQUIRE(VALID_RESOLVER(resolver)); 9022 return (resolver->dispatchmgr); 9023 } 9024 9025 dns_dispatch_t * 9026 dns_resolver_dispatchv4(dns_resolver_t *resolver) { 9027 REQUIRE(VALID_RESOLVER(resolver)); 9028 return (dns_dispatchset_get(resolver->dispatches4)); 9029 } 9030 9031 dns_dispatch_t * 9032 dns_resolver_dispatchv6(dns_resolver_t *resolver) { 9033 REQUIRE(VALID_RESOLVER(resolver)); 9034 return (dns_dispatchset_get(resolver->dispatches6)); 9035 } 9036 9037 isc_socketmgr_t * 9038 dns_resolver_socketmgr(dns_resolver_t *resolver) { 9039 REQUIRE(VALID_RESOLVER(resolver)); 9040 return (resolver->socketmgr); 9041 } 9042 9043 isc_taskmgr_t * 9044 dns_resolver_taskmgr(dns_resolver_t *resolver) { 9045 REQUIRE(VALID_RESOLVER(resolver)); 9046 return (resolver->taskmgr); 9047 } 9048 9049 isc_uint32_t 9050 dns_resolver_getlamettl(dns_resolver_t *resolver) { 9051 REQUIRE(VALID_RESOLVER(resolver)); 9052 return (resolver->lame_ttl); 9053 } 9054 9055 void 9056 dns_resolver_setlamettl(dns_resolver_t *resolver, isc_uint32_t lame_ttl) { 9057 REQUIRE(VALID_RESOLVER(resolver)); 9058 resolver->lame_ttl = lame_ttl; 9059 } 9060 9061 unsigned int 9062 dns_resolver_nrunning(dns_resolver_t *resolver) { 9063 unsigned int n; 9064 LOCK(&resolver->nlock); 9065 n = resolver->nfctx; 9066 UNLOCK(&resolver->nlock); 9067 return (n); 9068 } 9069 9070 isc_result_t 9071 dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt, 9072 dns_name_t *name, in_port_t port) { 9073 alternate_t *a; 9074 isc_result_t result; 9075 9076 REQUIRE(VALID_RESOLVER(resolver)); 9077 REQUIRE(!resolver->frozen); 9078 REQUIRE((alt == NULL) ^ (name == NULL)); 9079 9080 a = isc_mem_get(resolver->mctx, sizeof(*a)); 9081 if (a == NULL) 9082 return (ISC_R_NOMEMORY); 9083 if (alt != NULL) { 9084 a->isaddress = ISC_TRUE; 9085 a->_u.addr = *alt; 9086 } else { 9087 a->isaddress = ISC_FALSE; 9088 a->_u._n.port = port; 9089 dns_name_init(&a->_u._n.name, NULL); 9090 result = dns_name_dup(name, resolver->mctx, &a->_u._n.name); 9091 if (result != ISC_R_SUCCESS) { 9092 isc_mem_put(resolver->mctx, a, sizeof(*a)); 9093 return (result); 9094 } 9095 } 9096 ISC_LINK_INIT(a, link); 9097 ISC_LIST_APPEND(resolver->alternates, a, link); 9098 9099 return (ISC_R_SUCCESS); 9100 } 9101 9102 void 9103 dns_resolver_setudpsize(dns_resolver_t *resolver, isc_uint16_t udpsize) { 9104 REQUIRE(VALID_RESOLVER(resolver)); 9105 resolver->udpsize = udpsize; 9106 } 9107 9108 isc_uint16_t 9109 dns_resolver_getudpsize(dns_resolver_t *resolver) { 9110 REQUIRE(VALID_RESOLVER(resolver)); 9111 return (resolver->udpsize); 9112 } 9113 9114 void 9115 dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) { 9116 unsigned int i; 9117 dns_badcache_t *bad, *prev, *next; 9118 9119 REQUIRE(VALID_RESOLVER(resolver)); 9120 9121 LOCK(&resolver->lock); 9122 if (resolver->badcache == NULL) 9123 goto unlock; 9124 9125 if (name != NULL) { 9126 isc_time_t now; 9127 isc_result_t result; 9128 result = isc_time_now(&now); 9129 if (result != ISC_R_SUCCESS) 9130 isc_time_settoepoch(&now); 9131 i = dns_name_hash(name, ISC_FALSE) % resolver->badhash; 9132 prev = NULL; 9133 for (bad = resolver->badcache[i]; bad != NULL; bad = next) { 9134 int n; 9135 next = bad->next; 9136 n = isc_time_compare(&bad->expire, &now); 9137 if (n < 0 || dns_name_equal(name, &bad->name)) { 9138 if (prev == NULL) 9139 resolver->badcache[i] = bad->next; 9140 else 9141 prev->next = bad->next; 9142 isc_mem_put(resolver->mctx, bad, sizeof(*bad) + 9143 bad->name.length); 9144 resolver->badcount--; 9145 } else 9146 prev = bad; 9147 } 9148 } else 9149 destroy_badcache(resolver); 9150 9151 unlock: 9152 UNLOCK(&resolver->lock); 9153 } 9154 9155 void 9156 dns_resolver_flushbadnames(dns_resolver_t *resolver, dns_name_t *name) { 9157 dns_badcache_t *bad, *prev, *next; 9158 unsigned int i; 9159 int n; 9160 isc_time_t now; 9161 isc_result_t result; 9162 9163 REQUIRE(VALID_RESOLVER(resolver)); 9164 REQUIRE(name != NULL); 9165 9166 LOCK(&resolver->lock); 9167 if (resolver->badcache == NULL) 9168 goto unlock; 9169 9170 result = isc_time_now(&now); 9171 if (result != ISC_R_SUCCESS) 9172 isc_time_settoepoch(&now); 9173 9174 for (i = 0; i < resolver->badhash; i++) { 9175 prev = NULL; 9176 for (bad = resolver->badcache[i]; bad != NULL; bad = next) { 9177 next = bad->next; 9178 n = isc_time_compare(&bad->expire, &now); 9179 if (n < 0 || dns_name_issubdomain(&bad->name, name)) { 9180 if (prev == NULL) 9181 resolver->badcache[i] = bad->next; 9182 else 9183 prev->next = bad->next; 9184 isc_mem_put(resolver->mctx, bad, sizeof(*bad) + 9185 bad->name.length); 9186 resolver->badcount--; 9187 } else 9188 prev = bad; 9189 } 9190 } 9191 9192 unlock: 9193 UNLOCK(&resolver->lock); 9194 } 9195 9196 static void 9197 resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) { 9198 unsigned int newsize; 9199 dns_badcache_t **new, *bad, *next; 9200 unsigned int i; 9201 9202 if (grow) 9203 newsize = resolver->badhash * 2 + 1; 9204 else 9205 newsize = (resolver->badhash - 1) / 2; 9206 9207 new = isc_mem_get(resolver->mctx, 9208 sizeof(*resolver->badcache) * newsize); 9209 if (new == NULL) 9210 return; 9211 memset(new, 0, sizeof(*resolver->badcache) * newsize); 9212 for (i = 0; i < resolver->badhash; i++) { 9213 for (bad = resolver->badcache[i]; bad != NULL; bad = next) { 9214 next = bad->next; 9215 if (isc_time_compare(&bad->expire, now) < 0) { 9216 isc_mem_put(resolver->mctx, bad, sizeof(*bad) + 9217 bad->name.length); 9218 resolver->badcount--; 9219 } else { 9220 bad->next = new[bad->hashval % newsize]; 9221 new[bad->hashval % newsize] = bad; 9222 } 9223 } 9224 } 9225 isc_mem_put(resolver->mctx, resolver->badcache, 9226 sizeof(*resolver->badcache) * resolver->badhash); 9227 resolver->badhash = newsize; 9228 resolver->badcache = new; 9229 } 9230 9231 void 9232 dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, 9233 dns_rdatatype_t type, isc_time_t *expire) 9234 { 9235 isc_time_t now; 9236 isc_result_t result = ISC_R_SUCCESS; 9237 unsigned int i, hashval; 9238 dns_badcache_t *bad, *prev, *next; 9239 9240 REQUIRE(VALID_RESOLVER(resolver)); 9241 9242 LOCK(&resolver->lock); 9243 if (resolver->badcache == NULL) { 9244 resolver->badcache = isc_mem_get(resolver->mctx, 9245 sizeof(*resolver->badcache) * 9246 DNS_BADCACHE_SIZE); 9247 if (resolver->badcache == NULL) 9248 goto cleanup; 9249 resolver->badhash = DNS_BADCACHE_SIZE; 9250 memset(resolver->badcache, 0, sizeof(*resolver->badcache) * 9251 resolver->badhash); 9252 } 9253 9254 result = isc_time_now(&now); 9255 if (result != ISC_R_SUCCESS) 9256 isc_time_settoepoch(&now); 9257 hashval = dns_name_hash(name, ISC_FALSE); 9258 i = hashval % resolver->badhash; 9259 prev = NULL; 9260 for (bad = resolver->badcache[i]; bad != NULL; bad = next) { 9261 next = bad->next; 9262 if (bad->type == type && dns_name_equal(name, &bad->name)) 9263 break; 9264 if (isc_time_compare(&bad->expire, &now) < 0) { 9265 if (prev == NULL) 9266 resolver->badcache[i] = bad->next; 9267 else 9268 prev->next = bad->next; 9269 isc_mem_put(resolver->mctx, bad, sizeof(*bad) + 9270 bad->name.length); 9271 resolver->badcount--; 9272 } else 9273 prev = bad; 9274 } 9275 if (bad == NULL) { 9276 isc_buffer_t buffer; 9277 bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length); 9278 if (bad == NULL) 9279 goto cleanup; 9280 bad->type = type; 9281 bad->hashval = hashval; 9282 bad->expire = *expire; 9283 isc_buffer_init(&buffer, bad + 1, name->length); 9284 dns_name_init(&bad->name, NULL); 9285 dns_name_copy(name, &bad->name, &buffer); 9286 bad->next = resolver->badcache[i]; 9287 resolver->badcache[i] = bad; 9288 resolver->badcount++; 9289 if (resolver->badcount > resolver->badhash * 8) 9290 resizehash(resolver, &now, ISC_TRUE); 9291 if (resolver->badcount < resolver->badhash * 2 && 9292 resolver->badhash > DNS_BADCACHE_SIZE) 9293 resizehash(resolver, &now, ISC_FALSE); 9294 } else 9295 bad->expire = *expire; 9296 cleanup: 9297 UNLOCK(&resolver->lock); 9298 } 9299 9300 isc_boolean_t 9301 dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, 9302 dns_rdatatype_t type, isc_time_t *now) 9303 { 9304 dns_badcache_t *bad, *prev, *next; 9305 isc_boolean_t answer = ISC_FALSE; 9306 unsigned int i; 9307 9308 REQUIRE(VALID_RESOLVER(resolver)); 9309 9310 LOCK(&resolver->lock); 9311 if (resolver->badcache == NULL) 9312 goto unlock; 9313 9314 i = dns_name_hash(name, ISC_FALSE) % resolver->badhash; 9315 prev = NULL; 9316 for (bad = resolver->badcache[i]; bad != NULL; bad = next) { 9317 next = bad->next; 9318 /* 9319 * Search the hash list. Clean out expired records as we go. 9320 */ 9321 if (isc_time_compare(&bad->expire, now) < 0) { 9322 if (prev != NULL) 9323 prev->next = bad->next; 9324 else 9325 resolver->badcache[i] = bad->next; 9326 isc_mem_put(resolver->mctx, bad, sizeof(*bad) + 9327 bad->name.length); 9328 resolver->badcount--; 9329 continue; 9330 } 9331 if (bad->type == type && dns_name_equal(name, &bad->name)) { 9332 answer = ISC_TRUE; 9333 break; 9334 } 9335 prev = bad; 9336 } 9337 9338 /* 9339 * Slow sweep to clean out stale records. 9340 */ 9341 i = resolver->badsweep++ % resolver->badhash; 9342 bad = resolver->badcache[i]; 9343 if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) { 9344 resolver->badcache[i] = bad->next; 9345 isc_mem_put(resolver->mctx, bad, sizeof(*bad) + 9346 bad->name.length); 9347 resolver->badcount--; 9348 } 9349 9350 unlock: 9351 UNLOCK(&resolver->lock); 9352 return (answer); 9353 } 9354 9355 void 9356 dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) { 9357 char namebuf[DNS_NAME_FORMATSIZE]; 9358 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 9359 dns_badcache_t *bad, *next, *prev; 9360 isc_time_t now; 9361 unsigned int i; 9362 isc_uint64_t t; 9363 9364 LOCK(&resolver->lock); 9365 fprintf(fp, ";\n; Bad cache\n;\n"); 9366 9367 if (resolver->badcache == NULL) 9368 goto unlock; 9369 9370 TIME_NOW(&now); 9371 for (i = 0; i < resolver->badhash; i++) { 9372 prev = NULL; 9373 for (bad = resolver->badcache[i]; bad != NULL; bad = next) { 9374 next = bad->next; 9375 if (isc_time_compare(&bad->expire, &now) < 0) { 9376 if (prev != NULL) 9377 prev->next = bad->next; 9378 else 9379 resolver->badcache[i] = bad->next; 9380 isc_mem_put(resolver->mctx, bad, sizeof(*bad) + 9381 bad->name.length); 9382 resolver->badcount--; 9383 continue; 9384 } 9385 prev = bad; 9386 dns_name_format(&bad->name, namebuf, sizeof(namebuf)); 9387 dns_rdatatype_format(bad->type, typebuf, 9388 sizeof(typebuf)); 9389 t = isc_time_microdiff(&bad->expire, &now); 9390 t /= 1000; 9391 fprintf(fp, "; %s/%s [ttl " 9392 "%" ISC_PLATFORM_QUADFORMAT "u]\n", 9393 namebuf, typebuf, t); 9394 } 9395 } 9396 9397 unlock: 9398 UNLOCK(&resolver->lock); 9399 } 9400 9401 static void 9402 free_algorithm(void *node, void *arg) { 9403 unsigned char *algorithms = node; 9404 isc_mem_t *mctx = arg; 9405 9406 isc_mem_put(mctx, algorithms, *algorithms); 9407 } 9408 9409 void 9410 dns_resolver_reset_algorithms(dns_resolver_t *resolver) { 9411 9412 REQUIRE(VALID_RESOLVER(resolver)); 9413 9414 #if USE_ALGLOCK 9415 RWLOCK(&resolver->alglock, isc_rwlocktype_write); 9416 #endif 9417 if (resolver->algorithms != NULL) 9418 dns_rbt_destroy(&resolver->algorithms); 9419 #if USE_ALGLOCK 9420 RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); 9421 #endif 9422 } 9423 9424 isc_result_t 9425 dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name, 9426 unsigned int alg) 9427 { 9428 unsigned int len, mask; 9429 unsigned char *new; 9430 unsigned char *algorithms; 9431 isc_result_t result; 9432 dns_rbtnode_t *node = NULL; 9433 9434 REQUIRE(VALID_RESOLVER(resolver)); 9435 if (alg > 255) 9436 return (ISC_R_RANGE); 9437 9438 #if USE_ALGLOCK 9439 RWLOCK(&resolver->alglock, isc_rwlocktype_write); 9440 #endif 9441 if (resolver->algorithms == NULL) { 9442 result = dns_rbt_create(resolver->mctx, free_algorithm, 9443 resolver->mctx, &resolver->algorithms); 9444 if (result != ISC_R_SUCCESS) 9445 goto cleanup; 9446 } 9447 9448 len = alg/8 + 2; 9449 mask = 1 << (alg%8); 9450 9451 result = dns_rbt_addnode(resolver->algorithms, name, &node); 9452 9453 if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) { 9454 algorithms = node->data; 9455 if (algorithms == NULL || len > *algorithms) { 9456 new = isc_mem_get(resolver->mctx, len); 9457 if (new == NULL) { 9458 result = ISC_R_NOMEMORY; 9459 goto cleanup; 9460 } 9461 memset(new, 0, len); 9462 if (algorithms != NULL) 9463 memmove(new, algorithms, *algorithms); 9464 new[len-1] |= mask; 9465 *new = len; 9466 node->data = new; 9467 if (algorithms != NULL) 9468 isc_mem_put(resolver->mctx, algorithms, 9469 *algorithms); 9470 } else 9471 algorithms[len-1] |= mask; 9472 } 9473 result = ISC_R_SUCCESS; 9474 cleanup: 9475 #if USE_ALGLOCK 9476 RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); 9477 #endif 9478 return (result); 9479 } 9480 9481 isc_boolean_t 9482 dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name, 9483 unsigned int alg) 9484 { 9485 unsigned int len, mask; 9486 unsigned char *algorithms; 9487 void *data = NULL; 9488 isc_result_t result; 9489 isc_boolean_t found = ISC_FALSE; 9490 9491 REQUIRE(VALID_RESOLVER(resolver)); 9492 9493 /* 9494 * DH is unsupported for DNSKEYs, see RFC 4034 sec. A.1. 9495 */ 9496 if ((alg == DST_ALG_DH) || (alg == DST_ALG_INDIRECT)) 9497 return (ISC_FALSE); 9498 9499 #if USE_ALGLOCK 9500 RWLOCK(&resolver->alglock, isc_rwlocktype_read); 9501 #endif 9502 if (resolver->algorithms == NULL) 9503 goto unlock; 9504 result = dns_rbt_findname(resolver->algorithms, name, 0, NULL, &data); 9505 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 9506 len = alg/8 + 2; 9507 mask = 1 << (alg%8); 9508 algorithms = data; 9509 if (len <= *algorithms && (algorithms[len-1] & mask) != 0) 9510 found = ISC_TRUE; 9511 } 9512 unlock: 9513 #if USE_ALGLOCK 9514 RWUNLOCK(&resolver->alglock, isc_rwlocktype_read); 9515 #endif 9516 if (found) 9517 return (ISC_FALSE); 9518 9519 return (dst_algorithm_supported(alg)); 9520 } 9521 9522 static void 9523 free_digest(void *node, void *arg) { 9524 unsigned char *digests = node; 9525 isc_mem_t *mctx = arg; 9526 9527 isc_mem_put(mctx, digests, *digests); 9528 } 9529 9530 void 9531 dns_resolver_reset_ds_digests(dns_resolver_t *resolver) { 9532 9533 REQUIRE(VALID_RESOLVER(resolver)); 9534 9535 #if USE_ALGLOCK 9536 RWLOCK(&resolver->alglock, isc_rwlocktype_write); 9537 #endif 9538 if (resolver->digests != NULL) 9539 dns_rbt_destroy(&resolver->digests); 9540 #if USE_ALGLOCK 9541 RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); 9542 #endif 9543 } 9544 9545 isc_result_t 9546 dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name, 9547 unsigned int digest_type) 9548 { 9549 unsigned int len, mask; 9550 unsigned char *new; 9551 unsigned char *digests; 9552 isc_result_t result; 9553 dns_rbtnode_t *node = NULL; 9554 9555 REQUIRE(VALID_RESOLVER(resolver)); 9556 if (digest_type > 255) 9557 return (ISC_R_RANGE); 9558 9559 #if USE_ALGLOCK 9560 RWLOCK(&resolver->alglock, isc_rwlocktype_write); 9561 #endif 9562 if (resolver->digests == NULL) { 9563 result = dns_rbt_create(resolver->mctx, free_digest, 9564 resolver->mctx, &resolver->digests); 9565 if (result != ISC_R_SUCCESS) 9566 goto cleanup; 9567 } 9568 9569 len = digest_type/8 + 2; 9570 mask = 1 << (digest_type%8); 9571 9572 result = dns_rbt_addnode(resolver->digests, name, &node); 9573 9574 if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) { 9575 digests = node->data; 9576 if (digests == NULL || len > *digests) { 9577 new = isc_mem_get(resolver->mctx, len); 9578 if (new == NULL) { 9579 result = ISC_R_NOMEMORY; 9580 goto cleanup; 9581 } 9582 memset(new, 0, len); 9583 if (digests != NULL) 9584 memmove(new, digests, *digests); 9585 new[len-1] |= mask; 9586 *new = len; 9587 node->data = new; 9588 if (digests != NULL) 9589 isc_mem_put(resolver->mctx, digests, 9590 *digests); 9591 } else 9592 digests[len-1] |= mask; 9593 } 9594 result = ISC_R_SUCCESS; 9595 cleanup: 9596 #if USE_ALGLOCK 9597 RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); 9598 #endif 9599 return (result); 9600 } 9601 9602 isc_boolean_t 9603 dns_resolver_ds_digest_supported(dns_resolver_t *resolver, dns_name_t *name, 9604 unsigned int digest_type) 9605 { 9606 unsigned int len, mask; 9607 unsigned char *digests; 9608 void *data = NULL; 9609 isc_result_t result; 9610 isc_boolean_t found = ISC_FALSE; 9611 9612 REQUIRE(VALID_RESOLVER(resolver)); 9613 9614 #if USE_ALGLOCK 9615 RWLOCK(&resolver->alglock, isc_rwlocktype_read); 9616 #endif 9617 if (resolver->digests == NULL) 9618 goto unlock; 9619 result = dns_rbt_findname(resolver->digests, name, 0, NULL, &data); 9620 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 9621 len = digest_type/8 + 2; 9622 mask = 1 << (digest_type%8); 9623 digests = data; 9624 if (len <= *digests && (digests[len-1] & mask) != 0) 9625 found = ISC_TRUE; 9626 } 9627 unlock: 9628 #if USE_ALGLOCK 9629 RWUNLOCK(&resolver->alglock, isc_rwlocktype_read); 9630 #endif 9631 if (found) 9632 return (ISC_FALSE); 9633 return (dst_ds_digest_supported(digest_type)); 9634 } 9635 9636 void 9637 dns_resolver_resetmustbesecure(dns_resolver_t *resolver) { 9638 9639 REQUIRE(VALID_RESOLVER(resolver)); 9640 9641 #if USE_MBSLOCK 9642 RWLOCK(&resolver->mbslock, isc_rwlocktype_write); 9643 #endif 9644 if (resolver->mustbesecure != NULL) 9645 dns_rbt_destroy(&resolver->mustbesecure); 9646 #if USE_MBSLOCK 9647 RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write); 9648 #endif 9649 } 9650 9651 static isc_boolean_t yes = ISC_TRUE, no = ISC_FALSE; 9652 9653 isc_result_t 9654 dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name, 9655 isc_boolean_t value) 9656 { 9657 isc_result_t result; 9658 9659 REQUIRE(VALID_RESOLVER(resolver)); 9660 9661 #if USE_MBSLOCK 9662 RWLOCK(&resolver->mbslock, isc_rwlocktype_write); 9663 #endif 9664 if (resolver->mustbesecure == NULL) { 9665 result = dns_rbt_create(resolver->mctx, NULL, NULL, 9666 &resolver->mustbesecure); 9667 if (result != ISC_R_SUCCESS) 9668 goto cleanup; 9669 } 9670 result = dns_rbt_addname(resolver->mustbesecure, name, 9671 value ? &yes : &no); 9672 cleanup: 9673 #if USE_MBSLOCK 9674 RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write); 9675 #endif 9676 return (result); 9677 } 9678 9679 isc_boolean_t 9680 dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name) { 9681 void *data = NULL; 9682 isc_boolean_t value = ISC_FALSE; 9683 isc_result_t result; 9684 9685 REQUIRE(VALID_RESOLVER(resolver)); 9686 9687 #if USE_MBSLOCK 9688 RWLOCK(&resolver->mbslock, isc_rwlocktype_read); 9689 #endif 9690 if (resolver->mustbesecure == NULL) 9691 goto unlock; 9692 result = dns_rbt_findname(resolver->mustbesecure, name, 0, NULL, &data); 9693 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 9694 value = *(isc_boolean_t*)data; 9695 unlock: 9696 #if USE_MBSLOCK 9697 RWUNLOCK(&resolver->mbslock, isc_rwlocktype_read); 9698 #endif 9699 return (value); 9700 } 9701 9702 void 9703 dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur, 9704 isc_uint32_t *min, isc_uint32_t *max) 9705 { 9706 REQUIRE(VALID_RESOLVER(resolver)); 9707 9708 LOCK(&resolver->lock); 9709 if (cur != NULL) 9710 *cur = resolver->spillat; 9711 if (min != NULL) 9712 *min = resolver->spillatmin; 9713 if (max != NULL) 9714 *max = resolver->spillatmax; 9715 UNLOCK(&resolver->lock); 9716 } 9717 9718 void 9719 dns_resolver_setclientsperquery(dns_resolver_t *resolver, isc_uint32_t min, 9720 isc_uint32_t max) 9721 { 9722 REQUIRE(VALID_RESOLVER(resolver)); 9723 9724 LOCK(&resolver->lock); 9725 resolver->spillatmin = resolver->spillat = min; 9726 resolver->spillatmax = max; 9727 UNLOCK(&resolver->lock); 9728 } 9729 9730 isc_boolean_t 9731 dns_resolver_getzeronosoattl(dns_resolver_t *resolver) { 9732 REQUIRE(VALID_RESOLVER(resolver)); 9733 9734 return (resolver->zero_no_soa_ttl); 9735 } 9736 9737 void 9738 dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state) { 9739 REQUIRE(VALID_RESOLVER(resolver)); 9740 9741 resolver->zero_no_soa_ttl = state; 9742 } 9743 9744 unsigned int 9745 dns_resolver_getoptions(dns_resolver_t *resolver) { 9746 REQUIRE(VALID_RESOLVER(resolver)); 9747 9748 return (resolver->options); 9749 } 9750 9751 unsigned int 9752 dns_resolver_gettimeout(dns_resolver_t *resolver) { 9753 REQUIRE(VALID_RESOLVER(resolver)); 9754 9755 return (resolver->query_timeout); 9756 } 9757 9758 void 9759 dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds) { 9760 REQUIRE(VALID_RESOLVER(resolver)); 9761 9762 if (seconds == 0) 9763 seconds = DEFAULT_QUERY_TIMEOUT; 9764 if (seconds > MAXIMUM_QUERY_TIMEOUT) 9765 seconds = MAXIMUM_QUERY_TIMEOUT; 9766 if (seconds < MINIMUM_QUERY_TIMEOUT) 9767 seconds = MINIMUM_QUERY_TIMEOUT; 9768 9769 resolver->query_timeout = seconds; 9770 } 9771 9772 void 9773 dns_resolver_setquerydscp4(dns_resolver_t *resolver, isc_dscp_t dscp) { 9774 REQUIRE(VALID_RESOLVER(resolver)); 9775 9776 resolver->querydscp4 = dscp; 9777 } 9778 9779 isc_dscp_t 9780 dns_resolver_getquerydscp4(dns_resolver_t *resolver) { 9781 REQUIRE(VALID_RESOLVER(resolver)); 9782 return (resolver->querydscp4); 9783 } 9784 9785 void 9786 dns_resolver_setquerydscp6(dns_resolver_t *resolver, isc_dscp_t dscp) { 9787 REQUIRE(VALID_RESOLVER(resolver)); 9788 9789 resolver->querydscp6 = dscp; 9790 } 9791 9792 isc_dscp_t 9793 dns_resolver_getquerydscp6(dns_resolver_t *resolver) { 9794 REQUIRE(VALID_RESOLVER(resolver)); 9795 return (resolver->querydscp6); 9796 } 9797 9798 void 9799 dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth) { 9800 REQUIRE(VALID_RESOLVER(resolver)); 9801 resolver->maxdepth = maxdepth; 9802 } 9803 9804 unsigned int 9805 dns_resolver_getmaxdepth(dns_resolver_t *resolver) { 9806 REQUIRE(VALID_RESOLVER(resolver)); 9807 return (resolver->maxdepth); 9808 } 9809 9810 void 9811 dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) { 9812 REQUIRE(VALID_RESOLVER(resolver)); 9813 resolver->maxqueries = queries; 9814 } 9815 9816 unsigned int 9817 dns_resolver_getmaxqueries(dns_resolver_t *resolver) { 9818 REQUIRE(VALID_RESOLVER(resolver)); 9819 return (resolver->maxqueries); 9820 } 9821 9822