| 524 | } |
| 525 | |
| 526 | HostDBRecord::Handle |
| 527 | probe(HostDBHash const &hash, bool ignore_timeout) |
| 528 | { |
| 529 | static const Ptr<HostDBRecord> NO_RECORD; |
| 530 | |
| 531 | // If hostdb is disabled, don't return anything |
| 532 | if (!hostdb_enable) { |
| 533 | return NO_RECORD; |
| 534 | } |
| 535 | |
| 536 | // Otherwise HostDB is enabled, so we'll do our thing |
| 537 | uint64_t folded_hash = hash.hash.fold(); |
| 538 | ts::shared_mutex &bucket_lock = hostDB.refcountcache->lock_for_key(folded_hash); |
| 539 | |
| 540 | Ptr<HostDBRecord> record; |
| 541 | { |
| 542 | std::shared_lock<ts::shared_mutex> lock{bucket_lock}; |
| 543 | |
| 544 | // get the record from cache |
| 545 | record = hostDB.refcountcache->get(folded_hash); |
| 546 | // If there was nothing in the cache-- this is a miss |
| 547 | if (record.get() == nullptr) { |
| 548 | record = probe_ip(hash); |
| 549 | if (!record) { |
| 550 | record = probe_hostfile(hash); |
| 551 | } |
| 552 | return record; |
| 553 | } |
| 554 | |
| 555 | // If the dns response was failed, and we've hit the failed timeout, lets stop returning it |
| 556 | if (record->is_failed() && record->is_ip_fail_timeout()) { |
| 557 | return NO_RECORD; |
| 558 | // if we aren't ignoring timeouts, and we are past it-- then remove the record |
| 559 | } else if (!ignore_timeout && record->is_ip_timeout() && !record->serve_stale_but_revalidate()) { |
| 560 | Metrics::Counter::increment(hostdb_rsb.ttl_expires); |
| 561 | return NO_RECORD; |
| 562 | } |
| 563 | } |
| 564 | |
| 565 | // If the record is stale, but we want to revalidate-- lets start that up |
| 566 | if ((!ignore_timeout && record->is_ip_configured_stale() && record->record_type != HostDBType::HOST) || |
| 567 | (record->is_ip_timeout() && record->serve_stale_but_revalidate())) { |
| 568 | Metrics::Counter::increment(hostdb_rsb.total_serve_stale); |
| 569 | if (hostDB.is_pending_dns_for_hash(hash.hash)) { |
| 570 | Dbg(dbg_ctl_hostdb, "%s", |
| 571 | swoc::bwprint(ts::bw_dbg, "stale {} {} {}, using with pending refresh", record->ip_age(), |
| 572 | record->ip_timestamp.time_since_epoch(), record->ip_timeout_interval) |
| 573 | .c_str()); |
| 574 | return record; |
| 575 | } |
| 576 | Dbg(dbg_ctl_hostdb, "%s", |
| 577 | swoc::bwprint(ts::bw_dbg, "stale {} {} {}, using while refresh", record->ip_age(), record->ip_timestamp.time_since_epoch(), |
| 578 | record->ip_timeout_interval) |
| 579 | .c_str()); |
| 580 | HostDBContinuation *c = hostDBContAllocator.alloc(); |
| 581 | HostDBContinuation::Options copt; |
| 582 | copt.host_res_style = record->af_family == AF_INET6 ? HOST_RES_IPV6_ONLY : HOST_RES_IPV4_ONLY; |
| 583 | c->init(hash, copt); |
no test coverage detected