| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/network_time/network_time_tracker.h" | 5 #include "components/network_time/network_time_tracker.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/feature_list.h" | 11 #include "base/feature_list.h" |
| 12 #include "base/i18n/time_formatting.h" | 12 #include "base/i18n/time_formatting.h" |
| 13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/metrics/sparse_histogram.h" |
| 16 #include "base/rand_util.h" | 18 #include "base/rand_util.h" |
| 17 #include "base/run_loop.h" | 19 #include "base/run_loop.h" |
| 18 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/time/tick_clock.h" | 22 #include "base/time/tick_clock.h" |
| 21 #include "build/build_config.h" | 23 #include "build/build_config.h" |
| 22 #include "components/client_update_protocol/ecdsa.h" | 24 #include "components/client_update_protocol/ecdsa.h" |
| 23 #include "components/network_time/network_time_pref_names.h" | 25 #include "components/network_time/network_time_pref_names.h" |
| 24 #include "components/prefs/pref_registry_simple.h" | 26 #include "components/prefs/pref_registry_simple.h" |
| 25 #include "components/prefs/pref_service.h" | 27 #include "components/prefs/pref_service.h" |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 double probability; | 161 double probability; |
| 160 const std::string param = variations::GetVariationParamValueByFeature( | 162 const std::string param = variations::GetVariationParamValueByFeature( |
| 161 kNetworkTimeServiceQuerying, kVariationsServiceRandomQueryProbability); | 163 kNetworkTimeServiceQuerying, kVariationsServiceRandomQueryProbability); |
| 162 if (!param.empty() && base::StringToDouble(param, &probability) && | 164 if (!param.empty() && base::StringToDouble(param, &probability) && |
| 163 probability >= 0.0 && probability <= 1.0) { | 165 probability >= 0.0 && probability <= 1.0) { |
| 164 return probability; | 166 return probability; |
| 165 } | 167 } |
| 166 return kRandomQueryProbability; | 168 return kRandomQueryProbability; |
| 167 } | 169 } |
| 168 | 170 |
| 171 void RecordFetchValidHistogram(bool valid) { |
| 172 UMA_HISTOGRAM_BOOLEAN("NetworkTimeTracker.UpdateTimeFetchValid", valid); |
| 173 } |
| 174 |
| 169 } // namespace | 175 } // namespace |
| 170 | 176 |
| 171 // static | 177 // static |
| 172 void NetworkTimeTracker::RegisterPrefs(PrefRegistrySimple* registry) { | 178 void NetworkTimeTracker::RegisterPrefs(PrefRegistrySimple* registry) { |
| 173 registry->RegisterDictionaryPref(prefs::kNetworkTimeMapping, | 179 registry->RegisterDictionaryPref(prefs::kNetworkTimeMapping, |
| 174 new base::DictionaryValue()); | 180 new base::DictionaryValue()); |
| 175 } | 181 } |
| 176 | 182 |
| 177 NetworkTimeTracker::NetworkTimeTracker( | 183 NetworkTimeTracker::NetworkTimeTracker( |
| 178 std::unique_ptr<base::Clock> clock, | 184 std::unique_ptr<base::Clock> clock, |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 time_fetcher_->SaveResponseWithWriter( | 366 time_fetcher_->SaveResponseWithWriter( |
| 361 std::unique_ptr<net::URLFetcherResponseWriter>( | 367 std::unique_ptr<net::URLFetcherResponseWriter>( |
| 362 new SizeLimitingStringWriter(max_response_size_))); | 368 new SizeLimitingStringWriter(max_response_size_))); |
| 363 DCHECK(getter_); | 369 DCHECK(getter_); |
| 364 time_fetcher_->SetRequestContext(getter_.get()); | 370 time_fetcher_->SetRequestContext(getter_.get()); |
| 365 // Not expecting any cookies, but just in case. | 371 // Not expecting any cookies, but just in case. |
| 366 time_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | | 372 time_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | |
| 367 net::LOAD_DO_NOT_SAVE_COOKIES | | 373 net::LOAD_DO_NOT_SAVE_COOKIES | |
| 368 net::LOAD_DO_NOT_SEND_COOKIES | | 374 net::LOAD_DO_NOT_SEND_COOKIES | |
| 369 net::LOAD_DO_NOT_SEND_AUTH_DATA); | 375 net::LOAD_DO_NOT_SEND_AUTH_DATA); |
| 376 |
| 377 UMA_HISTOGRAM_BOOLEAN("NetworkTimeTracker.UpdateTimeFetchAttempted", true); |
| 378 |
| 370 time_fetcher_->Start(); | 379 time_fetcher_->Start(); |
| 371 fetch_started_ = tick_clock_->NowTicks(); | 380 fetch_started_ = tick_clock_->NowTicks(); |
| 372 | 381 |
| 373 timer_.Stop(); // Restarted in OnURLFetchComplete(). | 382 timer_.Stop(); // Restarted in OnURLFetchComplete(). |
| 374 } | 383 } |
| 375 | 384 |
| 376 bool NetworkTimeTracker::UpdateTimeFromResponse() { | 385 bool NetworkTimeTracker::UpdateTimeFromResponse() { |
| 377 if (time_fetcher_->GetStatus().status() != net::URLRequestStatus::SUCCESS && | 386 if (time_fetcher_->GetStatus().status() != net::URLRequestStatus::SUCCESS || |
| 378 time_fetcher_->GetResponseCode() != 200) { | 387 time_fetcher_->GetResponseCode() != 200) { |
| 379 DVLOG(1) << "fetch failed, status=" << time_fetcher_->GetStatus().status() | 388 DVLOG(1) << "fetch failed, status=" << time_fetcher_->GetStatus().status() |
| 380 << ",code=" << time_fetcher_->GetResponseCode(); | 389 << ",code=" << time_fetcher_->GetResponseCode(); |
| 390 // The error code is negated because net errors are negative, but |
| 391 // the corresponding histogram enum is positive. |
| 392 UMA_HISTOGRAM_SPARSE_SLOWLY("NetworkTimeTracker.UpdateTimeFetchFailed", |
| 393 -time_fetcher_->GetStatus().error()); |
| 381 return false; | 394 return false; |
| 382 } | 395 } |
| 383 | 396 |
| 384 std::string response_body; | 397 std::string response_body; |
| 385 if (!time_fetcher_->GetResponseAsString(&response_body)) { | 398 if (!time_fetcher_->GetResponseAsString(&response_body)) { |
| 386 DVLOG(1) << "failed to get response"; | 399 DVLOG(1) << "failed to get response"; |
| 387 return false; | 400 return false; |
| 388 } | 401 } |
| 389 DCHECK(query_signer_); | 402 DCHECK(query_signer_); |
| 390 if (!query_signer_->ValidateResponse(response_body, | 403 if (!query_signer_->ValidateResponse(response_body, |
| 391 GetServerProof(time_fetcher_.get()))) { | 404 GetServerProof(time_fetcher_.get()))) { |
| 392 DVLOG(1) << "invalid signature"; | 405 DVLOG(1) << "invalid signature"; |
| 406 RecordFetchValidHistogram(false); |
| 393 return false; | 407 return false; |
| 394 } | 408 } |
| 395 response_body = response_body.substr(5); // Skips leading )]}'\n | 409 response_body = response_body.substr(5); // Skips leading )]}'\n |
| 396 std::unique_ptr<base::Value> value = base::JSONReader::Read(response_body); | 410 std::unique_ptr<base::Value> value = base::JSONReader::Read(response_body); |
| 397 if (!value) { | 411 if (!value) { |
| 398 DVLOG(1) << "bad JSON"; | 412 DVLOG(1) << "bad JSON"; |
| 413 RecordFetchValidHistogram(false); |
| 399 return false; | 414 return false; |
| 400 } | 415 } |
| 401 const base::DictionaryValue* dict; | 416 const base::DictionaryValue* dict; |
| 402 if (!value->GetAsDictionary(&dict)) { | 417 if (!value->GetAsDictionary(&dict)) { |
| 403 DVLOG(1) << "not a dictionary"; | 418 DVLOG(1) << "not a dictionary"; |
| 419 RecordFetchValidHistogram(false); |
| 404 return false; | 420 return false; |
| 405 } | 421 } |
| 406 double current_time_millis; | 422 double current_time_millis; |
| 407 if (!dict->GetDouble("current_time_millis", ¤t_time_millis)) { | 423 if (!dict->GetDouble("current_time_millis", ¤t_time_millis)) { |
| 408 DVLOG(1) << "no current_time_millis"; | 424 DVLOG(1) << "no current_time_millis"; |
| 425 RecordFetchValidHistogram(false); |
| 409 return false; | 426 return false; |
| 410 } | 427 } |
| 428 |
| 429 RecordFetchValidHistogram(true); |
| 430 |
| 411 // There is a "server_nonce" key here too, but it serves no purpose other than | 431 // There is a "server_nonce" key here too, but it serves no purpose other than |
| 412 // to make the server's response unpredictable. | 432 // to make the server's response unpredictable. |
| 413 base::Time current_time = base::Time::FromJsTime(current_time_millis); | 433 base::Time current_time = base::Time::FromJsTime(current_time_millis); |
| 414 base::TimeDelta resolution = | 434 base::TimeDelta resolution = |
| 415 base::TimeDelta::FromMilliseconds(1) + | 435 base::TimeDelta::FromMilliseconds(1) + |
| 416 base::TimeDelta::FromSeconds(kTimeServerMaxSkewSeconds); | 436 base::TimeDelta::FromSeconds(kTimeServerMaxSkewSeconds); |
| 417 base::TimeDelta latency = tick_clock_->NowTicks() - fetch_started_; | 437 base::TimeDelta latency = tick_clock_->NowTicks() - fetch_started_; |
| 418 UpdateNetworkTime(current_time, resolution, latency, tick_clock_->NowTicks()); | 438 UpdateNetworkTime(current_time, resolution, latency, tick_clock_->NowTicks()); |
| 419 return true; | 439 return true; |
| 420 } | 440 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 base::Time network_time; | 476 base::Time network_time; |
| 457 if (!GetNetworkTime(&network_time, nullptr)) { | 477 if (!GetNetworkTime(&network_time, nullptr)) { |
| 458 return true; | 478 return true; |
| 459 } | 479 } |
| 460 | 480 |
| 461 // Otherwise, make the decision at random. | 481 // Otherwise, make the decision at random. |
| 462 return base::RandDouble() < RandomQueryProbability(); | 482 return base::RandDouble() < RandomQueryProbability(); |
| 463 } | 483 } |
| 464 | 484 |
| 465 } // namespace network_time | 485 } // namespace network_time |
| OLD | NEW |