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

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: 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
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 17 matching lines...) Expand all
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_transactions = max_concurrent_resolves;
60 if (max_transactions == 0) 64 if (max_transactions == 0)
61 max_transactions = 20; 65 max_transactions = 20;
62 size_t max_pending_requests = max_transactions * 100; 66 size_t max_pending_requests = max_transactions * 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),
65 max_transactions, 75 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_transactions,
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_transactions_(max_transactions),
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 transactions.
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_transactions_)
244 rv = StartNewTransactionFor(request.get()); 249 rv = StartNewTransactionFor(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);
(...skipping 66 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::OnRequestComplete(
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 |transaction| 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
352 // Extract AddressList out of DnsResponse.
353 AddressList addrlist;
mmenke 2011/12/02 00:53:55 nit: Should be an underscore between words: addr
szym 2011/12/05 23:06:28 Done.
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
mmenke 2011/12/02 00:53:55 Nit: Capitalize "add", add period.
szym 2011/12/05 23:06:28 Done.
359 while (parser.ParseRecord(&record)) {
360 if (record.type == dns_req->qtype() &&
361 (record.rdata.size() == kIPv4AddressSize ||
362 record.rdata.size() == kIPv6AddressSize))
mmenke 2011/12/02 00:53:55 Chrome style is to use braces on if statements, wh
szym 2011/12/05 23:06:28 Done.
363 ip_addresses.push_back(IPAddressNumber(record.rdata.begin(),
364 record.rdata.end()));
365 }
366 if (!ip_addresses.empty())
367 addrlist = AddressList::CreateFromIPAddressList(ip_addresses, port);
368 else
369 result = ERR_DNS_MALFORMED_RESPONSE;
370 }
371
345 // Run callback of every request that was depending on this transaction, 372 // Run callback of every request that was depending on this transaction,
346 // also notify observers. 373 // also notify observers.
347 AddressList addrlist;
348 if (result == OK)
349 addrlist = AddressList::CreateFromIPAddressList(ip_addresses, port);
350 for (RequestList::iterator it = requests.begin(); it != requests.end(); 374 for (RequestList::iterator it = requests.begin(); it != requests.end();
351 ++it) 375 ++it)
352 (*it)->OnAsyncComplete(result, addrlist); 376 (*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 |transaction| to be
355 // created are cancelled by the time |transaction| completes. In that 379 // created are cancelled by the time |transaction| 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, (c)
361 // recreating info from DnsTransaction::Key adds a lot of temporary 385 // recreating info from DnsTransaction::Key adds a lot of temporary
362 // code/functions (like converting back from qtype to AddressFamily.) 386 // code/functions (like converting back from qtype to AddressFamily.)
363 // Also, we only cache positive results. All of this will change when RR 387 // Also, we only cache positive results. All of this will change when RR
364 // cache is added. 388 // cache is added.
365 if (result == OK && cache_.get() && !requests.empty()) { 389 if (result == OK && cache_.get() && !requests.empty()) {
366 Request* request = requests.front(); 390 Request* request = requests.front();
367 HostResolver::RequestInfo info = request->info(); 391 HostResolver::RequestInfo info = request->info();
368 HostCache::Key key( 392 HostCache::Key key(
369 info.hostname(), info.address_family(), info.host_resolver_flags()); 393 info.hostname(), info.address_family(), info.host_resolver_flags());
370 cache_->Set(key, result, addrlist, base::TimeTicks::Now()); 394 cache_->Set(key, result, addrlist, base::TimeTicks::Now());
371 } 395 }
372 396
373 // Cleanup requests. 397 // Cleanup requests.
374 STLDeleteElements(&requests); 398 STLDeleteElements(&requests);
375 requestlist_map_.erase(transaction->key()); 399 requestlist_map_.erase(rit);
376 400
377 // Cleanup transaction and start a new one if there are pending requests. 401 // Cleanup transaction and start a new one if there are pending requests.
378 delete transaction; 402 delete dns_req;
379 transactions_.remove(transaction); 403 dns_requests_.remove(dns_req);
380 ProcessPending(); 404 ProcessPending();
381 } 405 }
382 406
383 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( 407 AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest(
384 const RequestInfo& info, 408 const RequestInfo& info,
385 const CompletionCallback& callback, 409 const CompletionCallback& callback,
386 AddressList* addresses, 410 AddressList* addresses,
387 const BoundNetLog& source_net_log) { 411 const BoundNetLog& source_net_log) {
388 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, 412 BoundNetLog request_net_log = BoundNetLog::Make(net_log_,
389 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST); 413 NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST);
390 return new Request( 414 return new Request(
391 this, source_net_log, request_net_log, info, callback, addresses); 415 this, source_net_log, request_net_log, info, callback, addresses);
392 } 416 }
393 417
394 bool AsyncHostResolver::AttachToRequestList(Request* request) { 418 bool AsyncHostResolver::AttachToRequestList(Request* request) {
395 KeyRequestListMap::iterator it = requestlist_map_.find(request->key()); 419 KeyRequestListMap::iterator it = requestlist_map_.find(request->key());
396 if (it == requestlist_map_.end()) 420 if (it == requestlist_map_.end())
397 return false; 421 return false;
398 it->second.push_back(request); 422 it->second.push_back(request);
399 return true; 423 return true;
400 } 424 }
401 425
402 int AsyncHostResolver::StartNewTransactionFor(Request* request) { 426 int AsyncHostResolver::StartNewTransactionFor(Request* request) {
403 DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end()); 427 DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end());
404 DCHECK(transactions_.size() < max_transactions_); 428 DCHECK(dns_requests_.size() < max_transactions_);
405 429
406 request->request_net_log().AddEvent( 430 request->request_net_log().AddEvent(
407 NetLog::TYPE_ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION, NULL); 431 NetLog::TYPE_ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION, NULL);
408 432
409 requestlist_map_[request->key()].push_back(request); 433 requestlist_map_[request->key()].push_back(request);
410 DnsTransaction* transaction = new DnsTransaction( 434 DnsClient::Request* dns_req = client_->CreateRequest(
411 dns_server_,
412 request->key().first, 435 request->key().first,
413 request->key().second, 436 request->key().second,
414 rand_int_cb_, 437 base::Bind(&AsyncHostResolver::OnRequestComplete, base::Unretained(this)),
415 factory_, 438 request->request_net_log());
416 request->request_net_log(), 439 dns_requests_.push_back(dns_req);
417 net_log_); 440 return dns_req->Start();
418 transaction->SetDelegate(this);
419 transactions_.push_back(transaction);
420 return transaction->Start();
421 } 441 }
422 442
423 int AsyncHostResolver::Enqueue(Request* request) { 443 int AsyncHostResolver::Enqueue(Request* request) {
424 Request* evicted_request = Insert(request); 444 Request* evicted_request = Insert(request);
425 int rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; 445 int rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
426 if (evicted_request == request) 446 if (evicted_request == request)
427 return rv; 447 return rv;
428 if (evicted_request != NULL) { 448 if (evicted_request != NULL) {
429 evicted_request->OnAsyncComplete(rv, AddressList()); 449 evicted_request->OnAsyncComplete(rv, AddressList());
430 delete evicted_request; 450 delete evicted_request;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 it = requests.erase(it); 507 it = requests.erase(it);
488 } else { 508 } else {
489 ++it; 509 ++it;
490 } 510 }
491 } 511 }
492 } 512 }
493 StartNewTransactionFor(request); 513 StartNewTransactionFor(request);
494 } 514 }
495 515
496 } // namespace net 516 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698