Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/dns_config_service.h" | 5 #include "net/dns/dns_config_service.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "net/base/ip_endpoint.h" | 10 #include "net/base/ip_endpoint.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 dict->SetInteger("attempts", attempts); | 68 dict->SetInteger("attempts", attempts); |
| 69 dict->SetBoolean("rotate", rotate); | 69 dict->SetBoolean("rotate", rotate); |
| 70 dict->SetBoolean("edns0", edns0); | 70 dict->SetBoolean("edns0", edns0); |
| 71 dict->SetInteger("num_hosts", hosts.size()); | 71 dict->SetInteger("num_hosts", hosts.size()); |
| 72 | 72 |
| 73 return dict; | 73 return dict; |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 DnsConfigService::DnsConfigService() | 77 DnsConfigService::DnsConfigService() |
| 78 : have_config_(false), | 78 : watch_failed_(false), |
| 79 have_config_(false), | |
| 79 have_hosts_(false), | 80 have_hosts_(false), |
| 80 need_update_(false), | 81 need_update_(false), |
| 81 last_sent_empty_(true) {} | 82 last_sent_empty_(true) {} |
| 82 | 83 |
| 83 DnsConfigService::~DnsConfigService() { | 84 DnsConfigService::~DnsConfigService() { |
| 84 // Must always clean up. | |
| 85 NetworkChangeNotifier::RemoveDNSObserver(this); | |
| 86 } | 85 } |
| 87 | 86 |
| 88 void DnsConfigService::Read(const CallbackType& callback) { | 87 void DnsConfigService::ReadConfig(const CallbackType& callback) { |
| 89 DCHECK(CalledOnValidThread()); | 88 DCHECK(CalledOnValidThread()); |
| 90 DCHECK(!callback.is_null()); | 89 DCHECK(!callback.is_null()); |
| 91 DCHECK(callback_.is_null()); | 90 DCHECK(callback_.is_null()); |
| 92 callback_ = callback; | 91 callback_ = callback; |
| 93 OnDNSChanged(NetworkChangeNotifier::CHANGE_DNS_WATCH_STARTED); | 92 ReadNow(); |
| 94 } | 93 } |
| 95 | 94 |
| 96 void DnsConfigService::Watch(const CallbackType& callback) { | 95 void DnsConfigService::WatchConfig(const CallbackType& callback) { |
| 97 DCHECK(CalledOnValidThread()); | 96 DCHECK(CalledOnValidThread()); |
| 98 DCHECK(!callback.is_null()); | 97 DCHECK(!callback.is_null()); |
| 99 DCHECK(callback_.is_null()); | 98 DCHECK(callback_.is_null()); |
| 100 NetworkChangeNotifier::AddDNSObserver(this); | |
| 101 callback_ = callback; | 99 callback_ = callback; |
| 102 if (NetworkChangeNotifier::IsWatchingDNS()) | 100 watch_failed_ = !StartWatching(); |
| 103 OnDNSChanged(NetworkChangeNotifier::CHANGE_DNS_WATCH_STARTED); | 101 ReadNow(); |
| 104 // else: Wait until signal before reading. | |
| 105 } | 102 } |
| 106 | 103 |
| 107 void DnsConfigService::InvalidateConfig() { | 104 void DnsConfigService::InvalidateConfig() { |
| 108 DCHECK(CalledOnValidThread()); | 105 DCHECK(CalledOnValidThread()); |
| 109 base::TimeTicks now = base::TimeTicks::Now(); | 106 base::TimeTicks now = base::TimeTicks::Now(); |
| 110 if (!last_invalidate_config_time_.is_null()) { | 107 if (!last_invalidate_config_time_.is_null()) { |
| 111 UMA_HISTOGRAM_LONG_TIMES("AsyncDNS.ConfigNotifyInterval", | 108 UMA_HISTOGRAM_LONG_TIMES("AsyncDNS.ConfigNotifyInterval", |
| 112 now - last_invalidate_config_time_); | 109 now - last_invalidate_config_time_); |
| 113 } | 110 } |
| 114 last_invalidate_config_time_ = now; | 111 last_invalidate_config_time_ = now; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 } | 165 } |
| 169 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostsChange", changed); | 166 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostsChange", changed); |
| 170 | 167 |
| 171 have_hosts_ = true; | 168 have_hosts_ = true; |
| 172 if (have_config_) | 169 if (have_config_) |
| 173 OnCompleteConfig(); | 170 OnCompleteConfig(); |
| 174 } | 171 } |
| 175 | 172 |
| 176 void DnsConfigService::StartTimer() { | 173 void DnsConfigService::StartTimer() { |
| 177 DCHECK(CalledOnValidThread()); | 174 DCHECK(CalledOnValidThread()); |
| 178 if (last_sent_empty_) { | 175 if (last_sent_empty_ && !watch_failed_) { |
| 179 DCHECK(!timer_.IsRunning()); | 176 DCHECK(!timer_.IsRunning()); |
| 180 return; // No need to withdraw again. | 177 return; // No need to withdraw again. |
| 181 } | 178 } |
| 182 timer_.Stop(); | 179 timer_.Stop(); |
| 183 | 180 |
| 184 // Give it a short timeout to come up with a valid config. Otherwise withdraw | 181 // Give it a short timeout to come up with a valid config. Otherwise withdraw |
| 185 // the config from the receiver. The goal is to avoid perceivable network | 182 // the config from the receiver. The goal is to avoid perceivable network |
| 186 // outage (when using the wrong config) but at the same time avoid | 183 // outage (when using the wrong config) but at the same time avoid |
| 187 // unnecessary Job aborts in HostResolverImpl. The signals come from multiple | 184 // unnecessary Job aborts in HostResolverImpl. The signals come from multiple |
| 188 // sources so it might receive multiple events during a config change. | 185 // sources so it might receive multiple events during a config change. |
| 189 | 186 |
| 190 // DHCP and user-induced changes are on the order of seconds, so 100ms should | 187 // DHCP and user-induced changes are on the order of seconds, so 100ms should |
| 191 // not add perceivable delay. On the other hand, config readers should finish | 188 // not add perceivable delay. On the other hand, config readers should finish |
| 192 // within 100ms with the rare exception of I/O block or extra large HOSTS. | 189 // within 100ms with the rare exception of I/O block or extra large HOSTS. |
| 193 const base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100); | 190 const base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100); |
| 194 | 191 |
| 195 timer_.Start(FROM_HERE, | 192 timer_.Start(FROM_HERE, |
| 196 kTimeout, | 193 kTimeout, |
| 197 this, | 194 this, |
| 198 &DnsConfigService::OnTimeout); | 195 &DnsConfigService::OnTimeout); |
| 199 } | 196 } |
| 200 | 197 |
| 201 void DnsConfigService::OnTimeout() { | 198 void DnsConfigService::OnTimeout() { |
| 202 DCHECK(CalledOnValidThread()); | 199 DCHECK(CalledOnValidThread()); |
| 203 DCHECK(!last_sent_empty_); | 200 DCHECK(!last_sent_empty_ || watch_failed_); |
| 204 // Indicate that even if there is no change in On*Read, we will need to | 201 // Indicate that even if there is no change in On*Read, we will need to |
| 205 // update the receiver when the config becomes complete. | 202 // update the receiver when the config becomes complete. |
| 206 need_update_ = true; | 203 need_update_ = true; |
| 207 // Empty config is considered invalid. | 204 // Empty config is considered invalid. |
| 208 last_sent_empty_ = true; | 205 last_sent_empty_ = true; |
| 209 last_sent_empty_time_ = base::TimeTicks::Now(); | 206 last_sent_empty_time_ = base::TimeTicks::Now(); |
| 210 callback_.Run(DnsConfig()); | 207 callback_.Run(DnsConfig()); |
| 211 } | 208 } |
| 212 | 209 |
| 213 void DnsConfigService::OnCompleteConfig() { | 210 void DnsConfigService::OnCompleteConfig() { |
| 211 if (watch_failed_) | |
| 212 return; // Let it time out. | |
|
mmenke
2012/08/31 15:05:59
Should we stop the timer if |needs_update_| is fal
szym
2012/08/31 15:55:57
I see. The idea is to not signal anything if we ha
mmenke
2012/08/31 16:04:03
I agree - think that this is the less confusing so
| |
| 214 timer_.Stop(); | 213 timer_.Stop(); |
| 215 if (!need_update_) | 214 if (!need_update_) |
| 216 return; | 215 return; |
| 217 need_update_ = false; | 216 need_update_ = false; |
| 218 last_sent_empty_ = false; | 217 last_sent_empty_ = false; |
| 219 callback_.Run(dns_config_); | 218 callback_.Run(dns_config_); |
| 220 } | 219 } |
| 221 | 220 |
| 222 } // namespace net | 221 } // namespace net |
| 223 | 222 |
| OLD | NEW |