| OLD | NEW |
| 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 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 // If by the time requests that caused |dns_req| are cancelled, we do | 342 // 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 | 343 // 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 | 344 // assume the most common port, otherwise we use the port number of the |
| 345 // first request. | 345 // first request. |
| 346 KeyRequestListMap::iterator rit = requestlist_map_.find( | 346 KeyRequestListMap::iterator rit = requestlist_map_.find( |
| 347 std::make_pair(dns_req->qname(), dns_req->qtype())); | 347 std::make_pair(dns_req->qname(), dns_req->qtype())); |
| 348 DCHECK(rit != requestlist_map_.end()); | 348 DCHECK(rit != requestlist_map_.end()); |
| 349 RequestList& requests = rit->second; | 349 RequestList& requests = rit->second; |
| 350 int port = requests.empty() ? 80 : requests.front()->info().port(); | 350 int port = requests.empty() ? 80 : requests.front()->info().port(); |
| 351 | 351 |
| 352 // Extract AddressList out of DnsResponse. | 352 // Extract AddressList and TTL out of DnsResponse. |
| 353 AddressList addr_list; | 353 AddressList addr_list; |
| 354 uint32 ttl = kuint32max; |
| 354 if (result == OK) { | 355 if (result == OK) { |
| 355 IPAddressList ip_addresses; | 356 IPAddressList ip_addresses; |
| 356 DnsRecordParser parser = response->Parser(); | 357 DnsRecordParser parser = response->Parser(); |
| 357 DnsResourceRecord record; | 358 DnsResourceRecord record; |
| 358 // TODO(szym): Add stricter checking of names, aliases and address lengths. | 359 // TODO(szym): Add stricter checking of names, aliases and address lengths. |
| 359 while (parser.ParseRecord(&record)) { | 360 while (parser.ParseRecord(&record)) { |
| 360 if (record.type == dns_req->qtype() && | 361 if (record.type == dns_req->qtype() && |
| 361 (record.rdata.size() == kIPv4AddressSize || | 362 (record.rdata.size() == kIPv4AddressSize || |
| 362 record.rdata.size() == kIPv6AddressSize)) { | 363 record.rdata.size() == kIPv6AddressSize)) { |
| 363 ip_addresses.push_back(IPAddressNumber(record.rdata.begin(), | 364 ip_addresses.push_back(IPAddressNumber(record.rdata.begin(), |
| 364 record.rdata.end())); | 365 record.rdata.end())); |
| 366 ttl = std::min(ttl, record.ttl); |
| 365 } | 367 } |
| 366 } | 368 } |
| 367 if (!ip_addresses.empty()) | 369 if (!ip_addresses.empty()) |
| 368 addr_list = AddressList::CreateFromIPAddressList(ip_addresses, port); | 370 addr_list = AddressList::CreateFromIPAddressList(ip_addresses, port); |
| 369 else | 371 else |
| 370 result = ERR_NAME_NOT_RESOLVED; | 372 result = ERR_NAME_NOT_RESOLVED; |
| 371 } | 373 } |
| 372 | 374 |
| 373 // Run callback of every request that was depending on this DNS request, | 375 // Run callback of every request that was depending on this DNS request, |
| 374 // also notify observers. | 376 // also notify observers. |
| 375 for (RequestList::iterator it = requests.begin(); it != requests.end(); ++it) | 377 for (RequestList::iterator it = requests.begin(); it != requests.end(); ++it) |
| 376 (*it)->OnAsyncComplete(result, addr_list); | 378 (*it)->OnAsyncComplete(result, addr_list); |
| 377 | 379 |
| 378 // It is possible that the requests that caused |dns_req| to be | 380 // It is possible that the requests that caused |dns_req| to be |
| 379 // created are cancelled by the time |dns_req| completes. In that | 381 // created are cancelled by the time |dns_req| completes. In that |
| 380 // case |requests| would be empty. We are knowingly throwing away the | 382 // 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 | 383 // 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 | 384 // 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 | 385 // does not have info(). |
| 384 // sense, since HostCache will be replaced with RR cache soon. | 386 // TODO(szym): Should DnsTransaction ignore HostResolverFlags or use defaults? |
| 385 // Also, we only cache positive results. All of this will change when RR | 387 if ((result == OK || result == ERR_NAME_NOT_RESOLVED) && cache_.get() && |
| 386 // cache is added. | 388 !requests.empty()) { |
| 387 if (result == OK && cache_.get() && !requests.empty()) { | |
| 388 Request* request = requests.front(); | 389 Request* request = requests.front(); |
| 389 HostResolver::RequestInfo info = request->info(); | 390 HostResolver::RequestInfo info = request->info(); |
| 390 HostCache::Key key( | 391 HostCache::Key key( |
| 391 info.hostname(), info.address_family(), info.host_resolver_flags()); | 392 info.hostname(), info.address_family(), info.host_resolver_flags()); |
| 392 cache_->Set(key, result, addr_list, base::TimeTicks::Now()); | 393 // Store negative results with TTL 0 to flush out the old entry. |
| 394 cache_->Set(key, |
| 395 result, |
| 396 addr_list, |
| 397 base::TimeTicks::Now(), |
| 398 (result == OK) ? base::TimeDelta::FromSeconds(ttl) |
| 399 : base::TimeDelta()); |
| 393 } | 400 } |
| 394 | 401 |
| 395 // Cleanup requests. | 402 // Cleanup requests. |
| 396 STLDeleteElements(&requests); | 403 STLDeleteElements(&requests); |
| 397 requestlist_map_.erase(rit); | 404 requestlist_map_.erase(rit); |
| 398 | 405 |
| 399 // Cleanup |dns_req| and start a new one if there are pending requests. | 406 // Cleanup |dns_req| and start a new one if there are pending requests. |
| 400 dns_requests_.remove(dns_req); | 407 dns_requests_.remove(dns_req); |
| 401 delete dns_req; | 408 delete dns_req; |
| 402 ProcessPending(); | 409 ProcessPending(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 it = requests.erase(it); | 513 it = requests.erase(it); |
| 507 } else { | 514 } else { |
| 508 ++it; | 515 ++it; |
| 509 } | 516 } |
| 510 } | 517 } |
| 511 } | 518 } |
| 512 StartNewDnsRequestFor(request); | 519 StartNewDnsRequestFor(request); |
| 513 } | 520 } |
| 514 | 521 |
| 515 } // namespace net | 522 } // namespace net |
| OLD | NEW |