blob: 3c311c4a2a8601a6828233aaa50b5e1ec437b9b1 [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"
sammc6ac3fe52015-02-25 06:00:2813
14namespace net {
sammc6119a59c2015-04-01 06:56:5215namespace {
16
17// Default TTL for successful host resolutions.
18const int kCacheEntryTTLSeconds = 5;
19
20// Default TTL for unsuccessful host resolutions.
21const int kNegativeCacheEntryTTLSeconds = 0;
22
23HostCache::Key CacheKeyForRequest(const HostResolver::RequestInfo& info) {
24 return HostCache::Key(info.hostname(), info.address_family(),
25 info.host_resolver_flags());
26}
27
28} // namespace
sammc6ac3fe52015-02-25 06:00:2829
amistry39230722015-07-03 00:24:3930class HostResolverMojo::Job : public interfaces::HostResolverRequestClient {
sammc6ac3fe52015-02-25 06:00:2831 public:
sammc6119a59c2015-04-01 06:56:5232 Job(const HostCache::Key& key,
33 AddressList* addresses,
sammc6ac3fe52015-02-25 06:00:2834 const CompletionCallback& callback,
sammc6119a59c2015-04-01 06:56:5235 mojo::InterfaceRequest<interfaces::HostResolverRequestClient> request,
36 base::WeakPtr<HostCache> host_cache);
sammc6ac3fe52015-02-25 06:00:2837
38 private:
39 // interfaces::HostResolverRequestClient override.
sammc170917f2016-10-09 23:26:0440 void ReportResult(int32_t error, const AddressList& address_list) override;
sammc6ac3fe52015-02-25 06:00:2841
amistry39230722015-07-03 00:24:3942 // Mojo error handler.
43 void OnConnectionError();
sammc6ac3fe52015-02-25 06:00:2844
sammc6119a59c2015-04-01 06:56:5245 const HostCache::Key key_;
sammc6ac3fe52015-02-25 06:00:2846 AddressList* addresses_;
47 CompletionCallback callback_;
48 mojo::Binding<interfaces::HostResolverRequestClient> binding_;
sammc6119a59c2015-04-01 06:56:5249 base::WeakPtr<HostCache> host_cache_;
sammc6ac3fe52015-02-25 06:00:2850};
51
maksim.sisov31452af2016-07-27 06:38:1052class HostResolverMojo::RequestImpl : public HostResolver::Request {
53 public:
54 explicit RequestImpl(std::unique_ptr<Job> job) : job_(std::move(job)) {}
55
56 ~RequestImpl() override {}
57
58 void ChangeRequestPriority(RequestPriority priority) override {}
59
60 private:
61 std::unique_ptr<Job> job_;
62};
63
sammca3242c92015-07-10 02:38:5164HostResolverMojo::HostResolverMojo(Impl* impl)
65 : impl_(impl),
sammc6119a59c2015-04-01 06:56:5266 host_cache_(HostCache::CreateDefaultCache()),
67 host_cache_weak_factory_(host_cache_.get()) {
sammc6ac3fe52015-02-25 06:00:2868}
69
70HostResolverMojo::~HostResolverMojo() = default;
71
72int HostResolverMojo::Resolve(const RequestInfo& info,
73 RequestPriority priority,
74 AddressList* addresses,
75 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1076 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2077 const NetLogWithSource& source_net_log) {
sammc6ac3fe52015-02-25 06:00:2878 DCHECK(thread_checker_.CalledOnValidThread());
maksim.sisov31452af2016-07-27 06:38:1079 DCHECK(request);
sammc6ac3fe52015-02-25 06:00:2880 DVLOG(1) << "Resolve " << info.host_port_pair().ToString();
sammc6119a59c2015-04-01 06:56:5281
82 HostCache::Key key = CacheKeyForRequest(info);
83 int cached_result = ResolveFromCacheInternal(info, key, addresses);
84 if (cached_result != ERR_DNS_CACHE_MISS) {
85 DVLOG(1) << "Resolved " << info.host_port_pair().ToString()
86 << " from cache";
87 return cached_result;
88 }
89
sammc6ac3fe52015-02-25 06:00:2890 interfaces::HostResolverRequestClientPtr handle;
maksim.sisov31452af2016-07-27 06:38:1091 std::unique_ptr<Job> job(new Job(key, addresses, callback,
92 mojo::GetProxy(&handle),
93 host_cache_weak_factory_.GetWeakPtr()));
94 request->reset(new RequestImpl(std::move(job)));
95
sammc170917f2016-10-09 23:26:0496 impl_->ResolveDns(base::MakeUnique<HostResolver::RequestInfo>(info),
dchengc7eeda422015-12-26 03:56:4897 std::move(handle));
sammc6ac3fe52015-02-25 06:00:2898 return ERR_IO_PENDING;
99}
100
101int HostResolverMojo::ResolveFromCache(const RequestInfo& info,
102 AddressList* addresses,
tfarina42834112016-09-22 13:38:20103 const NetLogWithSource& source_net_log) {
sammc6ac3fe52015-02-25 06:00:28104 DCHECK(thread_checker_.CalledOnValidThread());
105 DVLOG(1) << "ResolveFromCache " << info.host_port_pair().ToString();
sammc6119a59c2015-04-01 06:56:52106 return ResolveFromCacheInternal(info, CacheKeyForRequest(info), addresses);
sammc6ac3fe52015-02-25 06:00:28107}
108
sammc6119a59c2015-04-01 06:56:52109HostCache* HostResolverMojo::GetHostCache() {
110 return host_cache_.get();
111}
112
sammc6119a59c2015-04-01 06:56:52113int HostResolverMojo::ResolveFromCacheInternal(const RequestInfo& info,
114 const HostCache::Key& key,
115 AddressList* addresses) {
116 if (!info.allow_cached_response())
117 return ERR_DNS_CACHE_MISS;
118
119 const HostCache::Entry* entry =
120 host_cache_->Lookup(key, base::TimeTicks::Now());
121 if (!entry)
122 return ERR_DNS_CACHE_MISS;
123
juliatuttle317860e2016-05-12 14:47:22124 *addresses = AddressList::CopyWithPort(entry->addresses(), info.port());
125 return entry->error();
sammc6119a59c2015-04-01 06:56:52126}
127
sammc6ac3fe52015-02-25 06:00:28128HostResolverMojo::Job::Job(
sammc6119a59c2015-04-01 06:56:52129 const HostCache::Key& key,
sammc6ac3fe52015-02-25 06:00:28130 AddressList* addresses,
131 const CompletionCallback& callback,
sammc6119a59c2015-04-01 06:56:52132 mojo::InterfaceRequest<interfaces::HostResolverRequestClient> request,
133 base::WeakPtr<HostCache> host_cache)
134 : key_(key),
135 addresses_(addresses),
sammc6ac3fe52015-02-25 06:00:28136 callback_(callback),
dchengc7eeda422015-12-26 03:56:48137 binding_(this, std::move(request)),
sammc6119a59c2015-04-01 06:56:52138 host_cache_(host_cache) {
amistry39230722015-07-03 00:24:39139 binding_.set_connection_error_handler(base::Bind(
140 &HostResolverMojo::Job::OnConnectionError, base::Unretained(this)));
sammc6ac3fe52015-02-25 06:00:28141}
142
sammc170917f2016-10-09 23:26:04143void HostResolverMojo::Job::ReportResult(int32_t error,
144 const AddressList& address_list) {
145 if (error == OK)
146 *addresses_ = address_list;
sammc6119a59c2015-04-01 06:56:52147 if (host_cache_) {
148 base::TimeDelta ttl = base::TimeDelta::FromSeconds(
149 error == OK ? kCacheEntryTTLSeconds : kNegativeCacheEntryTTLSeconds);
150 HostCache::Entry entry(error, *addresses_, ttl);
151 host_cache_->Set(key_, entry, base::TimeTicks::Now(), ttl);
152 }
maksim.sisov31452af2016-07-27 06:38:10153 if (binding_.is_bound())
154 binding_.Close();
155 base::ResetAndReturn(&callback_).Run(error);
sammc6ac3fe52015-02-25 06:00:28156}
157
158void HostResolverMojo::Job::OnConnectionError() {
sammc170917f2016-10-09 23:26:04159 ReportResult(ERR_FAILED, AddressList());
sammc6ac3fe52015-02-25 06:00:28160}
161
162} // namespace net