| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #include "chrome/browser/safe_browsing/certificate_reporting_service.h" | 4 #include "chrome/browser/safe_browsing/certificate_reporting_service.h" |
| 5 | 5 |
| 6 #include "base/bind_helpers.h" | 6 #include "base/bind_helpers.h" |
| 7 #include "base/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.h" |
| 8 #include "base/metrics/sparse_histogram.h" | 8 #include "base/metrics/sparse_histogram.h" |
| 9 #include "base/time/clock.h" | 9 #include "base/time/clock.h" |
| 10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 const CertificateReportingService::Report& item2) { | 30 const CertificateReportingService::Report& item2) { |
| 31 return item1.creation_time > item2.creation_time; | 31 return item1.creation_time > item2.creation_time; |
| 32 } | 32 } |
| 33 | 33 |
| 34 // Records an UMA histogram of the net errors when certificate reports | 34 // Records an UMA histogram of the net errors when certificate reports |
| 35 // fail to send. | 35 // fail to send. |
| 36 void RecordUMAOnFailure(int net_error) { | 36 void RecordUMAOnFailure(int net_error) { |
| 37 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error); | 37 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error); |
| 38 } | 38 } |
| 39 | 39 |
| 40 void RecordUMAEvent(CertificateReportingService::ReportOutcome outcome) { | |
| 41 UMA_HISTOGRAM_ENUMERATION(CertificateReportingService::kReportEventHistogram, | |
| 42 outcome, | |
| 43 CertificateReportingService::REPORT_EVENT_COUNT); | |
| 44 } | |
| 45 | |
| 46 void CleanupOnIOThread( | 40 void CleanupOnIOThread( |
| 47 std::unique_ptr<CertificateReportingService::Reporter> reporter) { | 41 std::unique_ptr<CertificateReportingService::Reporter> reporter) { |
| 48 reporter.reset(); | 42 reporter.reset(); |
| 49 } | 43 } |
| 50 | 44 |
| 51 } // namespace | 45 } // namespace |
| 52 | 46 |
| 53 const char CertificateReportingService::kReportEventHistogram[] = | |
| 54 "SSL.CertificateErrorReportEvent"; | |
| 55 | |
| 56 CertificateReportingService::BoundedReportList::BoundedReportList( | 47 CertificateReportingService::BoundedReportList::BoundedReportList( |
| 57 size_t max_size) | 48 size_t max_size) |
| 58 : max_size_(max_size) { | 49 : max_size_(max_size) { |
| 59 CHECK(max_size <= 20) | 50 CHECK(max_size <= 20) |
| 60 << "Current implementation is not efficient for a large list."; | 51 << "Current implementation is not efficient for a large list."; |
| 61 DCHECK(thread_checker_.CalledOnValidThread()); | 52 DCHECK(thread_checker_.CalledOnValidThread()); |
| 62 } | 53 } |
| 63 | 54 |
| 64 CertificateReportingService::BoundedReportList::~BoundedReportList() {} | 55 CertificateReportingService::BoundedReportList::~BoundedReportList() {} |
| 65 | 56 |
| 66 void CertificateReportingService::BoundedReportList::Add(const Report& item) { | 57 void CertificateReportingService::BoundedReportList::Add(const Report& item) { |
| 67 DCHECK(thread_checker_.CalledOnValidThread()); | 58 DCHECK(thread_checker_.CalledOnValidThread()); |
| 68 DCHECK(items_.size() <= max_size_); | 59 DCHECK(items_.size() <= max_size_); |
| 69 if (items_.size() == max_size_) { | 60 if (items_.size() == max_size_) { |
| 70 const Report& last = items_.back(); | 61 const Report& last = items_.back(); |
| 71 if (item.creation_time <= last.creation_time) { | 62 if (item.creation_time <= last.creation_time) { |
| 72 // Report older than the oldest item in the queue, ignore. | 63 // Report older than the oldest item in the queue, ignore. |
| 73 RecordUMAEvent(REPORT_DROPPED_OR_IGNORED); | |
| 74 return; | 64 return; |
| 75 } | 65 } |
| 76 // Reached the maximum item count, remove the oldest item. | 66 // Reached the maximum item count, remove the oldest item. |
| 77 items_.pop_back(); | 67 items_.pop_back(); |
| 78 RecordUMAEvent(REPORT_DROPPED_OR_IGNORED); | |
| 79 } | 68 } |
| 80 items_.push_back(item); | 69 items_.push_back(item); |
| 81 std::sort(items_.begin(), items_.end(), ReportCompareFunc); | 70 std::sort(items_.begin(), items_.end(), ReportCompareFunc); |
| 82 } | 71 } |
| 83 | 72 |
| 84 void CertificateReportingService::BoundedReportList::Clear() { | 73 void CertificateReportingService::BoundedReportList::Clear() { |
| 85 items_.clear(); | 74 items_.clear(); |
| 86 } | 75 } |
| 87 | 76 |
| 88 const std::vector<CertificateReportingService::Report>& | 77 const std::vector<CertificateReportingService::Report>& |
| (...skipping 29 matching lines...) Expand all Loading... |
| 118 if (!retries_enabled_) { | 107 if (!retries_enabled_) { |
| 119 return; | 108 return; |
| 120 } | 109 } |
| 121 const base::Time now = clock_->Now(); | 110 const base::Time now = clock_->Now(); |
| 122 // Copy pending reports and clear the retry list. | 111 // Copy pending reports and clear the retry list. |
| 123 std::vector<Report> items = retry_list_->items(); | 112 std::vector<Report> items = retry_list_->items(); |
| 124 retry_list_->Clear(); | 113 retry_list_->Clear(); |
| 125 for (Report& report : items) { | 114 for (Report& report : items) { |
| 126 if (report.creation_time < now - report_ttl_) { | 115 if (report.creation_time < now - report_ttl_) { |
| 127 // Report too old, ignore. | 116 // Report too old, ignore. |
| 128 RecordUMAEvent(REPORT_DROPPED_OR_IGNORED); | |
| 129 continue; | 117 continue; |
| 130 } | 118 } |
| 131 if (!report.is_retried) { | 119 if (!report.is_retried) { |
| 132 // If this is the first retry, deserialize the report, set its retry bit | 120 // If this is the first retry, deserialize the report, set its retry bit |
| 133 // and serialize again. | 121 // and serialize again. |
| 134 certificate_reporting::ErrorReport error_report; | 122 certificate_reporting::ErrorReport error_report; |
| 135 CHECK(error_report.InitializeFromString(report.serialized_report)); | 123 CHECK(error_report.InitializeFromString(report.serialized_report)); |
| 136 error_report.SetIsRetryUpload(true); | 124 error_report.SetIsRetryUpload(true); |
| 137 CHECK(error_report.Serialize(&report.serialized_report)); | 125 CHECK(error_report.Serialize(&report.serialized_report)); |
| 138 } | 126 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 149 | 137 |
| 150 CertificateReportingService::BoundedReportList* | 138 CertificateReportingService::BoundedReportList* |
| 151 CertificateReportingService::Reporter::GetQueueForTesting() const { | 139 CertificateReportingService::Reporter::GetQueueForTesting() const { |
| 152 return retry_list_.get(); | 140 return retry_list_.get(); |
| 153 } | 141 } |
| 154 | 142 |
| 155 void CertificateReportingService::Reporter::SendInternal( | 143 void CertificateReportingService::Reporter::SendInternal( |
| 156 const CertificateReportingService::Report& report) { | 144 const CertificateReportingService::Report& report) { |
| 157 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 145 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 158 inflight_reports_.insert(std::make_pair(report.report_id, report)); | 146 inflight_reports_.insert(std::make_pair(report.report_id, report)); |
| 159 RecordUMAEvent(REPORT_SUBMITTED); | |
| 160 error_reporter_->SendExtendedReportingReport( | 147 error_reporter_->SendExtendedReportingReport( |
| 161 report.serialized_report, | 148 report.serialized_report, |
| 162 base::Bind(&CertificateReportingService::Reporter::SuccessCallback, | 149 base::Bind(&CertificateReportingService::Reporter::SuccessCallback, |
| 163 weak_factory_.GetWeakPtr(), report.report_id), | 150 weak_factory_.GetWeakPtr(), report.report_id), |
| 164 base::Bind(&CertificateReportingService::Reporter::ErrorCallback, | 151 base::Bind(&CertificateReportingService::Reporter::ErrorCallback, |
| 165 weak_factory_.GetWeakPtr(), report.report_id)); | 152 weak_factory_.GetWeakPtr(), report.report_id)); |
| 166 } | 153 } |
| 167 | 154 |
| 168 void CertificateReportingService::Reporter::ErrorCallback( | 155 void CertificateReportingService::Reporter::ErrorCallback( |
| 169 int report_id, | 156 int report_id, |
| 170 const GURL& url, | 157 const GURL& url, |
| 171 int net_error, | 158 int net_error, |
| 172 int http_response_code) { | 159 int http_response_code) { |
| 173 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 160 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 174 RecordUMAOnFailure(net_error); | 161 RecordUMAOnFailure(net_error); |
| 175 RecordUMAEvent(REPORT_FAILED); | |
| 176 if (retries_enabled_) { | 162 if (retries_enabled_) { |
| 177 auto it = inflight_reports_.find(report_id); | 163 auto it = inflight_reports_.find(report_id); |
| 178 DCHECK(it != inflight_reports_.end()); | 164 DCHECK(it != inflight_reports_.end()); |
| 179 retry_list_->Add(it->second); | 165 retry_list_->Add(it->second); |
| 180 } | 166 } |
| 181 CHECK_GT(inflight_reports_.erase(report_id), 0u); | 167 CHECK_GT(inflight_reports_.erase(report_id), 0u); |
| 182 } | 168 } |
| 183 | 169 |
| 184 void CertificateReportingService::Reporter::SuccessCallback(int report_id) { | 170 void CertificateReportingService::Reporter::SuccessCallback(int report_id) { |
| 185 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 171 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 186 RecordUMAEvent(REPORT_SUCCESSFUL); | |
| 187 CHECK_GT(inflight_reports_.erase(report_id), 0u); | 172 CHECK_GT(inflight_reports_.erase(report_id), 0u); |
| 188 } | 173 } |
| 189 | 174 |
| 190 CertificateReportingService::CertificateReportingService( | 175 CertificateReportingService::CertificateReportingService( |
| 191 safe_browsing::SafeBrowsingService* safe_browsing_service, | 176 safe_browsing::SafeBrowsingService* safe_browsing_service, |
| 192 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, | 177 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, |
| 193 Profile* profile, | 178 Profile* profile, |
| 194 uint8_t server_public_key[/* 32 */], | 179 uint8_t server_public_key[/* 32 */], |
| 195 uint32_t server_public_key_version, | 180 uint32_t server_public_key_version, |
| 196 size_t max_queued_report_count, | 181 size_t max_queued_report_count, |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 } | 322 } |
| 338 | 323 |
| 339 void CertificateReportingService::OnPreferenceChanged() { | 324 void CertificateReportingService::OnPreferenceChanged() { |
| 340 safe_browsing::SafeBrowsingService* safe_browsing_service_ = | 325 safe_browsing::SafeBrowsingService* safe_browsing_service_ = |
| 341 g_browser_process->safe_browsing_service(); | 326 g_browser_process->safe_browsing_service(); |
| 342 const bool enabled = safe_browsing_service_ && | 327 const bool enabled = safe_browsing_service_ && |
| 343 safe_browsing_service_->enabled_by_prefs() && | 328 safe_browsing_service_->enabled_by_prefs() && |
| 344 safe_browsing::IsExtendedReportingEnabled(pref_service_); | 329 safe_browsing::IsExtendedReportingEnabled(pref_service_); |
| 345 SetEnabled(enabled); | 330 SetEnabled(enabled); |
| 346 } | 331 } |
| OLD | NEW |