blob: 1abd9f966fa1ff7a9bdad564027f3b107a36646e [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_DNS_DNS_TASK_RESULTS_MANAGER_H_
#define NET_DNS_DNS_TASK_RESULTS_MANAGER_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
#include "net/dns/host_resolver.h"
#include "net/dns/host_resolver_dns_task.h"
#include "net/dns/public/dns_query_type.h"
#include "net/dns/public/host_resolver_results.h"
#include "net/log/net_log_with_source.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "url/scheme_host_port.h"
namespace net {
// Creates and updates intermediate service endpoints while resolving a host.
// This class is designed to have a 1:1 relationship with a HostResolverDnsTask
// and expects to be notified every time a DnsTransaction is completed. When
// notified, tries to create and update service endpoints from DNS responses
// received so far.
//
// If the A response comes before the AAAA response, delays service endpoints
// creation/update until an AAAA response is received or the AAAA query is
// timed out.
class NET_EXPORT_PRIVATE DnsTaskResultsManager {
public:
// Time to wait for a AAAA response after receiving an A response.
static constexpr base::TimeDelta kResolutionDelay = base::Milliseconds(50);
// Interface for watching for intermediate service endpoints updates.
class Delegate {
public:
virtual ~Delegate() = default;
// Called when service endpoints are updated.
virtual void OnServiceEndpointsUpdated() = 0;
};
// TODO(crbug.com/41493696): Update HostResolverManager::JobKey to use
// HostResolver::Host so that HostResolverManager::Job can create an instance
// of this class.
DnsTaskResultsManager(Delegate* delegate,
HostResolver::Host host,
DnsQueryTypeSet query_types,
const NetLogWithSource& net_log);
~DnsTaskResultsManager();
DnsTaskResultsManager(const DnsTaskResultsManager&) = delete;
DnsTaskResultsManager& operator=(const DnsTaskResultsManager&) = delete;
// Processes a query response represented by HostResolverInternalResults.
// Expected be called when a DnsTransaction is completed.
void ProcessDnsTransactionResults(
DnsQueryType query_type,
const std::set<std::unique_ptr<HostResolverInternalResult>>& results);
// Returns the current service endpoints. The results could change over time.
// Use the delegate's OnServiceEndpointsUpdated() to watch for updates.
const std::vector<ServiceEndpoint>& GetCurrentEndpoints() const;
// Returns all DNS record aliases, found as a result of A, AAAA, and HTTPS
// queries. The results could change over time.
const std::set<std::string>& GetAliases() const;
// True when a HTTP response is received. When true, call sites can start
// cryptographic handshakes since Chrome doesn't support HTTPS follow-up
// queries yet.
bool IsMetadataReady() const;
bool IsResolutionDelayTimerRunningForTest() {
return resolution_delay_timer_.IsRunning();
}
private:
struct PerDomainResult;
PerDomainResult& GetOrCreatePerDomainResult(const std::string& domain_name);
void OnAaaaResolutionTimedout();
void UpdateEndpoints();
// Checks all per domain results and return true when there is at least one
// valid address.
bool HasIpv4Addresses();
void RecordResolutionDelayResult(bool timedout);
const raw_ptr<Delegate> delegate_;
const HostResolver::Host host_;
const DnsQueryTypeSet query_types_;
const NetLogWithSource net_log_;
std::vector<ServiceEndpoint> current_endpoints_;
bool is_metadata_ready_ = false;
bool aaaa_response_received_ = false;
std::set<std::string> aliases_;
std::map</*domain_name=*/std::string, std::unique_ptr<PerDomainResult>>
per_domain_results_;
base::TimeTicks resolution_delay_start_time_;
base::OneShotTimer resolution_delay_timer_;
};
} // namespace net
#endif // NET_DNS_DNS_TASK_RESULTS_MANAGER_H_