#include "net/dns/host_resolver_manager.h"
#include <cmath>
#include <cstdint>
#include <iterator>
#include <limits>
#include <memory>
#include <numeric>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <tuple>
#include <unordered_set>
#include <utility>
#include <vector>
#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/containers/circular_deque.h"
#include "base/containers/contains.h"
#include "base/containers/flat_set.h"
#include "base/containers/linked_list.h"
#include "base/debug/debugger.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/safe_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "base/numerics/safe_conversions.h"
#include "base/observer_list.h"
#include "base/ranges/algorithm.h"
#include "base/sequence_checker.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "base/types/optional_util.h"
#include "base/values.h"
#include "build/build_config.h"
#include "net/base/address_family.h"
#include "net/base/address_list.h"
#include "net/base/completion_once_callback.h"
#include "net/base/features.h"
#include "net/base/host_port_pair.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/network_change_notifier.h"
#include "net/base/network_interfaces.h"
#include "net/base/prioritized_dispatcher.h"
#include "net/base/request_priority.h"
#include "net/base/trace_constants.h"
#include "net/base/tracing.h"
#include "net/base/url_util.h"
#include "net/dns/dns_alias_utility.h"
#include "net/dns/dns_client.h"
#include "net/dns/dns_names_util.h"
#include "net/dns/dns_response.h"
#include "net/dns/dns_response_result_extractor.h"
#include "net/dns/dns_transaction.h"
#include "net/dns/dns_util.h"
#include "net/dns/host_cache.h"
#include "net/dns/host_resolver_dns_task.h"
#include "net/dns/host_resolver_internal_result.h"
#include "net/dns/host_resolver_manager_job.h"
#include "net/dns/host_resolver_manager_request_impl.h"
#include "net/dns/host_resolver_manager_service_endpoint_request_impl.h"
#include "net/dns/host_resolver_mdns_listener_impl.h"
#include "net/dns/host_resolver_mdns_task.h"
#include "net/dns/host_resolver_nat64_task.h"
#include "net/dns/host_resolver_proc.h"
#include "net/dns/host_resolver_system_task.h"
#include "net/dns/httpssvc_metrics.h"
#include "net/dns/loopback_only.h"
#include "net/dns/mdns_client.h"
#include "net/dns/public/dns_protocol.h"
#include "net/dns/public/dns_query_type.h"
#include "net/dns/public/host_resolver_results.h"
#include "net/dns/public/resolve_error_info.h"
#include "net/dns/public/secure_dns_mode.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/dns/public/util.h"
#include "net/dns/record_parsed.h"
#include "net/dns/resolve_context.h"
#include "net/dns/test_dns_config_service.h"
#include "net/http/http_network_session.h"
#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
#include "net/log/net_log_source_type.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_factory.h"
#include "net/url_request/url_request_context.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "url/scheme_host_port.h"
#include "url/url_constants.h"
#if BUILDFLAG(ENABLE_MDNS)
#include "net/dns/mdns_client_impl.h"
#endif
#if BUILDFLAG(IS_WIN)
#include <Winsock2.h>
#include "net/base/winsock_init.h"
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include <net/if.h>
#include "net/base/sys_addrinfo.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#else
#include <ifaddrs.h>
#endif
#endif
namespace net {
namespace {
const size_t kMaxHostLength = …;
const int kIPv6ProbePeriodMs = …;
const uint8_t kIPv6ProbeAddress[] = …;
bool ResemblesMulticastDNSName(std::string_view hostname) { … }
bool ConfigureAsyncDnsNoFallbackFieldTrial() { … }
base::Value::Dict NetLogIPv6AvailableParams(bool ipv6_available, bool cached) { … }
const size_t kDefaultMaxSystemTasks = …;
PrioritizedDispatcher::Limits GetDispatcherLimits(
const HostResolver::ManagerOptions& options) { … }
base::Value::Dict NetLogResults(const HostCache::Entry& results) { … }
std::vector<IPEndPoint> FilterAddresses(std::vector<IPEndPoint> addresses,
DnsQueryTypeSet query_types) { … }
int GetPortForGloballyReachableCheck() { … }
enum class DnsClientCapability { … };
void RecordDnsClientCapabilityMetrics(const DnsClient* dns_client) { … }
}
bool ResolveLocalHostname(std::string_view host,
std::vector<IPEndPoint>* address_list) { … }
class HostResolverManager::ProbeRequestImpl
: public HostResolver::ProbeRequest,
public ResolveContext::DohStatusObserver { … };
HostResolverManager::HostResolverManager(
const HostResolver::ManagerOptions& options,
SystemDnsConfigChangeNotifier* system_dns_config_notifier,
NetLog* net_log)
: … { … }
HostResolverManager::HostResolverManager(
base::PassKey<HostResolverManager>,
const HostResolver::ManagerOptions& options,
SystemDnsConfigChangeNotifier* system_dns_config_notifier,
handles::NetworkHandle target_network,
NetLog* net_log)
: … { … }
HostResolverManager::~HostResolverManager() { … }
std::unique_ptr<HostResolverManager>
HostResolverManager::CreateNetworkBoundHostResolverManager(
const HostResolver::ManagerOptions& options,
handles::NetworkHandle target_network,
NetLog* net_log) { … }
std::unique_ptr<HostResolver::ResolveHostRequest>
HostResolverManager::CreateRequest(
absl::variant<url::SchemeHostPort, HostPortPair> host,
NetworkAnonymizationKey network_anonymization_key,
NetLogWithSource net_log,
std::optional<ResolveHostParameters> optional_parameters,
ResolveContext* resolve_context) { … }
std::unique_ptr<HostResolver::ResolveHostRequest>
HostResolverManager::CreateRequest(
HostResolver::Host host,
NetworkAnonymizationKey network_anonymization_key,
NetLogWithSource net_log,
std::optional<ResolveHostParameters> optional_parameters,
ResolveContext* resolve_context) { … }
std::unique_ptr<HostResolver::ProbeRequest>
HostResolverManager::CreateDohProbeRequest(ResolveContext* context) { … }
std::unique_ptr<HostResolver::MdnsListener>
HostResolverManager::CreateMdnsListener(const HostPortPair& host,
DnsQueryType query_type) { … }
std::unique_ptr<HostResolver::ServiceEndpointRequest>
HostResolverManager::CreateServiceEndpointRequest(
url::SchemeHostPort scheme_host_port,
NetworkAnonymizationKey network_anonymization_key,
NetLogWithSource net_log,
ResolveHostParameters parameters,
ResolveContext* resolve_context) { … }
void HostResolverManager::SetInsecureDnsClientEnabled(
bool enabled,
bool additional_dns_types_enabled) { … }
base::Value::Dict HostResolverManager::GetDnsConfigAsValue() const { … }
void HostResolverManager::SetDnsConfigOverrides(DnsConfigOverrides overrides) { … }
void HostResolverManager::RegisterResolveContext(ResolveContext* context) { … }
void HostResolverManager::DeregisterResolveContext(
const ResolveContext* context) { … }
void HostResolverManager::SetTickClockForTesting(
const base::TickClock* tick_clock) { … }
void HostResolverManager::SetIPv6ReachabilityOverride(
bool reachability_override) { … }
void HostResolverManager::SetMaxQueuedJobsForTesting(size_t value) { … }
void HostResolverManager::SetHaveOnlyLoopbackAddresses(bool result) { … }
void HostResolverManager::SetMdnsSocketFactoryForTesting(
std::unique_ptr<MDnsSocketFactory> socket_factory) { … }
void HostResolverManager::SetMdnsClientForTesting(
std::unique_ptr<MDnsClient> client) { … }
void HostResolverManager::SetDnsClientForTesting(
std::unique_ptr<DnsClient> dns_client) { … }
void HostResolverManager::SetLastIPv6ProbeResultForTesting(
bool last_ipv6_probe_result) { … }
bool HostResolverManager::IsLocalTask(TaskType task) { … }
void HostResolverManager::InitializeJobKeyAndIPAddress(
const NetworkAnonymizationKey& network_anonymization_key,
const ResolveHostParameters& parameters,
const NetLogWithSource& source_net_log,
JobKey& out_job_key,
IPAddress& out_ip_address) { … }
HostCache::Entry HostResolverManager::ResolveLocally(
bool only_ipv6_reachable,
const JobKey& job_key,
const IPAddress& ip_address,
ResolveHostParameters::CacheUsage cache_usage,
SecureDnsPolicy secure_dns_policy,
HostResolverSource source,
const NetLogWithSource& source_net_log,
HostCache* cache,
std::deque<TaskType>* out_tasks,
std::optional<HostCache::EntryStaleness>* out_stale_info) { … }
void HostResolverManager::CreateAndStartJob(JobKey key,
std::deque<TaskType> tasks,
RequestImpl* request) { … }
HostResolverManager::Job* HostResolverManager::AddJobWithoutRequest(
JobKey key,
ResolveHostParameters::CacheUsage cache_usage,
HostCache* host_cache,
std::deque<TaskType> tasks,
RequestPriority priority,
const NetLogWithSource& source_net_log) { … }
void HostResolverManager::CreateAndStartJobForServiceEndpointRequest(
JobKey key,
std::deque<TaskType> tasks,
ServiceEndpointRequestImpl* request) { … }
HostCache::Entry HostResolverManager::ResolveAsIP(DnsQueryTypeSet query_types,
bool resolve_canonname,
const IPAddress& ip_address) { … }
std::optional<HostCache::Entry> HostResolverManager::MaybeServeFromCache(
HostCache* cache,
const HostCache::Key& key,
ResolveHostParameters::CacheUsage cache_usage,
bool ignore_secure,
const NetLogWithSource& source_net_log,
std::optional<HostCache::EntryStaleness>* out_stale_info) { … }
std::optional<HostCache::Entry> HostResolverManager::MaybeReadFromConfig(
const JobKey& key) { … }
void HostResolverManager::StartBootstrapFollowup(
JobKey key,
HostCache* host_cache,
const NetLogWithSource& source_net_log) { … }
std::optional<HostCache::Entry> HostResolverManager::ServeFromHosts(
std::string_view hostname,
DnsQueryTypeSet query_types,
bool default_family_due_to_no_ipv6,
const std::deque<TaskType>& tasks) { … }
std::optional<HostCache::Entry> HostResolverManager::ServeLocalhost(
std::string_view hostname,
DnsQueryTypeSet query_types,
bool default_family_due_to_no_ipv6) { … }
void HostResolverManager::CacheResult(HostCache* cache,
const HostCache::Key& key,
const HostCache::Entry& entry,
base::TimeDelta ttl) { … }
std::unique_ptr<HostResolverManager::Job> HostResolverManager::RemoveJob(
JobMap::iterator job_it) { … }
SecureDnsMode HostResolverManager::GetEffectiveSecureDnsMode(
SecureDnsPolicy secure_dns_policy) { … }
bool HostResolverManager::ShouldForceSystemResolverDueToTestOverride() const { … }
void HostResolverManager::PushDnsTasks(bool system_task_allowed,
SecureDnsMode secure_dns_mode,
bool insecure_tasks_allowed,
bool allow_cache,
bool prioritize_local_lookups,
ResolveContext* resolve_context,
std::deque<TaskType>* out_tasks) { … }
void HostResolverManager::CreateTaskSequence(
const JobKey& job_key,
ResolveHostParameters::CacheUsage cache_usage,
SecureDnsPolicy secure_dns_policy,
std::deque<TaskType>* out_tasks) { … }
namespace {
bool RequestWillUseWiFi(handles::NetworkHandle network) { … }
}
void HostResolverManager::FinishIPv6ReachabilityCheck(
CompletionOnceCallback callback,
int rv) { … }
int HostResolverManager::StartIPv6ReachabilityCheck(
const NetLogWithSource& net_log,
ClientSocketFactory* client_socket_factory,
CompletionOnceCallback callback) { … }
void HostResolverManager::SetLastIPv6ProbeResult(bool last_ipv6_probe_result) { … }
int HostResolverManager::StartGloballyReachableCheck(
const IPAddress& dest,
const NetLogWithSource& net_log,
ClientSocketFactory* client_socket_factory,
CompletionOnceCallback callback) { … }
bool HostResolverManager::FinishGloballyReachableCheck(
DatagramClientSocket* socket,
int rv) { … }
void HostResolverManager::RunFinishGloballyReachableCheck(
scoped_refptr<base::RefCountedData<std::unique_ptr<DatagramClientSocket>>>
socket,
CompletionOnceCallback callback,
int rv) { … }
void HostResolverManager::RunLoopbackProbeJob() { … }
void HostResolverManager::RemoveAllJobs(const ResolveContext* context) { … }
void HostResolverManager::AbortJobsWithoutTargetNetwork(bool in_progress_only) { … }
void HostResolverManager::AbortInsecureDnsTasks(int error, bool fallback_only) { … }
void HostResolverManager::TryServingAllJobsFromHosts() { … }
void HostResolverManager::OnIPAddressChanged() { … }
void HostResolverManager::OnConnectionTypeChanged(
NetworkChangeNotifier::ConnectionType type) { … }
void HostResolverManager::OnSystemDnsConfigChanged(
std::optional<DnsConfig> config) { … }
void HostResolverManager::UpdateJobsForChangedConfig() { … }
void HostResolverManager::OnFallbackResolve(int dns_task_error) { … }
int HostResolverManager::GetOrCreateMdnsClient(MDnsClient** out_client) { … }
void HostResolverManager::InvalidateCaches(bool network_change) { … }
void HostResolverManager::UpdateConnectionType(
NetworkChangeNotifier::ConnectionType type) { … }
std::unique_ptr<DnsProbeRunner> HostResolverManager::CreateDohProbeRunner(
ResolveContext* resolve_context) { … }
}