15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/net/dns_probe_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/field_trial.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/dns_client.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/dns_config_service.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/dns_protocol.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::FieldTrialList; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::StringToInt; 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing chrome_common_net::DnsProbeStatus; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::DnsClient; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::DnsConfig; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::IPAddressNumber; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::IPEndPoint; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::ParseIPLiteralToNumber; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::NetworkChangeNotifier; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome_browser_net { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// How long the DnsProbeService will cache the probe result for. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// If it's older than this and we get a probe request, the service expires it 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and starts a new probe. 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMaxResultAgeMs = 5000; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The public DNS servers used by the DnsProbeService to verify internet 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// connectivity. 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kGooglePublicDns1[] = "8.8.8.8"; 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kGooglePublicDns2[] = "8.8.4.4"; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPEndPoint MakeDnsEndPoint(const std::string& dns_ip_literal) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber dns_ip_number; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool rv = ParseIPLiteralToNumber(dns_ip_literal, &dns_ip_number); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(rv); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPEndPoint(dns_ip_number, net::dns_protocol::kDefaultPort); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochDnsProbeStatus EvaluateResults(DnsProbeRunner::Result system_result, 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DnsProbeRunner::Result public_result) { 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the system DNS is working, assume the domain doesn't exist. 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (system_result == DnsProbeRunner::CORRECT) 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If the system DNS is unknown (e.g. on Android), but the public server is 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // reachable, assume the domain doesn't exist. 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (system_result == DnsProbeRunner::UNKNOWN && 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public_result == DnsProbeRunner::CORRECT) { 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN; 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the system DNS is not working but another public server is, assume the 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // DNS config is bad (or perhaps the DNS servers are down or broken). 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (public_result == DnsProbeRunner::CORRECT) 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the system DNS is not working and another public server is unreachable, 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // assume the internet connection is down (note that system DNS may be a 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // router on the LAN, so it may be reachable but returning errors.) 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (public_result == DnsProbeRunner::UNREACHABLE) 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Otherwise: the system DNS is not working and another public server is 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // responding but with errors or incorrect results. This is an awkward case; 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // an invasive captive portal or a restrictive firewall may be intercepting 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // or rewriting DNS traffic, or the public server may itself be failing or 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // down. 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HistogramProbe(DnsProbeStatus status, base::TimeDelta elapsed) { 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(chrome_common_net::DnsProbeStatusIsFinished(status)); 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("DnsProbe.ProbeResult", status, 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) chrome_common_net::DNS_PROBE_MAX); 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.ProbeDuration", elapsed); 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DnsProbeService::DnsProbeService() 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : state_(STATE_NO_RESULT) { 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NetworkChangeNotifier::AddDNSObserver(this); 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SetSystemClientToCurrentConfig(); 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SetPublicClientToGooglePublicDns(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DnsProbeService::~DnsProbeService() { 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NetworkChangeNotifier::RemoveDNSObserver(this); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::ProbeDns(const DnsProbeService::ProbeCallback& callback) { 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pending_callbacks_.push_back(callback); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (CachedResultIsExpired()) 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ClearCachedResult(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case STATE_NO_RESULT: 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch StartProbes(); 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case STATE_RESULT_CACHED: 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CallCallbacks(); 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case STATE_PROBE_RUNNING: 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Do nothing; probe is already running, and will call the callback. 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::OnDNSChanged() { 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ClearCachedResult(); 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SetSystemClientToCurrentConfig(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::SetSystemClientForTesting( 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<DnsClient> system_client) { 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch system_runner_.SetClient(system_client.Pass()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::SetPublicClientForTesting( 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<DnsClient> public_client) { 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_runner_.SetClient(public_client.Pass()); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::ClearCachedResultForTesting() { 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ClearCachedResult(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::SetSystemClientToCurrentConfig() { 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DnsConfig system_config; 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NetworkChangeNotifier::GetDnsConfig(&system_config); 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch system_config.search.clear(); 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch system_config.attempts = 1; 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch system_config.randomize_ports = false; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<DnsClient> system_client(DnsClient::CreateClient(NULL)); 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch system_client->SetConfig(system_config); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch system_runner_.SetClient(system_client.Pass()); 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::SetPublicClientToGooglePublicDns() { 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DnsConfig public_config; 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_config.nameservers.push_back(MakeDnsEndPoint(kGooglePublicDns1)); 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_config.nameservers.push_back(MakeDnsEndPoint(kGooglePublicDns2)); 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_config.attempts = 1; 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_config.randomize_ports = false; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<DnsClient> public_client(DnsClient::CreateClient(NULL)); 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_client->SetConfig(public_config); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_runner_.SetClient(public_client.Pass()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::StartProbes() { 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_EQ(STATE_NO_RESULT, state_); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!system_runner_.IsRunning()); 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!public_runner_.IsRunning()); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const base::Closure callback = base::Bind(&DnsProbeService::OnProbeComplete, 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Unretained(this)); 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch system_runner_.RunProbe(callback); 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_runner_.RunProbe(callback); 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch probe_start_time_ = base::Time::Now(); 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch state_ = STATE_PROBE_RUNNING; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(system_runner_.IsRunning()); 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(public_runner_.IsRunning()); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::OnProbeComplete() { 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_EQ(STATE_PROBE_RUNNING, state_); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (system_runner_.IsRunning() || public_runner_.IsRunning()) 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cached_result_ = EvaluateResults(system_runner_.result(), 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public_runner_.result()); 1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch state_ = STATE_RESULT_CACHED; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HistogramProbe(cached_result_, base::Time::Now() - probe_start_time_); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CallCallbacks(); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DnsProbeService::CallCallbacks() { 1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_EQ(STATE_RESULT_CACHED, state_); 1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(chrome_common_net::DnsProbeStatusIsFinished(cached_result_)); 1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!pending_callbacks_.empty()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::vector<ProbeCallback> callbacks; 2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch callbacks.swap(pending_callbacks_); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (std::vector<ProbeCallback>::const_iterator i = callbacks.begin(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != callbacks.end(); ++i) { 2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch i->Run(cached_result_); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DnsProbeService::ClearCachedResult() { 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (state_ == STATE_RESULT_CACHED) { 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch state_ = STATE_NO_RESULT; 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cached_result_ = chrome_common_net::DNS_PROBE_MAX; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool DnsProbeService::CachedResultIsExpired() const { 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (state_ != STATE_RESULT_CACHED) 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kMaxResultAge = 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kMaxResultAgeMs); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::Time::Now() - probe_start_time_ > kMaxResultAge; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace chrome_browser_net 227