Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: net/base/async_host_resolver.cc

Issue 7466031: AsyncHostResolver: integrated HostCache, temporarily, until we have RR cache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed copyright year. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/async_host_resolver.h ('k') | net/base/async_host_resolver_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/base/async_host_resolver.h" 5 #include "net/base/async_host_resolver.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 NetLog* net_log) { 73 NetLog* net_log) {
74 size_t max_transactions = max_concurrent_resolves; 74 size_t max_transactions = max_concurrent_resolves;
75 if (max_transactions == 0) 75 if (max_transactions == 0)
76 max_transactions = 20; 76 max_transactions = 20;
77 size_t max_pending_requests = max_transactions * 100; 77 size_t max_pending_requests = max_transactions * 100;
78 HostResolver* resolver = new AsyncHostResolver( 78 HostResolver* resolver = new AsyncHostResolver(
79 IPEndPoint(dns_ip, 53), 79 IPEndPoint(dns_ip, 53),
80 max_transactions, 80 max_transactions,
81 max_pending_requests, 81 max_pending_requests,
82 base::Bind(&base::RandInt), 82 base::Bind(&base::RandInt),
83 HostCache::CreateDefaultCache(),
83 NULL, 84 NULL,
84 net_log); 85 net_log);
85 return resolver; 86 return resolver;
86 } 87 }
87 88
88 //----------------------------------------------------------------------------- 89 //-----------------------------------------------------------------------------
89 class AsyncHostResolver::Request { 90 class AsyncHostResolver::Request {
90 public: 91 public:
91 Request(const BoundNetLog& source_net_log, 92 Request(const BoundNetLog& source_net_log,
92 const BoundNetLog& request_net_log, 93 const BoundNetLog& request_net_log,
(...skipping 11 matching lines...) Expand all
104 addresses_(addresses) { 105 addresses_(addresses) {
105 DCHECK(addresses_); 106 DCHECK(addresses_);
106 } 107 }
107 108
108 int id() const { return id_; } 109 int id() const { return id_; }
109 const HostResolver::RequestInfo& info() const { return info_; } 110 const HostResolver::RequestInfo& info() const { return info_; }
110 const Key& key() const { return key_; } 111 const Key& key() const { return key_; }
111 RequestPriority priority() const { return info_.priority(); } 112 RequestPriority priority() const { return info_.priority(); }
112 const BoundNetLog& source_net_log() const { return source_net_log_; } 113 const BoundNetLog& source_net_log() const { return source_net_log_; }
113 const BoundNetLog& request_net_log() const { return request_net_log_; } 114 const BoundNetLog& request_net_log() const { return request_net_log_; }
114 const AddressList* addresses() const { return addresses_; } 115 void set_addresses(const AddressList& addresses) { *addresses_ = addresses; }
115 116
116 void OnComplete(int result, const IPAddressList& ip_addresses) { 117 void OnComplete(int result, const IPAddressList& ip_addresses) {
117 DCHECK(callback_); 118 DCHECK(callback_);
118 if (result == OK) 119 if (result == OK)
119 *addresses_ = 120 *addresses_ =
120 AddressList::CreateFromIPAddressList(ip_addresses, info_.port()); 121 AddressList::CreateFromIPAddressList(ip_addresses, info_.port());
121 callback_->Run(result); 122 callback_->Run(result);
122 } 123 }
123 124
124 private: 125 private:
125 BoundNetLog source_net_log_; 126 BoundNetLog source_net_log_;
126 BoundNetLog request_net_log_; 127 BoundNetLog request_net_log_;
127 const int id_; 128 const int id_;
128 const HostResolver::RequestInfo info_; 129 const HostResolver::RequestInfo info_;
129 const Key key_; 130 const Key key_;
130 CompletionCallback* callback_; 131 CompletionCallback* callback_;
131 AddressList* addresses_; 132 AddressList* addresses_;
132 }; 133 };
133 134
134 //----------------------------------------------------------------------------- 135 //-----------------------------------------------------------------------------
135 AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server, 136 AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server,
136 size_t max_transactions, 137 size_t max_transactions,
137 size_t max_pending_requests, 138 size_t max_pending_requests,
138 const RandIntCallback& rand_int_cb, 139 const RandIntCallback& rand_int_cb,
140 HostCache* cache,
139 ClientSocketFactory* factory, 141 ClientSocketFactory* factory,
140 NetLog* net_log) 142 NetLog* net_log)
141 : max_transactions_(max_transactions), 143 : max_transactions_(max_transactions),
142 max_pending_requests_(max_pending_requests), 144 max_pending_requests_(max_pending_requests),
143 dns_server_(dns_server), 145 dns_server_(dns_server),
144 rand_int_cb_(rand_int_cb), 146 rand_int_cb_(rand_int_cb),
147 cache_(cache),
145 factory_(factory), 148 factory_(factory),
146 next_request_id_(0), 149 next_request_id_(0),
147 net_log_(net_log) { 150 net_log_(net_log) {
148 } 151 }
149 152
150 AsyncHostResolver::~AsyncHostResolver() { 153 AsyncHostResolver::~AsyncHostResolver() {
151 // Destroy request lists. 154 // Destroy request lists.
152 for (KeyRequestListMap::iterator it = requestlist_map_.begin(); 155 for (KeyRequestListMap::iterator it = requestlist_map_.begin();
153 it != requestlist_map_.end(); ++it) 156 it != requestlist_map_.end(); ++it)
154 STLDeleteElements(&it->second); 157 STLDeleteElements(&it->second);
(...skipping 14 matching lines...) Expand all
169 DCHECK(addresses); 172 DCHECK(addresses);
170 IPAddressNumber ip_number; 173 IPAddressNumber ip_number;
171 std::string dns_name; 174 std::string dns_name;
172 int rv = ERR_UNEXPECTED; 175 int rv = ERR_UNEXPECTED;
173 if (info.hostname().empty()) 176 if (info.hostname().empty())
174 rv = ERR_NAME_NOT_RESOLVED; 177 rv = ERR_NAME_NOT_RESOLVED;
175 else if (ParseIPLiteralToNumber(info.hostname(), &ip_number)) 178 else if (ParseIPLiteralToNumber(info.hostname(), &ip_number))
176 rv = ResolveAsIp(info, ip_number, addresses); 179 rv = ResolveAsIp(info, ip_number, addresses);
177 else if (!DNSDomainFromDot(info.hostname(), &dns_name)) 180 else if (!DNSDomainFromDot(info.hostname(), &dns_name))
178 rv = ERR_NAME_NOT_RESOLVED; 181 rv = ERR_NAME_NOT_RESOLVED;
179 else if (info.only_use_cached_response()) // TODO(agayev): support caching
180 rv = ERR_NAME_NOT_RESOLVED;
181 182
182 Request* request = CreateNewRequest( 183 Request* request = CreateNewRequest(
183 info, dns_name, callback, addresses, source_net_log); 184 info, dns_name, callback, addresses, source_net_log);
184 185
185 OnStart(request); 186 OnStart(request);
187 if (rv == ERR_UNEXPECTED) {
188 if (ServeFromCache(request))
189 rv = OK;
190 else if (info.only_use_cached_response())
191 rv = ERR_NAME_NOT_RESOLVED;
192 }
193
186 if (rv != ERR_UNEXPECTED) { 194 if (rv != ERR_UNEXPECTED) {
187 OnFinish(request, rv); 195 OnFinish(request, rv);
188 delete request; 196 delete request;
189 return rv; 197 return rv; // Synchronous resolution ends here.
190 } 198 }
191 199
192 if (out_req) 200 if (out_req)
193 *out_req = reinterpret_cast<RequestHandle>(request); 201 *out_req = reinterpret_cast<RequestHandle>(request);
194
195 if (AttachToRequestList(request)) 202 if (AttachToRequestList(request))
196 return ERR_IO_PENDING; 203 return ERR_IO_PENDING;
197 if (transactions_.size() < max_transactions_) 204 if (transactions_.size() < max_transactions_)
198 return StartNewTransactionFor(request); 205 return StartNewTransactionFor(request);
199 return Enqueue(request); 206 return Enqueue(request);
200 } 207 }
201 208
202 void AsyncHostResolver::OnStart(Request* request) { 209 void AsyncHostResolver::OnStart(Request* request) {
203 DCHECK(request); 210 DCHECK(request);
204 211
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } 285 }
279 286
280 HostResolverImpl* AsyncHostResolver::GetAsHostResolverImpl() { 287 HostResolverImpl* AsyncHostResolver::GetAsHostResolverImpl() {
281 return NULL; 288 return NULL;
282 } 289 }
283 290
284 void AsyncHostResolver::OnTransactionComplete( 291 void AsyncHostResolver::OnTransactionComplete(
285 int result, 292 int result,
286 const DnsTransaction* transaction, 293 const DnsTransaction* transaction,
287 const IPAddressList& ip_addresses) { 294 const IPAddressList& ip_addresses) {
288
289 DCHECK(std::find(transactions_.begin(), transactions_.end(), transaction) 295 DCHECK(std::find(transactions_.begin(), transactions_.end(), transaction)
290 != transactions_.end()); 296 != transactions_.end());
291 DCHECK(requestlist_map_.find(transaction->key()) != requestlist_map_.end()); 297 DCHECK(requestlist_map_.find(transaction->key()) != requestlist_map_.end());
292 298
293 // Run callback of every request that was depending on this transaction, 299 // Run callback of every request that was depending on this transaction,
294 // also notify observers. 300 // also notify observers.
295 RequestList& requests = requestlist_map_[transaction->key()]; 301 RequestList& requests = requestlist_map_[transaction->key()];
296 for (RequestList::iterator it = requests.begin(); it != requests.end(); 302 for (RequestList::iterator it = requests.begin(); it != requests.end();
297 ++it) { 303 ++it) {
298 Request* request = *it; 304 Request* request = *it;
299 OnFinish(request, result); 305 OnFinish(request, result);
300 request->OnComplete(result, ip_addresses); 306 request->OnComplete(result, ip_addresses);
301 } 307 }
302 308
309 // It is possible that the requests that caused |transaction| to be
310 // created are cancelled by the time |transaction| completes. In that
311 // case |requests| would be empty. We are knowingly throwing away the
312 // result of a DNS resolution in that case, because (a) if there are no
313 // requests, we do not have info to obtain a key from, (b) DnsTransaction
314 // does not have info(), adding one into it just temporarily doesn't make
315 // sense, since HostCache will be replaced with RR cache soon, (c)
316 // recreating info from DnsTransaction::Key adds a lot of temporary
317 // code/functions (like converting back from qtype to AddressFamily.)
318 // Also, we only cache positive results. All of this will change when RR
319 // cache is added.
320 if (result == OK && cache_.get() && !requests.empty()) {
321 Request* request = requests.front();
322 HostResolver::RequestInfo info = request->info();
323 HostCache::Key key(
324 info.hostname(), info.address_family(), info.host_resolver_flags());
325 AddressList addrlist =
326 AddressList::CreateFromIPAddressList(ip_addresses, info.port());
327 cache_->Set(key, result, addrlist, base::TimeTicks::Now());
328 }
329
303 // Cleanup requests. 330 // Cleanup requests.
304 STLDeleteElements(&requests); 331 STLDeleteElements(&requests);
305 requestlist_map_.erase(transaction->key()); 332 requestlist_map_.erase(transaction->key());
306 333
307 // Cleanup transaction and start a new one if there are pending requests. 334 // Cleanup transaction and start a new one if there are pending requests.
308 delete transaction; 335 delete transaction;
309 transactions_.remove(transaction); 336 transactions_.remove(transaction);
310 ProcessPending(); 337 ProcessPending();
311 } 338 }
312 339
340 bool AsyncHostResolver::ServeFromCache(Request* request) const {
341 // Sanity check -- it shouldn't be the case that allow_cached_response is
342 // false while only_use_cached_response is true.
343 DCHECK(request->info().allow_cached_response() ||
344 !request->info().only_use_cached_response());
345
346 if (!cache_.get() || !request->info().allow_cached_response())
347 return false;
348
349 HostResolver::RequestInfo info = request->info();
350 HostCache::Key key(info.hostname(), info.address_family(),
351 info.host_resolver_flags());
352 const HostCache::Entry* cache_entry = cache_->Lookup(
353 key, base::TimeTicks::Now());
354 if (cache_entry) {
355 request->request_net_log().AddEvent(
356 NetLog::TYPE_ASYNC_HOST_RESOLVER_CACHE_HIT, NULL);
357 DCHECK_EQ(OK, cache_entry->error);
358 request->set_addresses(
359 CreateAddressListUsingPort(cache_entry->addrlist, info.port()));
360 return true;
361 }
362 return false;
363 }
364
313 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( 365 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest(
314 const RequestInfo& info, 366 const RequestInfo& info,
315 const std::string& dns_name, 367 const std::string& dns_name,
316 CompletionCallback* callback, 368 CompletionCallback* callback,
317 AddressList* addresses, 369 AddressList* addresses,
318 const BoundNetLog& source_net_log) { 370 const BoundNetLog& source_net_log) {
319 371
320 uint16 query_type = QueryTypeFromAddressFamily(info.address_family()); 372 uint16 query_type = QueryTypeFromAddressFamily(info.address_family());
321 Key key(dns_name, query_type); 373 Key key(dns_name, query_type);
322 374
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 AsyncHostResolver::Request* AsyncHostResolver::Insert(Request* request) { 423 AsyncHostResolver::Request* AsyncHostResolver::Insert(Request* request) {
372 pending_requests_[request->priority()].push_back(request); 424 pending_requests_[request->priority()].push_back(request);
373 if (GetNumPending() > max_pending_requests_) { 425 if (GetNumPending() > max_pending_requests_) {
374 Request* req = RemoveLowest(); 426 Request* req = RemoveLowest();
375 DCHECK(req); 427 DCHECK(req);
376 return req; 428 return req;
377 } 429 }
378 return NULL; 430 return NULL;
379 } 431 }
380 432
381 size_t AsyncHostResolver::GetNumPending() { 433 size_t AsyncHostResolver::GetNumPending() const {
382 size_t num_pending = 0; 434 size_t num_pending = 0;
383 for (size_t i = 0; i < arraysize(pending_requests_); ++i) 435 for (size_t i = 0; i < arraysize(pending_requests_); ++i)
384 num_pending += pending_requests_[i].size(); 436 num_pending += pending_requests_[i].size();
385 return num_pending; 437 return num_pending;
386 } 438 }
387 439
388 AsyncHostResolver::Request* AsyncHostResolver::RemoveLowest() { 440 AsyncHostResolver::Request* AsyncHostResolver::RemoveLowest() {
389 for (int i = static_cast<int>(arraysize(pending_requests_)) - 1; 441 for (int i = static_cast<int>(arraysize(pending_requests_)) - 1;
390 i >= 0; --i) { 442 i >= 0; --i) {
391 RequestList& requests = pending_requests_[i]; 443 RequestList& requests = pending_requests_[i];
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 it = requests.erase(it); 475 it = requests.erase(it);
424 } else { 476 } else {
425 ++it; 477 ++it;
426 } 478 }
427 } 479 }
428 } 480 }
429 StartNewTransactionFor(request); 481 StartNewTransactionFor(request);
430 } 482 }
431 483
432 } // namespace net 484 } // namespace net
OLDNEW
« no previous file with comments | « net/base/async_host_resolver.h ('k') | net/base/async_host_resolver_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698