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

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

Issue 9190031: DnsClient refactoring + features (timeout, suffix search, server rotation). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added unit tests. Depends on CL 9251019 Created 8 years, 11 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
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/dns/async_host_resolver.h" 5 #include "net/dns/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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 config.nameservers.push_back(IPEndPoint(dns_ip, 53)); 68 config.nameservers.push_back(IPEndPoint(dns_ip, 53));
69 DnsSession* session = new DnsSession( 69 DnsSession* session = new DnsSession(
70 config, 70 config,
71 ClientSocketFactory::GetDefaultFactory(), 71 ClientSocketFactory::GetDefaultFactory(),
72 base::Bind(&base::RandInt), 72 base::Bind(&base::RandInt),
73 net_log); 73 net_log);
74 HostResolver* resolver = new AsyncHostResolver( 74 HostResolver* resolver = new AsyncHostResolver(
75 max_dns_requests, 75 max_dns_requests,
76 max_pending_requests, 76 max_pending_requests,
77 HostCache::CreateDefaultCache(), 77 HostCache::CreateDefaultCache(),
78 DnsClient::CreateClient(session), 78 DnsTransactionFactory::CreateFactory(session),
79 net_log); 79 net_log);
80 return resolver; 80 return resolver;
81 } 81 }
82 82
83 //----------------------------------------------------------------------------- 83 //-----------------------------------------------------------------------------
84 // Every call to Resolve() results in Request object being created. Such a 84 // Every call to Resolve() results in Request object being created. Such a
85 // call may complete either synchronously or asynchronously or it may get 85 // call may complete either synchronously or asynchronously or it may get
86 // cancelled, which can be either through specific CancelRequest call or by 86 // cancelled, which can be either through specific CancelRequest call or by
87 // the destruction of AsyncHostResolver, which would destruct pending or 87 // the destruction of AsyncHostResolver, which would destruct pending or
88 // in-progress requests, causing them to be cancelled. Synchronous 88 // in-progress requests, causing them to be cancelled. Synchronous
(...skipping 10 matching lines...) Expand all
99 : resolver_(resolver), 99 : resolver_(resolver),
100 source_net_log_(source_net_log), 100 source_net_log_(source_net_log),
101 request_net_log_(request_net_log), 101 request_net_log_(request_net_log),
102 info_(info), 102 info_(info),
103 callback_(callback), 103 callback_(callback),
104 addresses_(addresses), 104 addresses_(addresses),
105 result_(ERR_UNEXPECTED) { 105 result_(ERR_UNEXPECTED) {
106 DCHECK(addresses_); 106 DCHECK(addresses_);
107 DCHECK(resolver_); 107 DCHECK(resolver_);
108 resolver_->OnStart(this); 108 resolver_->OnStart(this);
109 std::string dns_name; 109 key_ = Key(info.hostname(),
110 if (DNSDomainFromDot(info.hostname(), &dns_name)) 110 QueryTypeFromAddressFamily(info.address_family()));
111 key_ = Key(dns_name, QueryTypeFromAddressFamily(info.address_family()));
112 } 111 }
113 112
114 ~Request() { 113 ~Request() {
115 if (!callback_.is_null()) 114 if (!callback_.is_null())
116 resolver_->OnCancel(this); 115 resolver_->OnCancel(this);
117 } 116 }
118 117
119 int result() const { return result_; } 118 int result() const { return result_; }
120 const Key& key() const { 119 const Key& key() const {
121 DCHECK(IsValid()); 120 DCHECK(IsValid());
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 Key key_; 197 Key key_;
199 CompletionCallback callback_; 198 CompletionCallback callback_;
200 AddressList* addresses_; 199 AddressList* addresses_;
201 int result_; 200 int result_;
202 }; 201 };
203 202
204 //----------------------------------------------------------------------------- 203 //-----------------------------------------------------------------------------
205 AsyncHostResolver::AsyncHostResolver(size_t max_dns_requests, 204 AsyncHostResolver::AsyncHostResolver(size_t max_dns_requests,
206 size_t max_pending_requests, 205 size_t max_pending_requests,
207 HostCache* cache, 206 HostCache* cache,
208 DnsClient* client, 207 scoped_ptr<DnsTransactionFactory> client,
209 NetLog* net_log) 208 NetLog* net_log)
210 : max_dns_requests_(max_dns_requests), 209 : max_dns_requests_(max_dns_requests),
211 max_pending_requests_(max_pending_requests), 210 max_pending_requests_(max_pending_requests),
212 cache_(cache), 211 cache_(cache),
213 client_(client), 212 client_(client.Pass()),
214 net_log_(net_log) { 213 net_log_(net_log) {
215 } 214 }
216 215
217 AsyncHostResolver::~AsyncHostResolver() { 216 AsyncHostResolver::~AsyncHostResolver() {
218 // Destroy request lists. 217 // Destroy request lists.
219 for (KeyRequestListMap::iterator it = requestlist_map_.begin(); 218 for (KeyRequestListMap::iterator it = requestlist_map_.begin();
220 it != requestlist_map_.end(); ++it) 219 it != requestlist_map_.end(); ++it)
221 STLDeleteElements(&it->second); 220 STLDeleteElements(&it->second);
222 221
223 // Destroy DNS requests. 222 // Destroy DNS requests.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 } 324 }
326 325
327 AddressFamily AsyncHostResolver::GetDefaultAddressFamily() const { 326 AddressFamily AsyncHostResolver::GetDefaultAddressFamily() const {
328 return ADDRESS_FAMILY_IPV4; 327 return ADDRESS_FAMILY_IPV4;
329 } 328 }
330 329
331 HostCache* AsyncHostResolver::GetHostCache() { 330 HostCache* AsyncHostResolver::GetHostCache() {
332 return cache_.get(); 331 return cache_.get();
333 } 332 }
334 333
335 void AsyncHostResolver::OnDnsRequestComplete( 334 void AsyncHostResolver::OnDnsTransactionComplete(
336 DnsClient::Request* dns_req, 335 DnsTransaction* transaction,
337 int result, 336 int result,
338 const DnsResponse* response) { 337 const DnsResponse* response) {
339 DCHECK(std::find(dns_requests_.begin(), dns_requests_.end(), dns_req) 338 DCHECK(std::find(dns_requests_.begin(), dns_requests_.end(), transaction)
340 != dns_requests_.end()); 339 != dns_requests_.end());
341 340
342 // If by the time requests that caused |dns_req| are cancelled, we do 341 // If by the time requests that caused |dns_req| are cancelled, we do
343 // not have a port number to associate with the result, therefore, we 342 // not have a port number to associate with the result, therefore, we
344 // assume the most common port, otherwise we use the port number of the 343 // assume the most common port, otherwise we use the port number of the
345 // first request. 344 // first request.
346 KeyRequestListMap::iterator rit = requestlist_map_.find( 345 KeyRequestListMap::iterator rit = requestlist_map_.find(
347 std::make_pair(dns_req->qname(), dns_req->qtype())); 346 std::make_pair(transaction->GetHostname(), transaction->GetType()));
348 DCHECK(rit != requestlist_map_.end()); 347 DCHECK(rit != requestlist_map_.end());
349 RequestList& requests = rit->second; 348 RequestList& requests = rit->second;
350 int port = requests.empty() ? 80 : requests.front()->info().port(); 349 int port = requests.empty() ? 80 : requests.front()->info().port();
351 350
352 // Extract AddressList out of DnsResponse. 351 // Extract AddressList out of DnsResponse.
353 AddressList addr_list; 352 AddressList addr_list;
354 if (result == OK) { 353 if (result == OK) {
355 IPAddressList ip_addresses; 354 IPAddressList ip_addresses;
356 DnsRecordParser parser = response->Parser(); 355 DnsRecordParser parser = response->Parser();
357 DnsResourceRecord record; 356 DnsResourceRecord record;
358 // TODO(szym): Add stricter checking of names, aliases and address lengths. 357 // TODO(szym): Add stricter checking of names, aliases and address lengths.
359 while (parser.ParseRecord(&record)) { 358 while (parser.ParseRecord(&record)) {
360 if (record.type == dns_req->qtype() && 359 if (record.type == transaction->GetType() &&
361 (record.rdata.size() == kIPv4AddressSize || 360 (record.rdata.size() == kIPv4AddressSize ||
362 record.rdata.size() == kIPv6AddressSize)) { 361 record.rdata.size() == kIPv6AddressSize)) {
363 ip_addresses.push_back(IPAddressNumber(record.rdata.begin(), 362 ip_addresses.push_back(IPAddressNumber(record.rdata.begin(),
364 record.rdata.end())); 363 record.rdata.end()));
365 } 364 }
366 } 365 }
367 if (!ip_addresses.empty()) 366 if (!ip_addresses.empty())
368 addr_list = AddressList::CreateFromIPAddressList(ip_addresses, port); 367 addr_list = AddressList::CreateFromIPAddressList(ip_addresses, port);
369 else 368 else
370 result = ERR_NAME_NOT_RESOLVED; 369 result = ERR_NAME_NOT_RESOLVED;
(...skipping 19 matching lines...) Expand all
390 HostCache::Key key( 389 HostCache::Key key(
391 info.hostname(), info.address_family(), info.host_resolver_flags()); 390 info.hostname(), info.address_family(), info.host_resolver_flags());
392 cache_->Set(key, result, addr_list, base::TimeTicks::Now()); 391 cache_->Set(key, result, addr_list, base::TimeTicks::Now());
393 } 392 }
394 393
395 // Cleanup requests. 394 // Cleanup requests.
396 STLDeleteElements(&requests); 395 STLDeleteElements(&requests);
397 requestlist_map_.erase(rit); 396 requestlist_map_.erase(rit);
398 397
399 // Cleanup |dns_req| and start a new one if there are pending requests. 398 // Cleanup |dns_req| and start a new one if there are pending requests.
400 dns_requests_.remove(dns_req); 399 dns_requests_.remove(transaction);
401 delete dns_req; 400 delete transaction;
402 ProcessPending(); 401 ProcessPending();
403 } 402 }
404 403
405 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( 404 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest(
406 const RequestInfo& info, 405 const RequestInfo& info,
407 const CompletionCallback& callback, 406 const CompletionCallback& callback,
408 AddressList* addresses, 407 AddressList* addresses,
409 const BoundNetLog& source_net_log) { 408 const BoundNetLog& source_net_log) {
410 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, 409 BoundNetLog request_net_log = BoundNetLog::Make(net_log_,
411 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST); 410 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST);
(...skipping 10 matching lines...) Expand all
422 } 421 }
423 422
424 int AsyncHostResolver::StartNewDnsRequestFor(Request* request) { 423 int AsyncHostResolver::StartNewDnsRequestFor(Request* request) {
425 DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end()); 424 DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end());
426 DCHECK(dns_requests_.size() < max_dns_requests_); 425 DCHECK(dns_requests_.size() < max_dns_requests_);
427 426
428 request->request_net_log().AddEvent( 427 request->request_net_log().AddEvent(
429 NetLog::TYPE_ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION, NULL); 428 NetLog::TYPE_ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION, NULL);
430 429
431 requestlist_map_[request->key()].push_back(request); 430 requestlist_map_[request->key()].push_back(request);
432 DnsClient::Request* dns_req = client_->CreateRequest( 431 scoped_ptr<DnsTransaction> dns_req = client_->CreateTransaction(
mmenke 2012/01/19 17:24:47 nit: "scoped_ptr<DnsTransaction> dns_req(client_.
mmenke 2012/01/19 17:24:47 nit: dns_transaction
433 request->key().first, 432 request->key().first,
434 request->key().second, 433 request->key().second,
435 base::Bind(&AsyncHostResolver::OnDnsRequestComplete, 434 base::Bind(&AsyncHostResolver::OnDnsTransactionComplete,
436 base::Unretained(this)), 435 base::Unretained(this)),
437 request->request_net_log()); 436 request->request_net_log());
438 dns_requests_.push_back(dns_req); 437 int rv = dns_req->Start();
439 return dns_req->Start(); 438 if (rv == ERR_IO_PENDING)
439 dns_requests_.push_back(dns_req.release());
440 return rv;
440 } 441 }
441 442
442 int AsyncHostResolver::Enqueue(Request* request) { 443 int AsyncHostResolver::Enqueue(Request* request) {
443 Request* evicted_request = Insert(request); 444 Request* evicted_request = Insert(request);
444 int rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; 445 int rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
445 if (evicted_request == request) 446 if (evicted_request == request)
446 return rv; 447 return rv;
447 if (evicted_request != NULL) { 448 if (evicted_request != NULL) {
448 evicted_request->OnAsyncComplete(rv, AddressList()); 449 evicted_request->OnAsyncComplete(rv, AddressList());
449 delete evicted_request; 450 delete evicted_request;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 it = requests.erase(it); 507 it = requests.erase(it);
507 } else { 508 } else {
508 ++it; 509 ++it;
509 } 510 }
510 } 511 }
511 } 512 }
512 StartNewDnsRequestFor(request); 513 StartNewDnsRequestFor(request);
513 } 514 }
514 515
515 } // namespace net 516 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698