blob: 4f13daf8a844c29536575b50ad1e053ef762ebdc [file] [log] [blame]
sammc6ac3fe52015-02-25 06:00:281// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/dns/host_resolver_mojo.h"
6
dchengc7eeda422015-12-26 03:56:487#include <utility>
8
maksim.sisov31452af2016-07-27 06:38:109#include "base/callback_helpers.h"
rockot85dce0862015-11-13 01:33:5910#include "mojo/public/cpp/bindings/binding.h"
sammc6ac3fe52015-02-25 06:00:2811#include "net/base/address_list.h"
12#include "net/base/net_errors.h"
amistry7ec58112015-02-26 06:03:0013#include "net/dns/mojo_host_type_converters.h"
eroman87c53d62015-04-02 06:51:0714#include "net/log/net_log.h"
sammc6ac3fe52015-02-25 06:00:2815
16namespace net {
sammc6119a59c2015-04-01 06:56:5217namespace {
18
19// Default TTL for successful host resolutions.
20const int kCacheEntryTTLSeconds = 5;
21
22// Default TTL for unsuccessful host resolutions.
23const int kNegativeCacheEntryTTLSeconds = 0;
24
25HostCache::Key CacheKeyForRequest(const HostResolver::RequestInfo& info) {
26 return HostCache::Key(info.hostname(), info.address_family(),
27 info.host_resolver_flags());
28}
29
30} // namespace
sammc6ac3fe52015-02-25 06:00:2831
amistry39230722015-07-03 00:24:3932class HostResolverMojo::Job : public interfaces::HostResolverRequestClient {
sammc6ac3fe52015-02-25 06:00:2833 public:
sammc6119a59c2015-04-01 06:56:5234 Job(const HostCache::Key& key,
35 AddressList* addresses,
sammc6ac3fe52015-02-25 06:00:2836 const CompletionCallback& callback,
sammc6119a59c2015-04-01 06:56:5237 mojo::InterfaceRequest<interfaces::HostResolverRequestClient> request,
38 base::WeakPtr<HostCache> host_cache);
sammc6ac3fe52015-02-25 06:00:2839
40 private:
41 // interfaces::HostResolverRequestClient override.
42 void ReportResult(int32_t error,
43 interfaces::AddressListPtr address_list) override;
44
amistry39230722015-07-03 00:24:3945 // Mojo error handler.
46 void OnConnectionError();
sammc6ac3fe52015-02-25 06:00:2847
sammc6119a59c2015-04-01 06:56:5248 const HostCache::Key key_;
sammc6ac3fe52015-02-25 06:00:2849 AddressList* addresses_;
50 CompletionCallback callback_;
51 mojo::Binding<interfaces::HostResolverRequestClient> binding_;
sammc6119a59c2015-04-01 06:56:5252 base::WeakPtr<HostCache> host_cache_;
sammc6ac3fe52015-02-25 06:00:2853};
54
maksim.sisov31452af2016-07-27 06:38:1055class HostResolverMojo::RequestImpl : public HostResolver::Request {
56 public:
57 explicit RequestImpl(std::unique_ptr<Job> job) : job_(std::move(job)) {}
58
59 ~RequestImpl() override {}
60
61 void ChangeRequestPriority(RequestPriority priority) override {}
62
63 private:
64 std::unique_ptr<Job> job_;
65};
66
sammca3242c92015-07-10 02:38:5167HostResolverMojo::HostResolverMojo(Impl* impl)
68 : impl_(impl),
sammc6119a59c2015-04-01 06:56:5269 host_cache_(HostCache::CreateDefaultCache()),
70 host_cache_weak_factory_(host_cache_.get()) {
sammc6ac3fe52015-02-25 06:00:2871}
72
73HostResolverMojo::~HostResolverMojo() = default;
74
75int HostResolverMojo::Resolve(const RequestInfo& info,
76 RequestPriority priority,
77 AddressList* addresses,
78 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1079 std::unique_ptr<Request>* request,
sammc6ac3fe52015-02-25 06:00:2880 const BoundNetLog& source_net_log) {
81 DCHECK(thread_checker_.CalledOnValidThread());
maksim.sisov31452af2016-07-27 06:38:1082 DCHECK(request);
sammc6ac3fe52015-02-25 06:00:2883 DVLOG(1) << "Resolve " << info.host_port_pair().ToString();
sammc6119a59c2015-04-01 06:56:5284
85 HostCache::Key key = CacheKeyForRequest(info);
86 int cached_result = ResolveFromCacheInternal(info, key, addresses);
87 if (cached_result != ERR_DNS_CACHE_MISS) {
88 DVLOG(1) << "Resolved " << info.host_port_pair().ToString()
89 << " from cache";
90 return cached_result;
91 }
92
sammc6ac3fe52015-02-25 06:00:2893 interfaces::HostResolverRequestClientPtr handle;
maksim.sisov31452af2016-07-27 06:38:1094 std::unique_ptr<Job> job(new Job(key, addresses, callback,
95 mojo::GetProxy(&handle),
96 host_cache_weak_factory_.GetWeakPtr()));
97 request->reset(new RequestImpl(std::move(job)));
98
sammca3242c92015-07-10 02:38:5199 impl_->ResolveDns(interfaces::HostResolverRequestInfo::From(info),
dchengc7eeda422015-12-26 03:56:48100 std::move(handle));
sammc6ac3fe52015-02-25 06:00:28101 return ERR_IO_PENDING;
102}
103
104int HostResolverMojo::ResolveFromCache(const RequestInfo& info,
105 AddressList* addresses,
106 const BoundNetLog& source_net_log) {
107 DCHECK(thread_checker_.CalledOnValidThread());
108 DVLOG(1) << "ResolveFromCache " << info.host_port_pair().ToString();
sammc6119a59c2015-04-01 06:56:52109 return ResolveFromCacheInternal(info, CacheKeyForRequest(info), addresses);
sammc6ac3fe52015-02-25 06:00:28110}
111
sammc6119a59c2015-04-01 06:56:52112HostCache* HostResolverMojo::GetHostCache() {
113 return host_cache_.get();
114}
115
sammc6119a59c2015-04-01 06:56:52116int HostResolverMojo::ResolveFromCacheInternal(const RequestInfo& info,
117 const HostCache::Key& key,
118 AddressList* addresses) {
119 if (!info.allow_cached_response())
120 return ERR_DNS_CACHE_MISS;
121
122 const HostCache::Entry* entry =
123 host_cache_->Lookup(key, base::TimeTicks::Now());
124 if (!entry)
125 return ERR_DNS_CACHE_MISS;
126
juliatuttle317860e2016-05-12 14:47:22127 *addresses = AddressList::CopyWithPort(entry->addresses(), info.port());
128 return entry->error();
sammc6119a59c2015-04-01 06:56:52129}
130
sammc6ac3fe52015-02-25 06:00:28131HostResolverMojo::Job::Job(
sammc6119a59c2015-04-01 06:56:52132 const HostCache::Key& key,
sammc6ac3fe52015-02-25 06:00:28133 AddressList* addresses,
134 const CompletionCallback& callback,
sammc6119a59c2015-04-01 06:56:52135 mojo::InterfaceRequest<interfaces::HostResolverRequestClient> request,
136 base::WeakPtr<HostCache> host_cache)
137 : key_(key),
138 addresses_(addresses),
sammc6ac3fe52015-02-25 06:00:28139 callback_(callback),
dchengc7eeda422015-12-26 03:56:48140 binding_(this, std::move(request)),
sammc6119a59c2015-04-01 06:56:52141 host_cache_(host_cache) {
amistry39230722015-07-03 00:24:39142 binding_.set_connection_error_handler(base::Bind(
143 &HostResolverMojo::Job::OnConnectionError, base::Unretained(this)));
sammc6ac3fe52015-02-25 06:00:28144}
145
146void HostResolverMojo::Job::ReportResult(
147 int32_t error,
148 interfaces::AddressListPtr address_list) {
149 if (error == OK && address_list)
150 *addresses_ = address_list->To<AddressList>();
sammc6119a59c2015-04-01 06:56:52151 if (host_cache_) {
152 base::TimeDelta ttl = base::TimeDelta::FromSeconds(
153 error == OK ? kCacheEntryTTLSeconds : kNegativeCacheEntryTTLSeconds);
154 HostCache::Entry entry(error, *addresses_, ttl);
155 host_cache_->Set(key_, entry, base::TimeTicks::Now(), ttl);
156 }
maksim.sisov31452af2016-07-27 06:38:10157 if (binding_.is_bound())
158 binding_.Close();
159 base::ResetAndReturn(&callback_).Run(error);
sammc6ac3fe52015-02-25 06:00:28160}
161
162void HostResolverMojo::Job::OnConnectionError() {
163 ReportResult(ERR_FAILED, interfaces::AddressListPtr());
164}
165
166} // namespace net