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