blob: 42801461c0a6121a7cad04f7de50b36f6e80f1aa [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
rockot85dce0862015-11-13 01:33:599#include "mojo/public/cpp/bindings/binding.h"
sammc6ac3fe52015-02-25 06:00:2810#include "net/base/address_list.h"
11#include "net/base/net_errors.h"
amistry7ec58112015-02-26 06:03:0012#include "net/dns/mojo_host_type_converters.h"
eroman87c53d62015-04-02 06:51:0713#include "net/log/net_log.h"
sammc6ac3fe52015-02-25 06:00:2814
15namespace net {
sammc6119a59c2015-04-01 06:56:5216namespace {
17
18// Default TTL for successful host resolutions.
19const int kCacheEntryTTLSeconds = 5;
20
21// Default TTL for unsuccessful host resolutions.
22const int kNegativeCacheEntryTTLSeconds = 0;
23
24HostCache::Key CacheKeyForRequest(const HostResolver::RequestInfo& info) {
25 return HostCache::Key(info.hostname(), info.address_family(),
26 info.host_resolver_flags());
27}
28
29} // namespace
sammc6ac3fe52015-02-25 06:00:2830
amistry39230722015-07-03 00:24:3931class HostResolverMojo::Job : public interfaces::HostResolverRequestClient {
sammc6ac3fe52015-02-25 06:00:2832 public:
sammc6119a59c2015-04-01 06:56:5233 Job(const HostCache::Key& key,
34 AddressList* addresses,
sammc6ac3fe52015-02-25 06:00:2835 const CompletionCallback& callback,
sammc6119a59c2015-04-01 06:56:5236 mojo::InterfaceRequest<interfaces::HostResolverRequestClient> request,
37 base::WeakPtr<HostCache> host_cache);
sammc6ac3fe52015-02-25 06:00:2838
39 private:
40 // interfaces::HostResolverRequestClient override.
41 void ReportResult(int32_t error,
42 interfaces::AddressListPtr address_list) override;
43
amistry39230722015-07-03 00:24:3944 // Mojo error handler.
45 void OnConnectionError();
sammc6ac3fe52015-02-25 06:00:2846
sammc6119a59c2015-04-01 06:56:5247 const HostCache::Key key_;
sammc6ac3fe52015-02-25 06:00:2848 AddressList* addresses_;
49 CompletionCallback callback_;
50 mojo::Binding<interfaces::HostResolverRequestClient> binding_;
sammc6119a59c2015-04-01 06:56:5251 base::WeakPtr<HostCache> host_cache_;
sammc6ac3fe52015-02-25 06:00:2852};
53
sammca3242c92015-07-10 02:38:5154HostResolverMojo::HostResolverMojo(Impl* impl)
55 : impl_(impl),
sammc6119a59c2015-04-01 06:56:5256 host_cache_(HostCache::CreateDefaultCache()),
57 host_cache_weak_factory_(host_cache_.get()) {
sammc6ac3fe52015-02-25 06:00:2858}
59
60HostResolverMojo::~HostResolverMojo() = default;
61
62int HostResolverMojo::Resolve(const RequestInfo& info,
63 RequestPriority priority,
64 AddressList* addresses,
65 const CompletionCallback& callback,
66 RequestHandle* request_handle,
67 const BoundNetLog& source_net_log) {
68 DCHECK(thread_checker_.CalledOnValidThread());
69 DVLOG(1) << "Resolve " << info.host_port_pair().ToString();
sammc6119a59c2015-04-01 06:56:5270
71 HostCache::Key key = CacheKeyForRequest(info);
72 int cached_result = ResolveFromCacheInternal(info, key, addresses);
73 if (cached_result != ERR_DNS_CACHE_MISS) {
74 DVLOG(1) << "Resolved " << info.host_port_pair().ToString()
75 << " from cache";
76 return cached_result;
77 }
78
sammc6ac3fe52015-02-25 06:00:2879 interfaces::HostResolverRequestClientPtr handle;
sammc6119a59c2015-04-01 06:56:5280 *request_handle = new Job(key, addresses, callback, mojo::GetProxy(&handle),
81 host_cache_weak_factory_.GetWeakPtr());
sammca3242c92015-07-10 02:38:5182 impl_->ResolveDns(interfaces::HostResolverRequestInfo::From(info),
dchengc7eeda422015-12-26 03:56:4883 std::move(handle));
sammc6ac3fe52015-02-25 06:00:2884 return ERR_IO_PENDING;
85}
86
87int HostResolverMojo::ResolveFromCache(const RequestInfo& info,
88 AddressList* addresses,
89 const BoundNetLog& source_net_log) {
90 DCHECK(thread_checker_.CalledOnValidThread());
91 DVLOG(1) << "ResolveFromCache " << info.host_port_pair().ToString();
sammc6119a59c2015-04-01 06:56:5292 return ResolveFromCacheInternal(info, CacheKeyForRequest(info), addresses);
sammc6ac3fe52015-02-25 06:00:2893}
94
juliatuttlec53b19a72016-05-05 13:51:3195void HostResolverMojo::ChangeRequestPriority(RequestHandle req,
96 RequestPriority priority) {
97 // Do nothing, since Resolve() discarded the priority anyway.
98}
99
sammc6ac3fe52015-02-25 06:00:28100void HostResolverMojo::CancelRequest(RequestHandle req) {
101 DCHECK(thread_checker_.CalledOnValidThread());
102 // Deleting the Job closes the HostResolverRequestClient connection,
103 // signalling cancellation of the request.
104 delete static_cast<Job*>(req);
105}
106
sammc6119a59c2015-04-01 06:56:52107HostCache* HostResolverMojo::GetHostCache() {
108 return host_cache_.get();
109}
110
sammc6119a59c2015-04-01 06:56:52111int HostResolverMojo::ResolveFromCacheInternal(const RequestInfo& info,
112 const HostCache::Key& key,
113 AddressList* addresses) {
114 if (!info.allow_cached_response())
115 return ERR_DNS_CACHE_MISS;
116
117 const HostCache::Entry* entry =
118 host_cache_->Lookup(key, base::TimeTicks::Now());
119 if (!entry)
120 return ERR_DNS_CACHE_MISS;
121
juliatuttle317860e2016-05-12 14:47:22122 *addresses = AddressList::CopyWithPort(entry->addresses(), info.port());
123 return entry->error();
sammc6119a59c2015-04-01 06:56:52124}
125
sammc6ac3fe52015-02-25 06:00:28126HostResolverMojo::Job::Job(
sammc6119a59c2015-04-01 06:56:52127 const HostCache::Key& key,
sammc6ac3fe52015-02-25 06:00:28128 AddressList* addresses,
129 const CompletionCallback& callback,
sammc6119a59c2015-04-01 06:56:52130 mojo::InterfaceRequest<interfaces::HostResolverRequestClient> request,
131 base::WeakPtr<HostCache> host_cache)
132 : key_(key),
133 addresses_(addresses),
sammc6ac3fe52015-02-25 06:00:28134 callback_(callback),
dchengc7eeda422015-12-26 03:56:48135 binding_(this, std::move(request)),
sammc6119a59c2015-04-01 06:56:52136 host_cache_(host_cache) {
amistry39230722015-07-03 00:24:39137 binding_.set_connection_error_handler(base::Bind(
138 &HostResolverMojo::Job::OnConnectionError, base::Unretained(this)));
sammc6ac3fe52015-02-25 06:00:28139}
140
141void HostResolverMojo::Job::ReportResult(
142 int32_t error,
143 interfaces::AddressListPtr address_list) {
144 if (error == OK && address_list)
145 *addresses_ = address_list->To<AddressList>();
sammc6119a59c2015-04-01 06:56:52146 if (host_cache_) {
147 base::TimeDelta ttl = base::TimeDelta::FromSeconds(
148 error == OK ? kCacheEntryTTLSeconds : kNegativeCacheEntryTTLSeconds);
149 HostCache::Entry entry(error, *addresses_, ttl);
150 host_cache_->Set(key_, entry, base::TimeTicks::Now(), ttl);
151 }
sammc6ac3fe52015-02-25 06:00:28152 callback_.Run(error);
153 delete this;
154}
155
156void HostResolverMojo::Job::OnConnectionError() {
157 ReportResult(ERR_FAILED, interfaces::AddressListPtr());
158}
159
160} // namespace net