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

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

Issue 8762001: Isolates generic DnsClient from AsyncHostResolver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: retrying to fix status of dns_session.h Created 9 years 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/dns/async_host_resolver.h ('k') | net/dns/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/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"
11 #include "base/message_loop.h"
11 #include "base/rand_util.h" 12 #include "base/rand_util.h"
12 #include "base/stl_util.h" 13 #include "base/stl_util.h"
13 #include "base/values.h" 14 #include "base/values.h"
14 #include "net/base/address_list.h" 15 #include "net/base/address_list.h"
15 #include "net/base/dns_util.h" 16 #include "net/base/dns_util.h"
16 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 #include "net/dns/dns_protocol.h"
19 #include "net/dns/dns_response.h"
20 #include "net/dns/dns_session.h"
17 #include "net/socket/client_socket_factory.h" 21 #include "net/socket/client_socket_factory.h"
18 22
19 namespace net { 23 namespace net {
20 24
21 namespace { 25 namespace {
22 26
23 // TODO(agayev): fix this when IPv6 support is added. 27 // TODO(agayev): fix this when IPv6 support is added.
24 uint16 QueryTypeFromAddressFamily(AddressFamily address_family) { 28 uint16 QueryTypeFromAddressFamily(AddressFamily address_family) {
25 return kDNS_A; 29 return dns_protocol::kTypeA;
26 } 30 }
27 31
28 class RequestParameters : public NetLog::EventParameters { 32 class RequestParameters : public NetLog::EventParameters {
29 public: 33 public:
30 RequestParameters(const HostResolver::RequestInfo& info, 34 RequestParameters(const HostResolver::RequestInfo& info,
31 const NetLog::Source& source) 35 const NetLog::Source& source)
32 : info_(info), source_(source) {} 36 : info_(info), source_(source) {}
33 37
34 virtual Value* ToValue() const { 38 virtual Value* ToValue() const {
35 DictionaryValue* dict = new DictionaryValue(); 39 DictionaryValue* dict = new DictionaryValue();
(...skipping 13 matching lines...) Expand all
49 private: 53 private:
50 const HostResolver::RequestInfo info_; 54 const HostResolver::RequestInfo info_;
51 const NetLog::Source source_; 55 const NetLog::Source source_;
52 }; 56 };
53 57
54 } // namespace 58 } // namespace
55 59
56 HostResolver* CreateAsyncHostResolver(size_t max_concurrent_resolves, 60 HostResolver* CreateAsyncHostResolver(size_t max_concurrent_resolves,
57 const IPAddressNumber& dns_ip, 61 const IPAddressNumber& dns_ip,
58 NetLog* net_log) { 62 NetLog* net_log) {
59 size_t max_transactions = max_concurrent_resolves; 63 size_t max_dns_requests = max_concurrent_resolves;
60 if (max_transactions == 0) 64 if (max_dns_requests == 0)
61 max_transactions = 20; 65 max_dns_requests = 20;
62 size_t max_pending_requests = max_transactions * 100; 66 size_t max_pending_requests = max_dns_requests * 100;
67 DnsConfig config;
68 config.nameservers.push_back(IPEndPoint(dns_ip, 53));
69 DnsSession* session = new DnsSession(
70 config,
71 ClientSocketFactory::GetDefaultFactory(),
72 base::Bind(&base::RandInt),
73 net_log);
63 HostResolver* resolver = new AsyncHostResolver( 74 HostResolver* resolver = new AsyncHostResolver(
64 IPEndPoint(dns_ip, 53), 75 max_dns_requests,
65 max_transactions,
66 max_pending_requests, 76 max_pending_requests,
67 base::Bind(&base::RandInt),
68 HostCache::CreateDefaultCache(), 77 HostCache::CreateDefaultCache(),
69 NULL, 78 DnsClient::CreateClient(session),
70 net_log); 79 net_log);
71 return resolver; 80 return resolver;
72 } 81 }
73 82
74 //----------------------------------------------------------------------------- 83 //-----------------------------------------------------------------------------
75 // 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
76 // call may complete either synchronously or asynchronously or it may get 85 // call may complete either synchronously or asynchronously or it may get
77 // cancelled, which can be either through specific CancelRequest call or by 86 // cancelled, which can be either through specific CancelRequest call or by
78 // the destruction of AsyncHostResolver, which would destruct pending or 87 // the destruction of AsyncHostResolver, which would destruct pending or
79 // in-progress requests, causing them to be cancelled. Synchronous 88 // in-progress requests, causing them to be cancelled. Synchronous
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 BoundNetLog source_net_log_; 195 BoundNetLog source_net_log_;
187 BoundNetLog request_net_log_; 196 BoundNetLog request_net_log_;
188 const HostResolver::RequestInfo info_; 197 const HostResolver::RequestInfo info_;
189 Key key_; 198 Key key_;
190 CompletionCallback callback_; 199 CompletionCallback callback_;
191 AddressList* addresses_; 200 AddressList* addresses_;
192 int result_; 201 int result_;
193 }; 202 };
194 203
195 //----------------------------------------------------------------------------- 204 //-----------------------------------------------------------------------------
196 AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server, 205 AsyncHostResolver::AsyncHostResolver(size_t max_dns_requests,
197 size_t max_transactions,
198 size_t max_pending_requests, 206 size_t max_pending_requests,
199 const RandIntCallback& rand_int_cb,
200 HostCache* cache, 207 HostCache* cache,
201 ClientSocketFactory* factory, 208 DnsClient* client,
202 NetLog* net_log) 209 NetLog* net_log)
203 : max_transactions_(max_transactions), 210 : max_dns_requests_(max_dns_requests),
204 max_pending_requests_(max_pending_requests), 211 max_pending_requests_(max_pending_requests),
205 dns_server_(dns_server),
206 rand_int_cb_(rand_int_cb),
207 cache_(cache), 212 cache_(cache),
208 factory_(factory), 213 client_(client),
209 net_log_(net_log) { 214 net_log_(net_log) {
210 } 215 }
211 216
212 AsyncHostResolver::~AsyncHostResolver() { 217 AsyncHostResolver::~AsyncHostResolver() {
213 // Destroy request lists. 218 // Destroy request lists.
214 for (KeyRequestListMap::iterator it = requestlist_map_.begin(); 219 for (KeyRequestListMap::iterator it = requestlist_map_.begin();
215 it != requestlist_map_.end(); ++it) 220 it != requestlist_map_.end(); ++it)
216 STLDeleteElements(&it->second); 221 STLDeleteElements(&it->second);
217 222
218 // Destroy transactions. 223 // Destroy DNS requests.
219 STLDeleteElements(&transactions_); 224 STLDeleteElements(&dns_requests_);
220 225
221 // Destroy pending requests. 226 // Destroy pending requests.
222 for (size_t i = 0; i < arraysize(pending_requests_); ++i) 227 for (size_t i = 0; i < arraysize(pending_requests_); ++i)
223 STLDeleteElements(&pending_requests_[i]); 228 STLDeleteElements(&pending_requests_[i]);
224 } 229 }
225 230
226 int AsyncHostResolver::Resolve(const RequestInfo& info, 231 int AsyncHostResolver::Resolve(const RequestInfo& info,
227 AddressList* addresses, 232 AddressList* addresses,
228 const CompletionCallback& callback, 233 const CompletionCallback& callback,
229 RequestHandle* out_req, 234 RequestHandle* out_req,
230 const BoundNetLog& source_net_log) { 235 const BoundNetLog& source_net_log) {
231 DCHECK(addresses); 236 DCHECK(addresses);
232 DCHECK_EQ(false, callback.is_null()); 237 DCHECK_EQ(false, callback.is_null());
233 scoped_ptr<Request> request( 238 scoped_ptr<Request> request(
234 CreateNewRequest(info, callback, addresses, source_net_log)); 239 CreateNewRequest(info, callback, addresses, source_net_log));
235 240
236 int rv = ERR_UNEXPECTED; 241 int rv = ERR_UNEXPECTED;
237 if (!request->IsValid()) 242 if (!request->IsValid())
238 rv = ERR_NAME_NOT_RESOLVED; 243 rv = ERR_NAME_NOT_RESOLVED;
239 else if (request->ResolveAsIp() || request->ServeFromCache()) 244 else if (request->ResolveAsIp() || request->ServeFromCache())
240 rv = request->result(); 245 rv = request->result();
241 else if (AttachToRequestList(request.get())) 246 else if (AttachToRequestList(request.get()))
242 rv = ERR_IO_PENDING; 247 rv = ERR_IO_PENDING;
243 else if (transactions_.size() < max_transactions_) 248 else if (dns_requests_.size() < max_dns_requests_)
244 rv = StartNewTransactionFor(request.get()); 249 rv = StartNewDnsRequestFor(request.get());
245 else 250 else
246 rv = Enqueue(request.get()); 251 rv = Enqueue(request.get());
247 252
248 if (rv != ERR_IO_PENDING) { 253 if (rv != ERR_IO_PENDING) {
249 request->OnSyncComplete(rv); 254 request->OnSyncComplete(rv);
250 } else { 255 } else {
251 Request* req = request.release(); 256 Request* req = request.release();
252 if (out_req) 257 if (out_req)
253 *out_req = reinterpret_cast<RequestHandle>(req); 258 *out_req = reinterpret_cast<RequestHandle>(req);
254 } 259 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 325 }
321 326
322 AddressFamily AsyncHostResolver::GetDefaultAddressFamily() const { 327 AddressFamily AsyncHostResolver::GetDefaultAddressFamily() const {
323 return ADDRESS_FAMILY_IPV4; 328 return ADDRESS_FAMILY_IPV4;
324 } 329 }
325 330
326 HostCache* AsyncHostResolver::GetHostCache() { 331 HostCache* AsyncHostResolver::GetHostCache() {
327 return cache_.get(); 332 return cache_.get();
328 } 333 }
329 334
330 void AsyncHostResolver::OnTransactionComplete( 335 void AsyncHostResolver::OnDnsRequestComplete(
336 DnsClient::Request* dns_req,
331 int result, 337 int result,
332 const DnsTransaction* transaction, 338 const DnsResponse* response) {
333 const IPAddressList& ip_addresses) { 339 DCHECK(std::find(dns_requests_.begin(), dns_requests_.end(), dns_req)
334 DCHECK(std::find(transactions_.begin(), transactions_.end(), transaction) 340 != dns_requests_.end());
335 != transactions_.end());
336 DCHECK(requestlist_map_.find(transaction->key()) != requestlist_map_.end());
337 341
338 // If by the time requests that caused |transaction| are cancelled, we do 342 // If by the time requests that caused |dns_req| are cancelled, we do
339 // not have a port number to associate with the result, therefore, we 343 // not have a port number to associate with the result, therefore, we
340 // assume the most common port, otherwise we use the port number of the 344 // assume the most common port, otherwise we use the port number of the
341 // first request. 345 // first request.
342 RequestList& requests = requestlist_map_[transaction->key()]; 346 KeyRequestListMap::iterator rit = requestlist_map_.find(
347 std::make_pair(dns_req->qname(), dns_req->qtype()));
348 DCHECK(rit != requestlist_map_.end());
349 RequestList& requests = rit->second;
343 int port = requests.empty() ? 80 : requests.front()->info().port(); 350 int port = requests.empty() ? 80 : requests.front()->info().port();
344 351
345 // Run callback of every request that was depending on this transaction, 352 // Extract AddressList out of DnsResponse.
353 AddressList addr_list;
354 if (result == OK) {
355 IPAddressList ip_addresses;
356 DnsRecordParser parser = response->Parser();
357 DnsResourceRecord record;
358 // TODO(szym): Add stricter checking of names, aliases and address lengths.
359 while (parser.ParseRecord(&record)) {
360 if (record.type == dns_req->qtype() &&
361 (record.rdata.size() == kIPv4AddressSize ||
362 record.rdata.size() == kIPv6AddressSize)) {
363 ip_addresses.push_back(IPAddressNumber(record.rdata.begin(),
364 record.rdata.end()));
365 }
366 }
367 if (!ip_addresses.empty())
368 addr_list = AddressList::CreateFromIPAddressList(ip_addresses, port);
369 else
370 result = ERR_NAME_NOT_RESOLVED;
371 }
372
373 // Run callback of every request that was depending on this DNS request,
346 // also notify observers. 374 // also notify observers.
347 AddressList addrlist; 375 for (RequestList::iterator it = requests.begin(); it != requests.end(); ++it)
348 if (result == OK) 376 (*it)->OnAsyncComplete(result, addr_list);
349 addrlist = AddressList::CreateFromIPAddressList(ip_addresses, port);
350 for (RequestList::iterator it = requests.begin(); it != requests.end();
351 ++it)
352 (*it)->OnAsyncComplete(result, addrlist);
353 377
354 // It is possible that the requests that caused |transaction| to be 378 // It is possible that the requests that caused |dns_req| to be
355 // created are cancelled by the time |transaction| completes. In that 379 // created are cancelled by the time |dns_req| completes. In that
356 // case |requests| would be empty. We are knowingly throwing away the 380 // case |requests| would be empty. We are knowingly throwing away the
357 // result of a DNS resolution in that case, because (a) if there are no 381 // result of a DNS resolution in that case, because (a) if there are no
358 // requests, we do not have info to obtain a key from, (b) DnsTransaction 382 // requests, we do not have info to obtain a key from, (b) DnsTransaction
359 // does not have info(), adding one into it just temporarily doesn't make 383 // does not have info(), adding one into it just temporarily doesn't make
360 // sense, since HostCache will be replaced with RR cache soon, (c) 384 // sense, since HostCache will be replaced with RR cache soon.
361 // recreating info from DnsTransaction::Key adds a lot of temporary
362 // code/functions (like converting back from qtype to AddressFamily.)
363 // Also, we only cache positive results. All of this will change when RR 385 // Also, we only cache positive results. All of this will change when RR
364 // cache is added. 386 // cache is added.
365 if (result == OK && cache_.get() && !requests.empty()) { 387 if (result == OK && cache_.get() && !requests.empty()) {
366 Request* request = requests.front(); 388 Request* request = requests.front();
367 HostResolver::RequestInfo info = request->info(); 389 HostResolver::RequestInfo info = request->info();
368 HostCache::Key key( 390 HostCache::Key key(
369 info.hostname(), info.address_family(), info.host_resolver_flags()); 391 info.hostname(), info.address_family(), info.host_resolver_flags());
370 cache_->Set(key, result, addrlist, base::TimeTicks::Now()); 392 cache_->Set(key, result, addr_list, base::TimeTicks::Now());
371 } 393 }
372 394
373 // Cleanup requests. 395 // Cleanup requests.
374 STLDeleteElements(&requests); 396 STLDeleteElements(&requests);
375 requestlist_map_.erase(transaction->key()); 397 requestlist_map_.erase(rit);
376 398
377 // Cleanup transaction and start a new one if there are pending requests. 399 // Cleanup |dns_req| and start a new one if there are pending requests.
378 delete transaction; 400 delete dns_req;
379 transactions_.remove(transaction); 401 dns_requests_.remove(dns_req);
380 ProcessPending(); 402 ProcessPending();
381 } 403 }
382 404
383 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( 405 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest(
384 const RequestInfo& info, 406 const RequestInfo& info,
385 const CompletionCallback& callback, 407 const CompletionCallback& callback,
386 AddressList* addresses, 408 AddressList* addresses,
387 const BoundNetLog& source_net_log) { 409 const BoundNetLog& source_net_log) {
388 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, 410 BoundNetLog request_net_log = BoundNetLog::Make(net_log_,
389 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST); 411 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST);
390 return new Request( 412 return new Request(
391 this, source_net_log, request_net_log, info, callback, addresses); 413 this, source_net_log, request_net_log, info, callback, addresses);
392 } 414 }
393 415
394 bool AsyncHostResolver::AttachToRequestList(Request* request) { 416 bool AsyncHostResolver::AttachToRequestList(Request* request) {
395 KeyRequestListMap::iterator it = requestlist_map_.find(request->key()); 417 KeyRequestListMap::iterator it = requestlist_map_.find(request->key());
396 if (it == requestlist_map_.end()) 418 if (it == requestlist_map_.end())
397 return false; 419 return false;
398 it->second.push_back(request); 420 it->second.push_back(request);
399 return true; 421 return true;
400 } 422 }
401 423
402 int AsyncHostResolver::StartNewTransactionFor(Request* request) { 424 int AsyncHostResolver::StartNewDnsRequestFor(Request* request) {
403 DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end()); 425 DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end());
404 DCHECK(transactions_.size() < max_transactions_); 426 DCHECK(dns_requests_.size() < max_dns_requests_);
405 427
406 request->request_net_log().AddEvent( 428 request->request_net_log().AddEvent(
407 NetLog::TYPE_ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION, NULL); 429 NetLog::TYPE_ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION, NULL);
408 430
409 requestlist_map_[request->key()].push_back(request); 431 requestlist_map_[request->key()].push_back(request);
410 DnsTransaction* transaction = new DnsTransaction( 432 DnsClient::Request* dns_req = client_->CreateRequest(
411 dns_server_,
412 request->key().first, 433 request->key().first,
413 request->key().second, 434 request->key().second,
414 rand_int_cb_, 435 base::Bind(&AsyncHostResolver::OnDnsRequestComplete,
415 factory_, 436 base::Unretained(this)),
416 request->request_net_log(), 437 request->request_net_log());
417 net_log_); 438 dns_requests_.push_back(dns_req);
418 transaction->SetDelegate(this); 439 return dns_req->Start();
419 transactions_.push_back(transaction);
420 return transaction->Start();
421 } 440 }
422 441
423 int AsyncHostResolver::Enqueue(Request* request) { 442 int AsyncHostResolver::Enqueue(Request* request) {
424 Request* evicted_request = Insert(request); 443 Request* evicted_request = Insert(request);
425 int rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; 444 int rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
426 if (evicted_request == request) 445 if (evicted_request == request)
427 return rv; 446 return rv;
428 if (evicted_request != NULL) { 447 if (evicted_request != NULL) {
429 evicted_request->OnAsyncComplete(rv, AddressList()); 448 evicted_request->OnAsyncComplete(rv, AddressList());
430 delete evicted_request; 449 delete evicted_request;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 RequestList::iterator it = requests.begin(); 502 RequestList::iterator it = requests.begin();
484 while (it != requests.end()) { 503 while (it != requests.end()) {
485 if (request->key() == (*it)->key()) { 504 if (request->key() == (*it)->key()) {
486 requestlist_map_[request->key()].push_back(*it); 505 requestlist_map_[request->key()].push_back(*it);
487 it = requests.erase(it); 506 it = requests.erase(it);
488 } else { 507 } else {
489 ++it; 508 ++it;
490 } 509 }
491 } 510 }
492 } 511 }
493 StartNewTransactionFor(request); 512 StartNewDnsRequestFor(request);
494 } 513 }
495 514
496 } // namespace net 515 } // namespace net
OLDNEW
« no previous file with comments | « net/dns/async_host_resolver.h ('k') | net/dns/async_host_resolver_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698