| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/dns/mock_host_resolver.h" | 5 #include "net/dns/mock_host_resolver.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" |
| 11 #include "base/location.h" | 12 #include "base/location.h" |
| 12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 13 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
| 14 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 15 #include "base/strings/pattern.h" | 16 #include "base/strings/pattern.h" |
| 16 #include "base/strings/string_split.h" | 17 #include "base/strings/string_split.h" |
| 17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 18 #include "base/threading/platform_thread.h" | 19 #include "base/threading/platform_thread.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "net/base/ip_address.h" | 21 #include "net/base/ip_address.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 48 IPAddress ip_address; | 49 IPAddress ip_address; |
| 49 if (!ip_address.AssignFromIPLiteral(address)) { | 50 if (!ip_address.AssignFromIPLiteral(address)) { |
| 50 LOG(WARNING) << "Not a supported IP literal: " << address.as_string(); | 51 LOG(WARNING) << "Not a supported IP literal: " << address.as_string(); |
| 51 return ERR_UNEXPECTED; | 52 return ERR_UNEXPECTED; |
| 52 } | 53 } |
| 53 addrlist->push_back(IPEndPoint(ip_address, 0)); | 54 addrlist->push_back(IPEndPoint(ip_address, 0)); |
| 54 } | 55 } |
| 55 return OK; | 56 return OK; |
| 56 } | 57 } |
| 57 | 58 |
| 58 struct MockHostResolverBase::Request { | 59 class MockHostResolverBase::RequestImpl : public HostResolver::Request { |
| 59 Request(const RequestInfo& req_info, | 60 public: |
| 60 AddressList* addr, | 61 RequestImpl(const RequestInfo& req_info, |
| 61 const CompletionCallback& cb) | 62 AddressList* addr, |
| 62 : info(req_info), addresses(addr), callback(cb) {} | 63 const CompletionCallback& cb, |
| 63 RequestInfo info; | 64 MockHostResolverBase* resolver, |
| 64 AddressList* addresses; | 65 size_t id) |
| 65 CompletionCallback callback; | 66 : info_(req_info), |
| 67 addresses_(addr), |
| 68 callback_(cb), |
| 69 resolver_(resolver), |
| 70 id_(id) {} |
| 71 |
| 72 ~RequestImpl() override { |
| 73 if (resolver_) |
| 74 resolver_->DetachRequest(id_); |
| 75 } |
| 76 |
| 77 void ChangeRequestPriority(RequestPriority priority) override {} |
| 78 |
| 79 void OnResolveCompleted(MockHostResolverBase* resolver, int error) { |
| 80 DCHECK_EQ(resolver_, resolver); |
| 81 resolver_ = nullptr; |
| 82 addresses_ = nullptr; |
| 83 base::ResetAndReturn(&callback_).Run(error); |
| 84 } |
| 85 |
| 86 RequestInfo info() { return info_; } |
| 87 |
| 88 AddressList* addresses() { return addresses_; } |
| 89 |
| 90 private: |
| 91 RequestInfo info_; |
| 92 AddressList* addresses_; |
| 93 CompletionCallback callback_; |
| 94 MockHostResolverBase* resolver_; |
| 95 size_t id_; |
| 96 |
| 97 DISALLOW_COPY_AND_ASSIGN(RequestImpl); |
| 66 }; | 98 }; |
| 67 | 99 |
| 68 MockHostResolverBase::~MockHostResolverBase() { | 100 MockHostResolverBase::~MockHostResolverBase() { |
| 69 STLDeleteValues(&requests_); | 101 DCHECK(requests_.empty()); |
| 70 } | 102 } |
| 71 | 103 |
| 72 int MockHostResolverBase::Resolve(const RequestInfo& info, | 104 int MockHostResolverBase::Resolve(const RequestInfo& info, |
| 73 RequestPriority priority, | 105 RequestPriority priority, |
| 74 AddressList* addresses, | 106 AddressList* addresses, |
| 75 const CompletionCallback& callback, | 107 const CompletionCallback& callback, |
| 76 RequestHandle* handle, | 108 std::unique_ptr<Request>* request, |
| 77 const BoundNetLog& net_log) { | 109 const BoundNetLog& net_log) { |
| 78 DCHECK(CalledOnValidThread()); | 110 DCHECK(CalledOnValidThread()); |
| 111 DCHECK(request); |
| 79 last_request_priority_ = priority; | 112 last_request_priority_ = priority; |
| 80 num_resolve_++; | 113 num_resolve_++; |
| 81 size_t id = next_request_id_++; | 114 size_t id = next_request_id_++; |
| 82 int rv = ResolveFromIPLiteralOrCache(info, addresses); | 115 int rv = ResolveFromIPLiteralOrCache(info, addresses); |
| 83 if (rv != ERR_DNS_CACHE_MISS) { | 116 if (rv != ERR_DNS_CACHE_MISS) { |
| 84 return rv; | 117 return rv; |
| 85 } | 118 } |
| 86 if (synchronous_mode_) { | 119 if (synchronous_mode_) { |
| 87 return ResolveProc(id, info, addresses); | 120 return ResolveProc(info, addresses); |
| 88 } | 121 } |
| 89 // Store the request for asynchronous resolution | 122 // Store the request for asynchronous resolution |
| 90 Request* req = new Request(info, addresses, callback); | 123 std::unique_ptr<RequestImpl> req( |
| 91 requests_[id] = req; | 124 new RequestImpl(info, addresses, callback, this, id)); |
| 92 if (handle) | 125 requests_[id] = req.get(); |
| 93 *handle = reinterpret_cast<RequestHandle>(id); | 126 *request = std::move(req); |
| 94 | 127 |
| 95 if (!ondemand_mode_) { | 128 if (!ondemand_mode_) { |
| 96 base::ThreadTaskRunnerHandle::Get()->PostTask( | 129 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 97 FROM_HERE, | 130 FROM_HERE, |
| 98 base::Bind(&MockHostResolverBase::ResolveNow, AsWeakPtr(), id)); | 131 base::Bind(&MockHostResolverBase::ResolveNow, AsWeakPtr(), id)); |
| 99 } | 132 } |
| 100 | 133 |
| 101 return ERR_IO_PENDING; | 134 return ERR_IO_PENDING; |
| 102 } | 135 } |
| 103 | 136 |
| 104 int MockHostResolverBase::ResolveFromCache(const RequestInfo& info, | 137 int MockHostResolverBase::ResolveFromCache(const RequestInfo& info, |
| 105 AddressList* addresses, | 138 AddressList* addresses, |
| 106 const BoundNetLog& net_log) { | 139 const BoundNetLog& net_log) { |
| 107 num_resolve_from_cache_++; | 140 num_resolve_from_cache_++; |
| 108 DCHECK(CalledOnValidThread()); | 141 DCHECK(CalledOnValidThread()); |
| 109 next_request_id_++; | 142 next_request_id_++; |
| 110 int rv = ResolveFromIPLiteralOrCache(info, addresses); | 143 int rv = ResolveFromIPLiteralOrCache(info, addresses); |
| 111 return rv; | 144 return rv; |
| 112 } | 145 } |
| 113 | 146 |
| 114 void MockHostResolverBase::CancelRequest(RequestHandle handle) { | 147 void MockHostResolverBase::DetachRequest(size_t id) { |
| 115 DCHECK(CalledOnValidThread()); | |
| 116 size_t id = reinterpret_cast<size_t>(handle); | |
| 117 RequestMap::iterator it = requests_.find(id); | 148 RequestMap::iterator it = requests_.find(id); |
| 118 if (it != requests_.end()) { | 149 CHECK(it != requests_.end()); |
| 119 std::unique_ptr<Request> req(it->second); | 150 requests_.erase(it); |
| 120 requests_.erase(it); | |
| 121 } else { | |
| 122 NOTREACHED() << "CancelRequest must NOT be called after request is " | |
| 123 "complete or canceled."; | |
| 124 } | |
| 125 } | 151 } |
| 126 | 152 |
| 127 HostCache* MockHostResolverBase::GetHostCache() { | 153 HostCache* MockHostResolverBase::GetHostCache() { |
| 128 return cache_.get(); | 154 return cache_.get(); |
| 129 } | 155 } |
| 130 | 156 |
| 131 void MockHostResolverBase::ResolveAllPending() { | 157 void MockHostResolverBase::ResolveAllPending() { |
| 132 DCHECK(CalledOnValidThread()); | 158 DCHECK(CalledOnValidThread()); |
| 133 DCHECK(ondemand_mode_); | 159 DCHECK(ondemand_mode_); |
| 134 for (RequestMap::iterator i = requests_.begin(); i != requests_.end(); ++i) { | 160 for (RequestMap::iterator i = requests_.begin(); i != requests_.end(); ++i) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 const HostCache::Entry* entry = cache_->Lookup(key, base::TimeTicks::Now()); | 202 const HostCache::Entry* entry = cache_->Lookup(key, base::TimeTicks::Now()); |
| 177 if (entry) { | 203 if (entry) { |
| 178 rv = entry->error(); | 204 rv = entry->error(); |
| 179 if (rv == OK) | 205 if (rv == OK) |
| 180 *addresses = AddressList::CopyWithPort(entry->addresses(), info.port()); | 206 *addresses = AddressList::CopyWithPort(entry->addresses(), info.port()); |
| 181 } | 207 } |
| 182 } | 208 } |
| 183 return rv; | 209 return rv; |
| 184 } | 210 } |
| 185 | 211 |
| 186 int MockHostResolverBase::ResolveProc(size_t id, | 212 int MockHostResolverBase::ResolveProc(const RequestInfo& info, |
| 187 const RequestInfo& info, | |
| 188 AddressList* addresses) { | 213 AddressList* addresses) { |
| 189 AddressList addr; | 214 AddressList addr; |
| 190 int rv = rules_->Resolve(info.hostname(), | 215 int rv = rules_->Resolve(info.hostname(), info.address_family(), |
| 191 info.address_family(), | 216 info.host_resolver_flags(), &addr, nullptr); |
| 192 info.host_resolver_flags(), | |
| 193 &addr, | |
| 194 NULL); | |
| 195 if (cache_.get()) { | 217 if (cache_.get()) { |
| 196 HostCache::Key key(info.hostname(), | 218 HostCache::Key key(info.hostname(), |
| 197 info.address_family(), | 219 info.address_family(), |
| 198 info.host_resolver_flags()); | 220 info.host_resolver_flags()); |
| 199 // Storing a failure with TTL 0 so that it overwrites previous value. | 221 // Storing a failure with TTL 0 so that it overwrites previous value. |
| 200 base::TimeDelta ttl; | 222 base::TimeDelta ttl; |
| 201 if (rv == OK) | 223 if (rv == OK) |
| 202 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); | 224 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); |
| 203 cache_->Set(key, HostCache::Entry(rv, addr), base::TimeTicks::Now(), ttl); | 225 cache_->Set(key, HostCache::Entry(rv, addr), base::TimeTicks::Now(), ttl); |
| 204 } | 226 } |
| 205 if (rv == OK) | 227 if (rv == OK) |
| 206 *addresses = AddressList::CopyWithPort(addr, info.port()); | 228 *addresses = AddressList::CopyWithPort(addr, info.port()); |
| 207 return rv; | 229 return rv; |
| 208 } | 230 } |
| 209 | 231 |
| 210 void MockHostResolverBase::ResolveNow(size_t id) { | 232 void MockHostResolverBase::ResolveNow(size_t id) { |
| 211 RequestMap::iterator it = requests_.find(id); | 233 RequestMap::iterator it = requests_.find(id); |
| 212 if (it == requests_.end()) | 234 if (it == requests_.end()) |
| 213 return; // was canceled | 235 return; // was canceled |
| 214 | 236 |
| 215 std::unique_ptr<Request> req(it->second); | 237 RequestImpl* req = it->second; |
| 216 requests_.erase(it); | 238 requests_.erase(it); |
| 217 int rv = ResolveProc(id, req->info, req->addresses); | 239 |
| 218 if (!req->callback.is_null()) | 240 int error = ResolveProc(req->info(), req->addresses()); |
| 219 req->callback.Run(rv); | 241 req->OnResolveCompleted(this, error); |
| 220 } | 242 } |
| 221 | 243 |
| 222 //----------------------------------------------------------------------------- | 244 //----------------------------------------------------------------------------- |
| 223 | 245 |
| 224 struct RuleBasedHostResolverProc::Rule { | 246 struct RuleBasedHostResolverProc::Rule { |
| 225 enum ResolverType { | 247 enum ResolverType { |
| 226 kResolverTypeFail, | 248 kResolverTypeFail, |
| 227 kResolverTypeSystem, | 249 kResolverTypeSystem, |
| 228 kResolverTypeIPLiteral, | 250 kResolverTypeIPLiteral, |
| 229 }; | 251 }; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 // Next add a rules-based layer the use controls. | 440 // Next add a rules-based layer the use controls. |
| 419 return new RuleBasedHostResolverProc(catchall); | 441 return new RuleBasedHostResolverProc(catchall); |
| 420 } | 442 } |
| 421 | 443 |
| 422 //----------------------------------------------------------------------------- | 444 //----------------------------------------------------------------------------- |
| 423 | 445 |
| 424 int HangingHostResolver::Resolve(const RequestInfo& info, | 446 int HangingHostResolver::Resolve(const RequestInfo& info, |
| 425 RequestPriority priority, | 447 RequestPriority priority, |
| 426 AddressList* addresses, | 448 AddressList* addresses, |
| 427 const CompletionCallback& callback, | 449 const CompletionCallback& callback, |
| 428 RequestHandle* out_req, | 450 std::unique_ptr<Request>* request, |
| 429 const BoundNetLog& net_log) { | 451 const BoundNetLog& net_log) { |
| 430 return ERR_IO_PENDING; | 452 return ERR_IO_PENDING; |
| 431 } | 453 } |
| 432 | 454 |
| 433 int HangingHostResolver::ResolveFromCache(const RequestInfo& info, | 455 int HangingHostResolver::ResolveFromCache(const RequestInfo& info, |
| 434 AddressList* addresses, | 456 AddressList* addresses, |
| 435 const BoundNetLog& net_log) { | 457 const BoundNetLog& net_log) { |
| 436 return ERR_DNS_CACHE_MISS; | 458 return ERR_DNS_CACHE_MISS; |
| 437 } | 459 } |
| 438 | 460 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 452 CHECK_EQ(old_proc, current_proc_.get()); | 474 CHECK_EQ(old_proc, current_proc_.get()); |
| 453 } | 475 } |
| 454 | 476 |
| 455 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) { | 477 void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) { |
| 456 current_proc_ = proc; | 478 current_proc_ = proc; |
| 457 previous_proc_ = HostResolverProc::SetDefault(current_proc_.get()); | 479 previous_proc_ = HostResolverProc::SetDefault(current_proc_.get()); |
| 458 current_proc_->SetLastProc(previous_proc_.get()); | 480 current_proc_->SetLastProc(previous_proc_.get()); |
| 459 } | 481 } |
| 460 | 482 |
| 461 } // namespace net | 483 } // namespace net |
| OLD | NEW |