blob: 2d32399d1f65a813d0a33bc5d15d8e506352a9c5 [file] [log] [blame]
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/dns/context_host_resolver.h"
#include <string>
#include <utility>
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "base/time/tick_clock.h"
#include "net/dns/dns_config.h"
#include "net/dns/host_cache.h"
#include "net/dns/host_resolver_manager.h"
#include "net/dns/host_resolver_proc.h"
#include "net/url_request/url_request_context.h"
namespace net {
// Wrapper of ResolveHostRequests that on destruction will remove itself from
// |ContextHostResolver::active_requests_|.
class ContextHostResolver::WrappedRequest
: public HostResolver::ResolveHostRequest {
public:
WrappedRequest(
std::unique_ptr<HostResolverManager::CancellableRequest> inner_request,
ContextHostResolver* resolver)
: inner_request_(std::move(inner_request)), resolver_(resolver) {}
~WrappedRequest() override { Cancel(); }
void Cancel() {
// Cannot destroy |inner_request_| because it is still allowed to call
// Get...Results() methods if the request was already complete.
inner_request_->Cancel();
if (resolver_) {
resolver_->active_requests_.erase(this);
resolver_ = nullptr;
}
}
int Start(CompletionOnceCallback callback) override {
DCHECK(resolver_);
return inner_request_->Start(std::move(callback));
}
const base::Optional<AddressList>& GetAddressResults() const override {
return inner_request_->GetAddressResults();
}
const base::Optional<std::vector<std::string>>& GetTextResults()
const override {
return inner_request_->GetTextResults();
}
const base::Optional<std::vector<HostPortPair>>& GetHostnameResults()
const override {
return inner_request_->GetHostnameResults();
}
const base::Optional<HostCache::EntryStaleness>& GetStaleInfo()
const override {
return inner_request_->GetStaleInfo();
}
void ChangeRequestPriority(RequestPriority priority) override {
inner_request_->ChangeRequestPriority(priority);
}
private:
std::unique_ptr<HostResolverManager::CancellableRequest> inner_request_;
// Resolver is expected to call Cancel() on destruction, clearing the pointer
// before it becomes invalid.
ContextHostResolver* resolver_;
DISALLOW_COPY_AND_ASSIGN(WrappedRequest);
};
ContextHostResolver::ContextHostResolver(HostResolverManager* manager,
std::unique_ptr<HostCache> host_cache)
: manager_(manager), host_cache_(std::move(host_cache)) {
DCHECK(manager_);
if (host_cache_)
manager_->AddHostCacheInvalidator(host_cache_->invalidator());
}
ContextHostResolver::ContextHostResolver(
std::unique_ptr<HostResolverManager> owned_manager,
std::unique_ptr<HostCache> host_cache)
: manager_(owned_manager.get()),
owned_manager_(std::move(owned_manager)),
host_cache_(std::move(host_cache)) {
DCHECK(manager_);
if (host_cache_)
manager_->AddHostCacheInvalidator(host_cache_->invalidator());
}
ContextHostResolver::~ContextHostResolver() {
if (owned_manager_)
DCHECK_EQ(owned_manager_.get(), manager_);
if (host_cache_)
manager_->RemoveHostCacheInvalidator(host_cache_->invalidator());
// Silently cancel all requests associated with this resolver.
while (!active_requests_.empty())
(*active_requests_.begin())->Cancel();
}
std::unique_ptr<HostResolver::ResolveHostRequest>
ContextHostResolver::CreateRequest(
const HostPortPair& host,
const NetLogWithSource& source_net_log,
const base::Optional<ResolveHostParameters>& optional_parameters) {
auto request = std::make_unique<WrappedRequest>(
manager_->CreateRequest(host, source_net_log, optional_parameters,
context_, host_cache_.get()),
this);
active_requests_.insert(request.get());
return request;
}
std::unique_ptr<HostResolver::MdnsListener>
ContextHostResolver::CreateMdnsListener(const HostPortPair& host,
DnsQueryType query_type) {
return manager_->CreateMdnsListener(host, query_type);
}
HostCache* ContextHostResolver::GetHostCache() {
return host_cache_.get();
}
std::unique_ptr<base::Value> ContextHostResolver::GetDnsConfigAsValue() const {
return manager_->GetDnsConfigAsValue();
}
void ContextHostResolver::SetRequestContext(
URLRequestContext* request_context) {
DCHECK(request_context);
DCHECK(!context_);
context_ = request_context;
}
HostResolverManager* ContextHostResolver::GetManagerForTesting() {
return manager_;
}
const URLRequestContext* ContextHostResolver::GetContextForTesting() const {
return context_;
}
size_t ContextHostResolver::LastRestoredCacheSize() const {
return host_cache_ ? host_cache_->last_restore_size() : 0;
}
size_t ContextHostResolver::CacheSize() const {
return host_cache_ ? host_cache_->size() : 0;
}
void ContextHostResolver::SetProcParamsForTesting(
const ProcTaskParams& proc_params) {
manager_->set_proc_params_for_test(proc_params);
}
void ContextHostResolver::SetTickClockForTesting(
const base::TickClock* tick_clock) {
manager_->SetTickClockForTesting(tick_clock);
if (host_cache_)
host_cache_->set_tick_clock_for_testing(tick_clock);
}
} // namespace net