#include "net/dns/host_cache.h"
#include <algorithm>
#include <iterator>
#include <map>
#include <memory>
#include <optional>
#include <ostream>
#include <set>
#include <string>
#include <string_view>
#include <type_traits>
#include <unordered_set>
#include <utility>
#include <vector>
#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/default_tick_clock.h"
#include "base/types/optional_util.h"
#include "base/value_iterators.h"
#include "net/base/address_family.h"
#include "net/base/ip_endpoint.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/trace_constants.h"
#include "net/base/tracing.h"
#include "net/dns/host_resolver.h"
#include "net/dns/host_resolver_internal_result.h"
#include "net/dns/https_record_rdata.h"
#include "net/dns/public/dns_protocol.h"
#include "net/dns/public/host_resolver_source.h"
#include "net/log/net_log.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "url/scheme_host_port.h"
namespace net {
namespace {
#define CACHE_HISTOGRAM_TIME(name, time) …
#define CACHE_HISTOGRAM_COUNT(name, count) …
#define CACHE_HISTOGRAM_ENUM(name, value, max) …
const char kSchemeKey[] = …;
const char kHostnameKey[] = …;
const char kPortKey[] = …;
const char kDnsQueryTypeKey[] = …;
const char kFlagsKey[] = …;
const char kHostResolverSourceKey[] = …;
const char kSecureKey[] = …;
const char kNetworkAnonymizationKey[] = …;
const char kExpirationKey[] = …;
const char kTtlKey[] = …;
const char kPinnedKey[] = …;
const char kNetworkChangesKey[] = …;
const char kNetErrorKey[] = …;
const char kIpEndpointsKey[] = …;
const char kEndpointAddressKey[] = …;
const char kEndpointPortKey[] = …;
const char kEndpointMetadatasKey[] = …;
const char kEndpointMetadataWeightKey[] = …;
const char kEndpointMetadataValueKey[] = …;
const char kAliasesKey[] = …;
const char kAddressesKey[] = …;
const char kTextRecordsKey[] = …;
const char kHostnameResultsKey[] = …;
const char kHostPortsKey[] = …;
const char kCanonicalNamesKey[] = …;
base::Value IpEndpointToValue(const IPEndPoint& endpoint) { … }
std::optional<IPEndPoint> IpEndpointFromValue(const base::Value& value) { … }
base::Value EndpointMetadataPairToValue(
const std::pair<HttpsRecordPriority, ConnectionEndpointMetadata>& pair) { … }
std::optional<std::pair<HttpsRecordPriority, ConnectionEndpointMetadata>>
EndpointMetadataPairFromValue(const base::Value& value) { … }
bool IPEndPointsFromLegacyAddressListValue(
const base::Value::List& value,
std::vector<IPEndPoint>& ip_endpoints) { … }
template <typename T>
void MergeLists(T& target, const T& source) { … }
template <typename T>
void MergeContainers(T& target, const T& source) { … }
bool IsValidHostname(std::string_view hostname) { … }
const std::string& GetHostname(
const absl::variant<url::SchemeHostPort, std::string>& host) { … }
std::optional<DnsQueryType> GetDnsQueryType(int dns_query_type) { … }
}
enum HostCache::SetOutcome : int { … };
enum HostCache::LookupOutcome : int { … };
enum HostCache::EraseReason : int { … };
HostCache::Key::Key(absl::variant<url::SchemeHostPort, std::string> host,
DnsQueryType dns_query_type,
HostResolverFlags host_resolver_flags,
HostResolverSource host_resolver_source,
const NetworkAnonymizationKey& network_anonymization_key)
: … { … }
HostCache::Key::Key() = default;
HostCache::Key::Key(const Key& key) = default;
HostCache::Key::Key(Key&& key) = default;
HostCache::Key::~Key() = default;
HostCache::Entry::Entry(int error,
Source source,
std::optional<base::TimeDelta> ttl)
: … { … }
HostCache::Entry::Entry(
const std::set<std::unique_ptr<HostResolverInternalResult>>& results,
base::Time now,
base::TimeTicks now_ticks,
Source empty_source) { … }
HostCache::Entry::Entry(const Entry& entry) = default;
HostCache::Entry::Entry(Entry&& entry) = default;
HostCache::Entry::~Entry() = default;
std::vector<HostResolverEndpointResult> HostCache::Entry::GetEndpoints() const { … }
std::vector<ConnectionEndpointMetadata> HostCache::Entry::GetMetadatas() const { … }
std::optional<base::TimeDelta> HostCache::Entry::GetOptionalTtl() const { … }
HostCache::Entry HostCache::Entry::MergeEntries(Entry front, Entry back) { … }
HostCache::Entry HostCache::Entry::CopyWithDefaultPort(uint16_t port) const { … }
HostCache::Entry& HostCache::Entry::operator=(const Entry& entry) = default;
HostCache::Entry& HostCache::Entry::operator=(Entry&& entry) = default;
HostCache::Entry::Entry(int error,
std::vector<IPEndPoint> ip_endpoints,
std::set<std::string> aliases,
Source source,
std::optional<base::TimeDelta> ttl)
: … { … }
HostCache::Entry::Entry(const HostCache::Entry& entry,
base::TimeTicks now,
base::TimeDelta ttl,
int network_changes)
: … { … }
HostCache::Entry::Entry(
int error,
std::vector<IPEndPoint> ip_endpoints,
std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
endpoint_metadatas,
std::set<std::string> aliases,
std::vector<std::string>&& text_records,
std::vector<HostPortPair>&& hostnames,
std::vector<bool>&& https_record_compatibility,
Source source,
base::TimeTicks expires,
int network_changes)
: … { … }
void HostCache::Entry::PrepareForCacheInsertion() { … }
bool HostCache::Entry::IsStale(base::TimeTicks now, int network_changes) const { … }
void HostCache::Entry::CountHit(bool hit_is_stale) { … }
void HostCache::Entry::GetStaleness(base::TimeTicks now,
int network_changes,
EntryStaleness* out) const { … }
base::Value HostCache::Entry::NetLogParams() const { … }
base::Value::Dict HostCache::Entry::GetAsValue(bool include_staleness) const { … }
std::optional<base::TimeDelta> HostCache::Entry::TtlFromInternalResults(
const std::set<std::unique_ptr<HostResolverInternalResult>>& results,
base::Time now,
base::TimeTicks now_ticks) { … }
const HostCache::EntryStaleness HostCache::kNotStale = …;
HostCache::HostCache(size_t max_entries)
: … { … }
HostCache::~HostCache() { … }
const std::pair<const HostCache::Key, HostCache::Entry>*
HostCache::Lookup(const Key& key, base::TimeTicks now, bool ignore_secure) { … }
const std::pair<const HostCache::Key, HostCache::Entry>* HostCache::LookupStale(
const Key& key,
base::TimeTicks now,
HostCache::EntryStaleness* stale_out,
bool ignore_secure) { … }
std::pair<const HostCache::Key, HostCache::Entry>*
HostCache::GetLessStaleMoreSecureResult(
base::TimeTicks now,
std::pair<const HostCache::Key, HostCache::Entry>* result1,
std::pair<const HostCache::Key, HostCache::Entry>* result2) { … }
std::pair<const HostCache::Key, HostCache::Entry>*
HostCache::LookupInternalIgnoringFields(const Key& initial_key,
base::TimeTicks now,
bool ignore_secure) { … }
std::pair<const HostCache::Key, HostCache::Entry>* HostCache::LookupInternal(
const Key& key) { … }
void HostCache::Set(const Key& key,
const Entry& entry,
base::TimeTicks now,
base::TimeDelta ttl) { … }
const HostCache::Key* HostCache::GetMatchingKeyForTesting(
std::string_view hostname,
HostCache::Entry::Source* source_out,
HostCache::EntryStaleness* stale_out) const { … }
void HostCache::AddEntry(const Key& key, Entry&& entry) { … }
void HostCache::Invalidate() { … }
void HostCache::set_persistence_delegate(PersistenceDelegate* delegate) { … }
void HostCache::clear() { … }
void HostCache::ClearForHosts(
const base::RepeatingCallback<bool(const std::string&)>& host_filter) { … }
void HostCache::GetList(base::Value::List& entry_list,
bool include_staleness,
SerializationType serialization_type) const { … }
bool HostCache::RestoreFromListValue(const base::Value::List& old_cache) { … }
size_t HostCache::size() const { … }
size_t HostCache::max_entries() const { … }
bool HostCache::EvictOneEntry(base::TimeTicks now) { … }
bool HostCache::HasActivePin(const Entry& entry) { … }
}
std::ostream& operator<<(std::ostream& out,
const net::HostCache::EntryStaleness& s) { … }