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

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

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