1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.h"
6
7 #include <list>
8 #include <map>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "base/feature_list.h"
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/functional/bind.h"
18 #include "base/functional/callback_helpers.h"
19 #include "base/json/json_reader.h"
20 #include "base/json/json_string_value_serializer.h"
21 #include "base/metrics/histogram_macros.h"
22 #include "base/task/sequenced_task_runner.h"
23 #include "base/task/task_traits.h"
24 #include "base/thread_annotations.h"
25 #include "net/base/features.h"
26 #include "net/base/network_anonymization_key.h"
27 #include "net/extras/sqlite/sqlite_persistent_store_backend_base.h"
28 #include "net/reporting/reporting_endpoint.h"
29 #include "sql/database.h"
30 #include "sql/meta_table.h"
31 #include "sql/statement.h"
32 #include "sql/transaction.h"
33 #include "url/origin.h"
34
35 namespace net {
36
37 namespace {
38 // Version 1 - 2019/03 - crrev.com/c/1504493, crrev.com/c/1560456
39 //
40 // Version 1 adds tables for NEL policies, Reporting endpoints, and Reporting
41 // endpoint groups.
42 //
43 // Version 2 - 2020/10 - https://crrev.com/c/2485253
44 //
45 // Version 2 adds NetworkAnonymizationKey fields to all entries. When migrating,
46 // existing entries get an empty NetworkAnonymizationKey value.
47 const int kCurrentVersionNumber = 2;
48 const int kCompatibleVersionNumber = 2;
49
50 // Histogram names
51 const char kNumberOfLoadedNelPoliciesHistogramName[] =
52 "ReportingAndNEL.NumberOfLoadedNELPolicies";
53 const char kNumberOfLoadedNelPolicies2HistogramName[] =
54 "ReportingAndNEL.NumberOfLoadedNELPolicies2";
55 const char kNumberOfLoadedReportingEndpoints2HistogramName[] =
56 "ReportingAndNEL.NumberOfLoadedReportingEndpoints2";
57 const char kNumberOfLoadedReportingEndpointGroups2HistogramName[] =
58 "ReportingAndNEL.NumberOfLoadedReportingEndpointGroups2";
59 } // namespace
60
GetReportingAndNelStoreBackgroundSequencePriority()61 base::TaskPriority GetReportingAndNelStoreBackgroundSequencePriority() {
62 return base::TaskPriority::USER_BLOCKING;
63 }
64
65 // Converts a NetworkAnonymizationKey to a string for serializing to disk.
66 // Returns false on failure, which happens for transient keys that should not be
67 // serialized to disk.
NetworkAnonymizationKeyToString(const NetworkAnonymizationKey & network_anonymization_key,std::string * out_string)68 [[nodiscard]] bool NetworkAnonymizationKeyToString(
69 const NetworkAnonymizationKey& network_anonymization_key,
70 std::string* out_string) {
71 base::Value value;
72 if (!network_anonymization_key.ToValue(&value))
73 return false;
74 return JSONStringValueSerializer(out_string).Serialize(value);
75 }
76
77 // Attempts to convert a string returned by NetworkAnonymizationKeyToString() to
78 // a NetworkAnonymizationKey. Returns false on failure.
NetworkAnonymizationKeyFromString(const std::string & string,NetworkAnonymizationKey * out_network_anonymization_key)79 [[nodiscard]] bool NetworkAnonymizationKeyFromString(
80 const std::string& string,
81 NetworkAnonymizationKey* out_network_anonymization_key) {
82 absl::optional<base::Value> value = base::JSONReader::Read(string);
83 if (!value)
84 return false;
85
86 if (!NetworkAnonymizationKey::FromValue(*value,
87 out_network_anonymization_key))
88 return false;
89
90 // If network state partitionining is disabled, but the
91 // NetworkAnonymizationKeys is non-empty, ignore the entry. The entry will
92 // still be in the on-disk database, in case NAKs are re-enabled, it just
93 // won't be loaded into memory. The entry could still be loaded with an empty
94 // NetworkAnonymizationKey, but that would require logic to resolve conflicts.
95 if (!out_network_anonymization_key->IsEmpty() &&
96 !NetworkAnonymizationKey::IsPartitioningEnabled()) {
97 *out_network_anonymization_key = NetworkAnonymizationKey();
98 return false;
99 }
100
101 return true;
102 }
103
104 class SQLitePersistentReportingAndNelStore::Backend
105 : public SQLitePersistentStoreBackendBase {
106 public:
Backend(const base::FilePath & path,const scoped_refptr<base::SequencedTaskRunner> & client_task_runner,const scoped_refptr<base::SequencedTaskRunner> & background_task_runner)107 Backend(
108 const base::FilePath& path,
109 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
110 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner)
111 : SQLitePersistentStoreBackendBase(
112 path,
113 /* histogram_tag = */ "ReportingAndNEL",
114 kCurrentVersionNumber,
115 kCompatibleVersionNumber,
116 background_task_runner,
117 client_task_runner,
118 /*enable_exclusive_access=*/false) {}
119
120 Backend(const Backend&) = delete;
121 Backend& operator=(const Backend&) = delete;
122
123 void LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback);
124 void AddNelPolicy(const NetworkErrorLoggingService::NelPolicy& policy);
125 void UpdateNelPolicyAccessTime(
126 const NetworkErrorLoggingService::NelPolicy& policy);
127 void DeleteNelPolicy(const NetworkErrorLoggingService::NelPolicy& policy);
128
129 void LoadReportingClients(ReportingClientsLoadedCallback loaded_callback);
130 void AddReportingEndpoint(const ReportingEndpoint& endpoint);
131 void AddReportingEndpointGroup(const CachedReportingEndpointGroup& group);
132 void UpdateReportingEndpointGroupAccessTime(
133 const CachedReportingEndpointGroup& group);
134 void UpdateReportingEndpointDetails(const ReportingEndpoint& endpoint);
135 void UpdateReportingEndpointGroupDetails(
136 const CachedReportingEndpointGroup& group);
137 void DeleteReportingEndpoint(const ReportingEndpoint& endpoint);
138 void DeleteReportingEndpointGroup(const CachedReportingEndpointGroup& group);
139
140 // Gets the number of queued operations.
141 size_t GetQueueLengthForTesting() const;
142
143 private:
~Backend()144 ~Backend() override {
145 DCHECK(nel_policy_pending_ops_.empty());
146 DCHECK(reporting_endpoint_pending_ops_.empty());
147 DCHECK(reporting_endpoint_group_pending_ops_.empty());
148 DCHECK_EQ(0u, num_pending_);
149 }
150
151 // Represents a mutating operation to the database, specified by a type (add,
152 // update access time, update data, or delete) and data representing the entry
153 // in the database to be added/updated/deleted.
154 template <typename DataType>
155 class PendingOperation;
156
157 // Types of PendingOperation. Here to avoid templatizing the enum.
158 enum class PendingOperationType {
159 ADD,
160 UPDATE_ACCESS_TIME,
161 UPDATE_DETAILS,
162 DELETE
163 };
164
165 // List of pending operations for a particular entry in the database.
166 template <typename DataType>
167 using PendingOperationsVector =
168 std::vector<std::unique_ptr<PendingOperation<DataType>>>;
169
170 // A copy of the information relevant to a NEL policy.
171 struct NelPolicyInfo;
172 // A copy of the information relevant to a Reporting endpoint.
173 struct ReportingEndpointInfo;
174 // A copy of the information relevant to a Reporting endpoint group.
175 struct ReportingEndpointGroupInfo;
176 // TODO(chlily): add ReportingReportInfo.
177
178 // Uniquely identifies an endpoint in the store.
179 using ReportingEndpointKey = std::pair<ReportingEndpointGroupKey, GURL>;
180
181 // Map of pending operations for each entry in the database.
182 // Key types are: - url::Origin for NEL policies,
183 // - ReportingEndpointKey for Reporting endpoints,
184 // - ReportingEndpointGroupKey for Reporting endpoint groups
185 // (defined in //net/reporting/reporting_endpoint.h).
186 template <typename KeyType, typename DataType>
187 using QueueType = std::map<KeyType, PendingOperationsVector<DataType>>;
188
189 // SQLitePersistentStoreBackendBase implementation
190 bool CreateDatabaseSchema() override;
191 absl::optional<int> DoMigrateDatabaseSchema() override;
192 void DoCommit() override;
193
194 // Commit a pending operation pertaining to a NEL policy.
195 // Returns true on success.
196 bool CommitNelPolicyOperation(PendingOperation<NelPolicyInfo>* op);
197 // Commit a pending operation pertaining to a Reporting endpoint.
198 // Returns true on success.
199 bool CommitReportingEndpointOperation(
200 PendingOperation<ReportingEndpointInfo>* op);
201 // Commit a pending operation pertaining to a Reporting endpoint group.
202 // Returns true on success.
203 bool CommitReportingEndpointGroupOperation(
204 PendingOperation<ReportingEndpointGroupInfo>* op);
205
206 // Add a pending operation to the appropriate queue.
207 template <typename KeyType, typename DataType>
208 void BatchOperation(KeyType key,
209 std::unique_ptr<PendingOperation<DataType>> po,
210 QueueType<KeyType, DataType>* queue);
211
212 // If there are existing pending operations for a given key, potentially
213 // remove some of the existing operations before adding |new_op|.
214 // In particular, if |new_op| is a deletion, then all the previous pending
215 // operations are made irrelevant and can be deleted. If |new_op| is an
216 // update-access-time, and the last operation in |ops_for_key| is also an
217 // update-access-time, then it can be discarded because |new_op| is about to
218 // overwrite the access time with a new value anyway. Similarly for
219 // update-details.
220 template <typename DataType>
221 void MaybeCoalesceOperations(PendingOperationsVector<DataType>* ops_for_key,
222 PendingOperation<DataType>* new_op)
223 EXCLUSIVE_LOCKS_REQUIRED(lock_);
224
225 // After adding a pending operation to one of the pending operations queues,
226 // this method posts a task to commit all pending operations if we reached the
227 // batch size, or starts a timer to commit after a time interval if we just
228 // started a new batch. |num_pending| is the total number of pending
229 // operations after the one we just added.
230 void OnOperationBatched(size_t num_pending);
231
232 // Loads NEL policies into a vector in the background, then posts a
233 // task to the client task runner to call |loaded_callback| with the loaded
234 // NEL policies.
235 void LoadNelPoliciesAndNotifyInBackground(
236 NelPoliciesLoadedCallback loaded_callback);
237
238 // Calls |loaded_callback| with the loaded NEL policies (which may be empty if
239 // loading was unsuccessful). If loading was successful, also report metrics.
240 void CompleteLoadNelPoliciesAndNotifyInForeground(
241 NelPoliciesLoadedCallback loaded_callback,
242 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies,
243 bool load_success);
244
245 // Loads Reporting endpoints and endpoint groups into two vectors in the
246 // background, then posts a task to the client task runner to call
247 // |loaded_callback| with the loaded endpoints and endpoint groups.
248 void LoadReportingClientsAndNotifyInBackground(
249 ReportingClientsLoadedCallback loaded_callback);
250
251 // Calls |loaded_callback| with the loaded endpoints and endpoint groups
252 // (which may be empty if loading was unsuccessful). If loading was
253 // successful, also report metrics.
254 void CompleteLoadReportingClientsAndNotifyInForeground(
255 ReportingClientsLoadedCallback loaded_callback,
256 std::vector<ReportingEndpoint> loaded_endpoints,
257 std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups,
258 bool load_success);
259
260 void RecordNumberOfLoadedNelPolicies(size_t count);
261 void RecordNumberOfLoadedReportingEndpoints(size_t count);
262 void RecordNumberOfLoadedReportingEndpointGroups(size_t count);
263
264 // Total number of pending operations (may not match the sum of the number of
265 // elements in the pending operations queues, due to operation coalescing).
266 size_t num_pending_ GUARDED_BY(lock_) = 0;
267
268 // Queue of pending operations pertaining to NEL policies, keyed on origin.
269 QueueType<NetworkErrorLoggingService::NelPolicyKey, NelPolicyInfo>
270 nel_policy_pending_ops_ GUARDED_BY(lock_);
271 // Queue of pending operations pertaining to Reporting endpoints, keyed on
272 // origin, group name, and url.
273 QueueType<ReportingEndpointKey, ReportingEndpointInfo>
274 reporting_endpoint_pending_ops_ GUARDED_BY(lock_);
275 // Queue of pending operations pertaining to Reporting endpoint groups, keyed
276 // on origin and group name.
277 QueueType<ReportingEndpointGroupKey, ReportingEndpointGroupInfo>
278 reporting_endpoint_group_pending_ops_ GUARDED_BY(lock_);
279
280 // TODO(chlily): add reporting_report_pending_ops_ for Reporting reports.
281
282 // Protects |num_pending_|, and all the pending operations queues.
283 mutable base::Lock lock_;
284 };
285
286 namespace {
287
CreateV2NelPoliciesSchema(sql::Database * db)288 bool CreateV2NelPoliciesSchema(sql::Database* db) {
289 DCHECK(!db->DoesTableExist("nel_policies"));
290
291 std::string stmt =
292 "CREATE TABLE nel_policies ("
293 " nik TEXT NOT NULL,"
294 " origin_scheme TEXT NOT NULL,"
295 " origin_host TEXT NOT NULL,"
296 " origin_port INTEGER NOT NULL,"
297 " received_ip_address TEXT NOT NULL,"
298 " group_name TEXT NOT NULL,"
299 " expires_us_since_epoch INTEGER NOT NULL,"
300 " success_fraction REAL NOT NULL,"
301 " failure_fraction REAL NOT NULL,"
302 " is_include_subdomains INTEGER NOT NULL,"
303 " last_access_us_since_epoch INTEGER NOT NULL,"
304 // Each (origin, nik) specifies at most one NEL policy.
305 " UNIQUE (origin_scheme, origin_host, origin_port, nik)"
306 ")";
307
308 return db->Execute(stmt.c_str());
309 }
310
CreateV2ReportingEndpointsSchema(sql::Database * db)311 bool CreateV2ReportingEndpointsSchema(sql::Database* db) {
312 DCHECK(!db->DoesTableExist("reporting_endpoints"));
313
314 std::string stmt =
315 "CREATE TABLE reporting_endpoints ("
316 " nik TEXT NOT NULL,"
317 " origin_scheme TEXT NOT NULL,"
318 " origin_host TEXT NOT NULL,"
319 " origin_port INTEGER NOT NULL,"
320 " group_name TEXT NOT NULL,"
321 " url TEXT NOT NULL,"
322 " priority INTEGER NOT NULL,"
323 " weight INTEGER NOT NULL,"
324 // Each (origin, group, url, nik) tuple specifies at most one endpoint.
325 " UNIQUE (origin_scheme, origin_host, origin_port, group_name, url, nik)"
326 ")";
327
328 return db->Execute(stmt.c_str());
329 }
330
CreateV2ReportingEndpointGroupsSchema(sql::Database * db)331 bool CreateV2ReportingEndpointGroupsSchema(sql::Database* db) {
332 DCHECK(!db->DoesTableExist("reporting_endpoint_groups"));
333
334 std::string stmt =
335 "CREATE TABLE reporting_endpoint_groups ("
336 " nik TEXT NOT NULL,"
337 " origin_scheme TEXT NOT NULL,"
338 " origin_host TEXT NOT NULL,"
339 " origin_port INTEGER NOT NULL,"
340 " group_name TEXT NOT NULL,"
341 " is_include_subdomains INTEGER NOT NULL,"
342 " expires_us_since_epoch INTEGER NOT NULL,"
343 " last_access_us_since_epoch INTEGER NOT NULL,"
344 // Each (origin, group, nik) tuple specifies at most one endpoint group.
345 " UNIQUE (origin_scheme, origin_host, origin_port, group_name, nik)"
346 ")";
347
348 return db->Execute(stmt.c_str());
349 }
350
351 } // namespace
352
353 template <typename DataType>
354 class SQLitePersistentReportingAndNelStore::Backend::PendingOperation {
355 public:
PendingOperation(PendingOperationType type,DataType data)356 PendingOperation(PendingOperationType type, DataType data)
357 : type_(type), data_(std::move(data)) {}
358
type() const359 PendingOperationType type() const { return type_; }
data() const360 const DataType& data() const { return data_; }
361
362 private:
363 const PendingOperationType type_;
364 const DataType data_;
365 };
366
367 // Makes a copy of the relevant information about a NelPolicy, stored in a
368 // form suitable for adding to the database.
369 // TODO(chlily): Add NIK.
370 struct SQLitePersistentReportingAndNelStore::Backend::NelPolicyInfo {
371 // This should only be invoked through CreatePendingOperation().
NelPolicyInfonet::SQLitePersistentReportingAndNelStore::Backend::NelPolicyInfo372 NelPolicyInfo(const NetworkErrorLoggingService::NelPolicy& nel_policy,
373 std::string network_anonymization_key_string)
374 : network_anonymization_key_string(
375 std::move(network_anonymization_key_string)),
376 origin_scheme(nel_policy.key.origin.scheme()),
377 origin_host(nel_policy.key.origin.host()),
378 origin_port(nel_policy.key.origin.port()),
379 received_ip_address(nel_policy.received_ip_address.ToString()),
380 report_to(nel_policy.report_to),
381 expires_us_since_epoch(
382 nel_policy.expires.ToDeltaSinceWindowsEpoch().InMicroseconds()),
383 success_fraction(nel_policy.success_fraction),
384 failure_fraction(nel_policy.failure_fraction),
385 is_include_subdomains(nel_policy.include_subdomains),
386 last_access_us_since_epoch(
387 nel_policy.last_used.ToDeltaSinceWindowsEpoch().InMicroseconds()) {}
388
389 // Creates the specified operation for the given policy. Returns nullptr for
390 // endpoints with transient NetworkAnonymizationKeys.
391 static std::unique_ptr<PendingOperation<NelPolicyInfo>>
CreatePendingOperationnet::SQLitePersistentReportingAndNelStore::Backend::NelPolicyInfo392 CreatePendingOperation(
393 PendingOperationType type,
394 const NetworkErrorLoggingService::NelPolicy& nel_policy) {
395 std::string network_anonymization_key_string;
396 if (!NetworkAnonymizationKeyToString(
397 nel_policy.key.network_anonymization_key,
398 &network_anonymization_key_string)) {
399 return nullptr;
400 }
401
402 return std::make_unique<PendingOperation<NelPolicyInfo>>(
403 type,
404 NelPolicyInfo(nel_policy, std::move(network_anonymization_key_string)));
405 }
406
407 // NetworkAnonymizationKey associated with the request that received the
408 // policy, converted to a string via NetworkAnonymizationKeyToString().
409 std::string network_anonymization_key_string;
410
411 // Origin the policy was received from.
412 std::string origin_scheme;
413 std::string origin_host;
414 int origin_port = 0;
415
416 // IP address of the server that the policy was received from.
417 std::string received_ip_address;
418 // The Reporting group which the policy specifies.
419 std::string report_to;
420 // When the policy expires, in microseconds since the Windows epoch.
421 int64_t expires_us_since_epoch = 0;
422 // Sampling fractions.
423 double success_fraction = 0.0;
424 double failure_fraction = 1.0;
425 // Whether the policy applies to subdomains of the origin.
426 bool is_include_subdomains = false;
427 // Last time the policy was updated or used, in microseconds since the
428 // Windows epoch.
429 int64_t last_access_us_since_epoch = 0;
430 };
431
432 // Makes a copy of the relevant information about a ReportingEndpoint, stored in
433 // a form suitable for adding to the database.
434 struct SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointInfo {
435 // This should only be invoked through CreatePendingOperation().
ReportingEndpointInfonet::SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointInfo436 ReportingEndpointInfo(const ReportingEndpoint& endpoint,
437 std::string network_anonymization_key_string)
438 : network_anonymization_key_string(
439 std::move(network_anonymization_key_string)),
440 origin_scheme(endpoint.group_key.origin.scheme()),
441 origin_host(endpoint.group_key.origin.host()),
442 origin_port(endpoint.group_key.origin.port()),
443 group_name(endpoint.group_key.group_name),
444 url(endpoint.info.url.spec()),
445 priority(endpoint.info.priority),
446 weight(endpoint.info.weight) {}
447
448 // Creates the specified operation for the given endpoint. Returns nullptr for
449 // endpoints with transient NetworkAnonymizationKeys.
450 static std::unique_ptr<PendingOperation<ReportingEndpointInfo>>
CreatePendingOperationnet::SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointInfo451 CreatePendingOperation(PendingOperationType type,
452 const ReportingEndpoint& endpoint) {
453 std::string network_anonymization_key_string;
454 if (!NetworkAnonymizationKeyToString(
455 endpoint.group_key.network_anonymization_key,
456 &network_anonymization_key_string)) {
457 return nullptr;
458 }
459
460 return std::make_unique<PendingOperation<ReportingEndpointInfo>>(
461 type, ReportingEndpointInfo(
462 endpoint, std::move(network_anonymization_key_string)));
463 }
464
465 // NetworkAnonymizationKey associated with the endpoint, converted to a string
466 // via NetworkAnonymizationKeyString().
467 std::string network_anonymization_key_string;
468
469 // Origin the endpoint was received from.
470 std::string origin_scheme;
471 std::string origin_host;
472 int origin_port = 0;
473
474 // Name of the group the endpoint belongs to.
475 std::string group_name;
476 // URL of the endpoint.
477 std::string url;
478 // Priority of the endpoint.
479 int priority = ReportingEndpoint::EndpointInfo::kDefaultPriority;
480 // Weight of the endpoint.
481 int weight = ReportingEndpoint::EndpointInfo::kDefaultWeight;
482 };
483
484 struct SQLitePersistentReportingAndNelStore::Backend::
485 ReportingEndpointGroupInfo {
ReportingEndpointGroupInfonet::SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointGroupInfo486 ReportingEndpointGroupInfo(const CachedReportingEndpointGroup& group,
487 std::string network_anonymization_key_string)
488 : network_anonymization_key_string(
489 std::move(network_anonymization_key_string)),
490 origin_scheme(group.group_key.origin.scheme()),
491 origin_host(group.group_key.origin.host()),
492 origin_port(group.group_key.origin.port()),
493 group_name(group.group_key.group_name),
494 is_include_subdomains(group.include_subdomains ==
495 OriginSubdomains::INCLUDE),
496 expires_us_since_epoch(
497 group.expires.ToDeltaSinceWindowsEpoch().InMicroseconds()),
498 last_access_us_since_epoch(
499 group.last_used.ToDeltaSinceWindowsEpoch().InMicroseconds()) {}
500
501 // Creates the specified operation for the given endpoint reporting group.
502 // Returns nullptr for groups with transient NetworkAnonymizationKeys.
503 static std::unique_ptr<PendingOperation<ReportingEndpointGroupInfo>>
CreatePendingOperationnet::SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointGroupInfo504 CreatePendingOperation(PendingOperationType type,
505 const CachedReportingEndpointGroup& group) {
506 std::string network_anonymization_key_string;
507 if (!NetworkAnonymizationKeyToString(
508 group.group_key.network_anonymization_key,
509 &network_anonymization_key_string)) {
510 return nullptr;
511 }
512
513 return std::make_unique<PendingOperation<ReportingEndpointGroupInfo>>(
514 type, ReportingEndpointGroupInfo(
515 group, std::move(network_anonymization_key_string)));
516 }
517
518 // NetworkAnonymizationKey associated with the endpoint group, converted to a
519 // string via NetworkAnonymizationKeyToString().
520 std::string network_anonymization_key_string;
521
522 // Origin the endpoint group was received from.
523 std::string origin_scheme;
524 std::string origin_host;
525 int origin_port = 0;
526
527 // Name of the group.
528 std::string group_name;
529 // Whether the group applies to subdomains of the origin.
530 bool is_include_subdomains = false;
531 // When the group expires, in microseconds since the Windows epoch.
532 int64_t expires_us_since_epoch = 0;
533 // Last time the group was updated or used, in microseconds since the Windows
534 // epoch.
535 int64_t last_access_us_since_epoch = 0;
536 };
537
LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback)538 void SQLitePersistentReportingAndNelStore::Backend::LoadNelPolicies(
539 NelPoliciesLoadedCallback loaded_callback) {
540 PostBackgroundTask(
541 FROM_HERE, base::BindOnce(&Backend::LoadNelPoliciesAndNotifyInBackground,
542 this, std::move(loaded_callback)));
543 }
544
AddNelPolicy(const NetworkErrorLoggingService::NelPolicy & policy)545 void SQLitePersistentReportingAndNelStore::Backend::AddNelPolicy(
546 const NetworkErrorLoggingService::NelPolicy& policy) {
547 auto po =
548 NelPolicyInfo::CreatePendingOperation(PendingOperationType::ADD, policy);
549 if (!po)
550 return;
551 BatchOperation(policy.key, std::move(po), &nel_policy_pending_ops_);
552 }
553
UpdateNelPolicyAccessTime(const NetworkErrorLoggingService::NelPolicy & policy)554 void SQLitePersistentReportingAndNelStore::Backend::UpdateNelPolicyAccessTime(
555 const NetworkErrorLoggingService::NelPolicy& policy) {
556 auto po = NelPolicyInfo::CreatePendingOperation(
557 PendingOperationType::UPDATE_ACCESS_TIME, policy);
558 if (!po)
559 return;
560 BatchOperation(policy.key, std::move(po), &nel_policy_pending_ops_);
561 }
562
DeleteNelPolicy(const NetworkErrorLoggingService::NelPolicy & policy)563 void SQLitePersistentReportingAndNelStore::Backend::DeleteNelPolicy(
564 const NetworkErrorLoggingService::NelPolicy& policy) {
565 auto po = NelPolicyInfo::CreatePendingOperation(PendingOperationType::DELETE,
566 policy);
567 if (!po)
568 return;
569 BatchOperation(policy.key, std::move(po), &nel_policy_pending_ops_);
570 }
571
LoadReportingClients(ReportingClientsLoadedCallback loaded_callback)572 void SQLitePersistentReportingAndNelStore::Backend::LoadReportingClients(
573 ReportingClientsLoadedCallback loaded_callback) {
574 PostBackgroundTask(
575 FROM_HERE,
576 base::BindOnce(&Backend::LoadReportingClientsAndNotifyInBackground, this,
577 std::move(loaded_callback)));
578 }
579
AddReportingEndpoint(const ReportingEndpoint & endpoint)580 void SQLitePersistentReportingAndNelStore::Backend::AddReportingEndpoint(
581 const ReportingEndpoint& endpoint) {
582 auto po = ReportingEndpointInfo::CreatePendingOperation(
583 PendingOperationType::ADD, endpoint);
584 if (!po)
585 return;
586 ReportingEndpointKey key =
587 std::make_pair(endpoint.group_key, endpoint.info.url);
588 BatchOperation(std::move(key), std::move(po),
589 &reporting_endpoint_pending_ops_);
590 }
591
AddReportingEndpointGroup(const CachedReportingEndpointGroup & group)592 void SQLitePersistentReportingAndNelStore::Backend::AddReportingEndpointGroup(
593 const CachedReportingEndpointGroup& group) {
594 auto po = ReportingEndpointGroupInfo::CreatePendingOperation(
595 PendingOperationType::ADD, group);
596 if (!po)
597 return;
598 BatchOperation(group.group_key, std::move(po),
599 &reporting_endpoint_group_pending_ops_);
600 }
601
602 void SQLitePersistentReportingAndNelStore::Backend::
UpdateReportingEndpointGroupAccessTime(const CachedReportingEndpointGroup & group)603 UpdateReportingEndpointGroupAccessTime(
604 const CachedReportingEndpointGroup& group) {
605 auto po = ReportingEndpointGroupInfo::CreatePendingOperation(
606 PendingOperationType::UPDATE_ACCESS_TIME, group);
607 if (!po)
608 return;
609 BatchOperation(group.group_key, std::move(po),
610 &reporting_endpoint_group_pending_ops_);
611 }
612
613 void SQLitePersistentReportingAndNelStore::Backend::
UpdateReportingEndpointDetails(const ReportingEndpoint & endpoint)614 UpdateReportingEndpointDetails(const ReportingEndpoint& endpoint) {
615 auto po = ReportingEndpointInfo::CreatePendingOperation(
616 PendingOperationType::UPDATE_DETAILS, endpoint);
617 if (!po)
618 return;
619 ReportingEndpointKey key =
620 std::make_pair(endpoint.group_key, endpoint.info.url);
621 BatchOperation(std::move(key), std::move(po),
622 &reporting_endpoint_pending_ops_);
623 }
624
625 void SQLitePersistentReportingAndNelStore::Backend::
UpdateReportingEndpointGroupDetails(const CachedReportingEndpointGroup & group)626 UpdateReportingEndpointGroupDetails(
627 const CachedReportingEndpointGroup& group) {
628 auto po = ReportingEndpointGroupInfo::CreatePendingOperation(
629 PendingOperationType::UPDATE_DETAILS, group);
630 if (!po)
631 return;
632 BatchOperation(group.group_key, std::move(po),
633 &reporting_endpoint_group_pending_ops_);
634 }
635
DeleteReportingEndpoint(const ReportingEndpoint & endpoint)636 void SQLitePersistentReportingAndNelStore::Backend::DeleteReportingEndpoint(
637 const ReportingEndpoint& endpoint) {
638 auto po = ReportingEndpointInfo::CreatePendingOperation(
639 PendingOperationType::DELETE, endpoint);
640 if (!po)
641 return;
642 ReportingEndpointKey key =
643 std::make_pair(endpoint.group_key, endpoint.info.url);
644 BatchOperation(std::move(key), std::move(po),
645 &reporting_endpoint_pending_ops_);
646 }
647
648 void SQLitePersistentReportingAndNelStore::Backend::
DeleteReportingEndpointGroup(const CachedReportingEndpointGroup & group)649 DeleteReportingEndpointGroup(const CachedReportingEndpointGroup& group) {
650 auto po = ReportingEndpointGroupInfo::CreatePendingOperation(
651 PendingOperationType::DELETE, group);
652 if (!po)
653 return;
654 BatchOperation(group.group_key, std::move(po),
655 &reporting_endpoint_group_pending_ops_);
656 }
657
GetQueueLengthForTesting() const658 size_t SQLitePersistentReportingAndNelStore::Backend::GetQueueLengthForTesting()
659 const {
660 size_t count = 0;
661 {
662 base::AutoLock locked(lock_);
663 for (auto& key_and_pending_ops : nel_policy_pending_ops_) {
664 count += key_and_pending_ops.second.size();
665 }
666 for (auto& key_and_pending_ops : reporting_endpoint_pending_ops_) {
667 count += key_and_pending_ops.second.size();
668 }
669 for (auto& key_and_pending_ops : reporting_endpoint_group_pending_ops_) {
670 count += key_and_pending_ops.second.size();
671 }
672 }
673 return count;
674 }
675
CreateDatabaseSchema()676 bool SQLitePersistentReportingAndNelStore::Backend::CreateDatabaseSchema() {
677 if (!db()->DoesTableExist("nel_policies") &&
678 !CreateV2NelPoliciesSchema(db())) {
679 return false;
680 }
681
682 if (!db()->DoesTableExist("reporting_endpoints") &&
683 !CreateV2ReportingEndpointsSchema(db())) {
684 return false;
685 }
686
687 if (!db()->DoesTableExist("reporting_endpoint_groups") &&
688 !CreateV2ReportingEndpointGroupsSchema(db())) {
689 return false;
690 }
691
692 // TODO(chlily): Initialize tables for Reporting reports.
693
694 return true;
695 }
696
697 absl::optional<int>
DoMigrateDatabaseSchema()698 SQLitePersistentReportingAndNelStore::Backend::DoMigrateDatabaseSchema() {
699 int cur_version = meta_table()->GetVersionNumber();
700
701 // Migrate from version 1 to version 2.
702 //
703 // For migration purposes, the NetworkAnonymizationKey field of the stored
704 // policies will be populated with an empty list, which corresponds to an
705 // empty NIK. This matches the behavior when NIKs are disabled. This will
706 // result in effectively clearing all policies once NIKs are enabled, at
707 // which point the the migration code should just be switched to deleting
708 // the old tables instead.
709 if (cur_version == 1) {
710 sql::Transaction transaction(db());
711 if (!transaction.Begin())
712 return absl::nullopt;
713
714 // Migrate NEL policies table.
715 if (!db()->Execute("DROP TABLE IF EXISTS nel_policies_old; "
716 "ALTER TABLE nel_policies RENAME TO nel_policies_old")) {
717 return absl::nullopt;
718 }
719 if (!CreateV2NelPoliciesSchema(db()))
720 return absl::nullopt;
721 // clang-format off
722 // The "report_to" field is renamed to "group_name" for consistency with
723 // the other tables.
724 std::string nel_policies_migrate_stmt =
725 "INSERT INTO nel_policies (nik, origin_scheme, origin_host, "
726 " origin_port, group_name, received_ip_address, expires_us_since_epoch, "
727 " success_fraction, failure_fraction, is_include_subdomains, "
728 " last_access_us_since_epoch) "
729 "SELECT '[]', origin_scheme, origin_host, origin_port, "
730 " report_to, received_ip_address, expires_us_since_epoch, "
731 " success_fraction, failure_fraction, is_include_subdomains, "
732 " last_access_us_since_epoch "
733 "FROM nel_policies_old" ;
734 // clang-format on
735 if (!db()->Execute(nel_policies_migrate_stmt.c_str()))
736 return absl::nullopt;
737 if (!db()->Execute("DROP TABLE nel_policies_old"))
738 return absl::nullopt;
739
740 // Migrate Reporting endpoints table.
741 if (!db()->Execute("DROP TABLE IF EXISTS reporting_endpoints_old; "
742 "ALTER TABLE reporting_endpoints RENAME TO "
743 "reporting_endpoints_old")) {
744 return absl::nullopt;
745 }
746 if (!CreateV2ReportingEndpointsSchema(db()))
747 return absl::nullopt;
748 // clang-format off
749 std::string reporting_endpoints_migrate_stmt =
750 "INSERT INTO reporting_endpoints (nik, origin_scheme, origin_host, "
751 " origin_port, group_name, url, priority, weight) "
752 "SELECT '[]', origin_scheme, origin_host, origin_port, group_name, "
753 " url, priority, weight "
754 "FROM reporting_endpoints_old" ;
755 // clang-format on
756 if (!db()->Execute(reporting_endpoints_migrate_stmt.c_str()))
757 return absl::nullopt;
758 if (!db()->Execute("DROP TABLE reporting_endpoints_old"))
759 return absl::nullopt;
760
761 // Migrate Reporting endpoint groups table.
762 if (!db()->Execute("DROP TABLE IF EXISTS reporting_endpoint_groups_old; "
763 "ALTER TABLE reporting_endpoint_groups RENAME TO "
764 "reporting_endpoint_groups_old")) {
765 return absl::nullopt;
766 }
767 if (!CreateV2ReportingEndpointGroupsSchema(db()))
768 return absl::nullopt;
769 // clang-format off
770 std::string reporting_endpoint_groups_migrate_stmt =
771 "INSERT INTO reporting_endpoint_groups (nik, origin_scheme, "
772 " origin_host, origin_port, group_name, is_include_subdomains, "
773 " expires_us_since_epoch, last_access_us_since_epoch) "
774 "SELECT '[]', origin_scheme, origin_host, origin_port, "
775 " group_name, is_include_subdomains, expires_us_since_epoch, "
776 " last_access_us_since_epoch "
777 "FROM reporting_endpoint_groups_old" ;
778 // clang-format on
779 if (!db()->Execute(reporting_endpoint_groups_migrate_stmt.c_str()))
780 return absl::nullopt;
781 if (!db()->Execute("DROP TABLE reporting_endpoint_groups_old"))
782 return absl::nullopt;
783
784 ++cur_version;
785 if (!meta_table()->SetVersionNumber(cur_version) ||
786 !meta_table()->SetCompatibleVersionNumber(
787 std::min(cur_version, kCompatibleVersionNumber)) ||
788 !transaction.Commit()) {
789 return absl::nullopt;
790 }
791 }
792
793 // Future database upgrade statements go here.
794
795 return absl::make_optional(cur_version);
796 }
797
DoCommit()798 void SQLitePersistentReportingAndNelStore::Backend::DoCommit() {
799 QueueType<NetworkErrorLoggingService::NelPolicyKey, NelPolicyInfo>
800 nel_policy_ops;
801 QueueType<ReportingEndpointKey, ReportingEndpointInfo> reporting_endpoint_ops;
802 QueueType<ReportingEndpointGroupKey, ReportingEndpointGroupInfo>
803 reporting_endpoint_group_ops;
804 size_t op_count = 0;
805 {
806 base::AutoLock locked(lock_);
807 nel_policy_pending_ops_.swap(nel_policy_ops);
808 reporting_endpoint_pending_ops_.swap(reporting_endpoint_ops);
809 reporting_endpoint_group_pending_ops_.swap(reporting_endpoint_group_ops);
810 // TODO(chlily): swap out pending operations queue for Reporting reports.
811 op_count = num_pending_;
812 num_pending_ = 0;
813 }
814 if (!db() || op_count == 0)
815 return;
816
817 sql::Transaction transaction(db());
818 if (!transaction.Begin())
819 return;
820
821 // Commit all the NEL policy operations.
822 for (const auto& origin_and_nel_policy_ops : nel_policy_ops) {
823 const PendingOperationsVector<NelPolicyInfo>& ops_for_origin =
824 origin_and_nel_policy_ops.second;
825 for (const std::unique_ptr<PendingOperation<NelPolicyInfo>>& nel_policy_op :
826 ops_for_origin) {
827 CommitNelPolicyOperation(nel_policy_op.get());
828 }
829 }
830
831 // Commit all the Reporting endpoint operations.
832 for (const auto& key_and_reporting_endpoint_ops : reporting_endpoint_ops) {
833 const PendingOperationsVector<ReportingEndpointInfo>& ops_for_key =
834 key_and_reporting_endpoint_ops.second;
835 for (const std::unique_ptr<PendingOperation<ReportingEndpointInfo>>&
836 reporting_endpoint_op : ops_for_key) {
837 CommitReportingEndpointOperation(reporting_endpoint_op.get());
838 }
839 }
840
841 // Commit all the Reporting endpoint group operations.
842 for (const auto& key_and_reporting_endpoint_group_ops :
843 reporting_endpoint_group_ops) {
844 const PendingOperationsVector<ReportingEndpointGroupInfo>& ops_for_key =
845 key_and_reporting_endpoint_group_ops.second;
846 for (const std::unique_ptr<PendingOperation<ReportingEndpointGroupInfo>>&
847 reporting_endpoint_group_op : ops_for_key) {
848 CommitReportingEndpointGroupOperation(reporting_endpoint_group_op.get());
849 }
850 }
851
852 // TODO(chlily): Commit operations pertaining to Reporting reports.
853
854 transaction.Commit();
855 }
856
CommitNelPolicyOperation(PendingOperation<NelPolicyInfo> * op)857 bool SQLitePersistentReportingAndNelStore::Backend::CommitNelPolicyOperation(
858 PendingOperation<NelPolicyInfo>* op) {
859 DCHECK_EQ(1, db()->transaction_nesting());
860
861 sql::Statement add_statement(db()->GetCachedStatement(
862 SQL_FROM_HERE,
863 "INSERT INTO nel_policies (nik, origin_scheme, origin_host, origin_port, "
864 "received_ip_address, group_name, expires_us_since_epoch, "
865 "success_fraction, failure_fraction, is_include_subdomains, "
866 "last_access_us_since_epoch) VALUES (?,?,?,?,?,?,?,?,?,?,?)"));
867 if (!add_statement.is_valid())
868 return false;
869
870 sql::Statement update_access_statement(db()->GetCachedStatement(
871 SQL_FROM_HERE,
872 "UPDATE nel_policies SET last_access_us_since_epoch=? WHERE "
873 "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=?"));
874 if (!update_access_statement.is_valid())
875 return false;
876
877 sql::Statement del_statement(db()->GetCachedStatement(
878 SQL_FROM_HERE,
879 "DELETE FROM nel_policies WHERE "
880 "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=?"));
881 if (!del_statement.is_valid())
882 return false;
883
884 const NelPolicyInfo& nel_policy_info = op->data();
885
886 switch (op->type()) {
887 case PendingOperationType::ADD:
888 add_statement.Reset(true);
889 add_statement.BindString(
890 0, nel_policy_info.network_anonymization_key_string);
891 add_statement.BindString(1, nel_policy_info.origin_scheme);
892 add_statement.BindString(2, nel_policy_info.origin_host);
893 add_statement.BindInt(3, nel_policy_info.origin_port);
894 add_statement.BindString(4, nel_policy_info.received_ip_address);
895 add_statement.BindString(5, nel_policy_info.report_to);
896 add_statement.BindInt64(6, nel_policy_info.expires_us_since_epoch);
897 add_statement.BindDouble(7, nel_policy_info.success_fraction);
898 add_statement.BindDouble(8, nel_policy_info.failure_fraction);
899 add_statement.BindBool(9, nel_policy_info.is_include_subdomains);
900 add_statement.BindInt64(10, nel_policy_info.last_access_us_since_epoch);
901 if (!add_statement.Run()) {
902 DLOG(WARNING) << "Could not add a NEL policy to the DB.";
903 return false;
904 }
905 break;
906
907 case PendingOperationType::UPDATE_ACCESS_TIME:
908 update_access_statement.Reset(true);
909 update_access_statement.BindInt64(
910 0, nel_policy_info.last_access_us_since_epoch);
911 update_access_statement.BindString(
912 1, nel_policy_info.network_anonymization_key_string);
913 update_access_statement.BindString(2, nel_policy_info.origin_scheme);
914 update_access_statement.BindString(3, nel_policy_info.origin_host);
915 update_access_statement.BindInt(4, nel_policy_info.origin_port);
916 if (!update_access_statement.Run()) {
917 DLOG(WARNING)
918 << "Could not update NEL policy last access time in the DB.";
919 return false;
920 }
921 break;
922
923 case PendingOperationType::DELETE:
924 del_statement.Reset(true);
925 del_statement.BindString(
926 0, nel_policy_info.network_anonymization_key_string);
927 del_statement.BindString(1, nel_policy_info.origin_scheme);
928 del_statement.BindString(2, nel_policy_info.origin_host);
929 del_statement.BindInt(3, nel_policy_info.origin_port);
930 if (!del_statement.Run()) {
931 DLOG(WARNING) << "Could not delete a NEL policy from the DB.";
932 return false;
933 }
934 break;
935
936 default:
937 // There are no UPDATE_DETAILS operations for NEL policies.
938 // TODO(chlily): Maybe add the ability to update details as opposed to
939 // removing and re-adding every time; it might be slightly more efficient.
940 NOTREACHED();
941 break;
942 }
943
944 return true;
945 }
946
947 bool SQLitePersistentReportingAndNelStore::Backend::
CommitReportingEndpointOperation(PendingOperation<ReportingEndpointInfo> * op)948 CommitReportingEndpointOperation(
949 PendingOperation<ReportingEndpointInfo>* op) {
950 DCHECK_EQ(1, db()->transaction_nesting());
951
952 sql::Statement add_statement(db()->GetCachedStatement(
953 SQL_FROM_HERE,
954 "INSERT INTO reporting_endpoints (nik, origin_scheme, origin_host, "
955 "origin_port, group_name, url, priority, weight) "
956 "VALUES (?,?,?,?,?,?,?,?)"));
957 if (!add_statement.is_valid())
958 return false;
959
960 sql::Statement update_details_statement(db()->GetCachedStatement(
961 SQL_FROM_HERE,
962 "UPDATE reporting_endpoints SET priority=?, weight=? WHERE "
963 "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=? "
964 "AND group_name=? AND url=?"));
965 if (!update_details_statement.is_valid())
966 return false;
967
968 sql::Statement del_statement(db()->GetCachedStatement(
969 SQL_FROM_HERE,
970 "DELETE FROM reporting_endpoints WHERE "
971 "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=? "
972 "AND group_name=? AND url=?"));
973 if (!del_statement.is_valid())
974 return false;
975
976 const ReportingEndpointInfo& reporting_endpoint_info = op->data();
977
978 switch (op->type()) {
979 case PendingOperationType::ADD:
980 add_statement.Reset(true);
981 add_statement.BindString(
982 0, reporting_endpoint_info.network_anonymization_key_string);
983 add_statement.BindString(1, reporting_endpoint_info.origin_scheme);
984 add_statement.BindString(2, reporting_endpoint_info.origin_host);
985 add_statement.BindInt(3, reporting_endpoint_info.origin_port);
986 add_statement.BindString(4, reporting_endpoint_info.group_name);
987 add_statement.BindString(5, reporting_endpoint_info.url);
988 add_statement.BindInt(6, reporting_endpoint_info.priority);
989 add_statement.BindInt(7, reporting_endpoint_info.weight);
990 if (!add_statement.Run()) {
991 DLOG(WARNING) << "Could not add a Reporting endpoint to the DB.";
992 return false;
993 }
994 break;
995
996 case PendingOperationType::UPDATE_DETAILS:
997 update_details_statement.Reset(true);
998 update_details_statement.BindInt(0, reporting_endpoint_info.priority);
999 update_details_statement.BindInt(1, reporting_endpoint_info.weight);
1000 update_details_statement.BindString(
1001 2, reporting_endpoint_info.network_anonymization_key_string);
1002 update_details_statement.BindString(
1003 3, reporting_endpoint_info.origin_scheme);
1004 update_details_statement.BindString(4,
1005 reporting_endpoint_info.origin_host);
1006 update_details_statement.BindInt(5, reporting_endpoint_info.origin_port);
1007 update_details_statement.BindString(6,
1008 reporting_endpoint_info.group_name);
1009 update_details_statement.BindString(7, reporting_endpoint_info.url);
1010 if (!update_details_statement.Run()) {
1011 DLOG(WARNING)
1012 << "Could not update Reporting endpoint details in the DB.";
1013 return false;
1014 }
1015 break;
1016
1017 case PendingOperationType::DELETE:
1018 del_statement.Reset(true);
1019 del_statement.BindString(
1020 0, reporting_endpoint_info.network_anonymization_key_string);
1021 del_statement.BindString(1, reporting_endpoint_info.origin_scheme);
1022 del_statement.BindString(2, reporting_endpoint_info.origin_host);
1023 del_statement.BindInt(3, reporting_endpoint_info.origin_port);
1024 del_statement.BindString(4, reporting_endpoint_info.group_name);
1025 del_statement.BindString(5, reporting_endpoint_info.url);
1026 if (!del_statement.Run()) {
1027 DLOG(WARNING) << "Could not delete a Reporting endpoint from the DB.";
1028 return false;
1029 }
1030 break;
1031
1032 default:
1033 // There are no UPDATE_ACCESS_TIME operations for Reporting endpoints
1034 // because their access times are not tracked.
1035 NOTREACHED();
1036 break;
1037 }
1038
1039 return true;
1040 }
1041
1042 bool SQLitePersistentReportingAndNelStore::Backend::
CommitReportingEndpointGroupOperation(PendingOperation<ReportingEndpointGroupInfo> * op)1043 CommitReportingEndpointGroupOperation(
1044 PendingOperation<ReportingEndpointGroupInfo>* op) {
1045 DCHECK_EQ(1, db()->transaction_nesting());
1046
1047 sql::Statement add_statement(db()->GetCachedStatement(
1048 SQL_FROM_HERE,
1049 "INSERT INTO reporting_endpoint_groups (nik, origin_scheme, origin_host, "
1050 "origin_port, group_name, is_include_subdomains, expires_us_since_epoch, "
1051 "last_access_us_since_epoch) VALUES (?,?,?,?,?,?,?,?)"));
1052 if (!add_statement.is_valid())
1053 return false;
1054
1055 sql::Statement update_access_statement(db()->GetCachedStatement(
1056 SQL_FROM_HERE,
1057 "UPDATE reporting_endpoint_groups SET last_access_us_since_epoch=? WHERE "
1058 "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=? AND "
1059 "group_name=?"));
1060 if (!update_access_statement.is_valid())
1061 return false;
1062
1063 sql::Statement update_details_statement(db()->GetCachedStatement(
1064 SQL_FROM_HERE,
1065 "UPDATE reporting_endpoint_groups SET is_include_subdomains=?, "
1066 "expires_us_since_epoch=?, last_access_us_since_epoch=? WHERE "
1067 "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=? AND "
1068 "group_name=?"));
1069 if (!update_details_statement.is_valid())
1070 return false;
1071
1072 sql::Statement del_statement(
1073 db()->GetCachedStatement(SQL_FROM_HERE,
1074 "DELETE FROM reporting_endpoint_groups WHERE "
1075 "nik=? AND origin_scheme=? AND origin_host=? "
1076 "AND origin_port=? AND group_name=?"));
1077 if (!del_statement.is_valid())
1078 return false;
1079
1080 const ReportingEndpointGroupInfo& reporting_endpoint_group_info = op->data();
1081
1082 switch (op->type()) {
1083 case PendingOperationType::ADD:
1084 add_statement.Reset(true);
1085 add_statement.BindString(
1086 0, reporting_endpoint_group_info.network_anonymization_key_string);
1087 add_statement.BindString(1, reporting_endpoint_group_info.origin_scheme);
1088 add_statement.BindString(2, reporting_endpoint_group_info.origin_host);
1089 add_statement.BindInt(3, reporting_endpoint_group_info.origin_port);
1090 add_statement.BindString(4, reporting_endpoint_group_info.group_name);
1091 add_statement.BindBool(
1092 5, reporting_endpoint_group_info.is_include_subdomains);
1093 add_statement.BindInt64(
1094 6, reporting_endpoint_group_info.expires_us_since_epoch);
1095 add_statement.BindInt64(
1096 7, reporting_endpoint_group_info.last_access_us_since_epoch);
1097 if (!add_statement.Run()) {
1098 DLOG(WARNING) << "Could not add a Reporting endpoint group to the DB.";
1099 return false;
1100 }
1101 break;
1102
1103 case PendingOperationType::UPDATE_ACCESS_TIME:
1104 update_access_statement.Reset(true);
1105 update_access_statement.BindInt64(
1106 0, reporting_endpoint_group_info.last_access_us_since_epoch);
1107 update_access_statement.BindString(
1108 1, reporting_endpoint_group_info.network_anonymization_key_string);
1109 update_access_statement.BindString(
1110 2, reporting_endpoint_group_info.origin_scheme);
1111 update_access_statement.BindString(
1112 3, reporting_endpoint_group_info.origin_host);
1113 update_access_statement.BindInt(
1114 4, reporting_endpoint_group_info.origin_port);
1115 update_access_statement.BindString(
1116 5, reporting_endpoint_group_info.group_name);
1117 if (!update_access_statement.Run()) {
1118 DLOG(WARNING)
1119 << "Could not update Reporting endpoint group last access "
1120 "time in the DB.";
1121 return false;
1122 }
1123 break;
1124
1125 case PendingOperationType::UPDATE_DETAILS:
1126 update_details_statement.Reset(true);
1127 update_details_statement.BindBool(
1128 0, reporting_endpoint_group_info.is_include_subdomains);
1129 update_details_statement.BindInt64(
1130 1, reporting_endpoint_group_info.expires_us_since_epoch);
1131 update_details_statement.BindInt64(
1132 2, reporting_endpoint_group_info.last_access_us_since_epoch);
1133 update_details_statement.BindString(
1134 3, reporting_endpoint_group_info.network_anonymization_key_string);
1135 update_details_statement.BindString(
1136 4, reporting_endpoint_group_info.origin_scheme);
1137 update_details_statement.BindString(
1138 5, reporting_endpoint_group_info.origin_host);
1139 update_details_statement.BindInt(
1140 6, reporting_endpoint_group_info.origin_port);
1141 update_details_statement.BindString(
1142 7, reporting_endpoint_group_info.group_name);
1143 if (!update_details_statement.Run()) {
1144 DLOG(WARNING)
1145 << "Could not update Reporting endpoint group details in the DB.";
1146 return false;
1147 }
1148 break;
1149
1150 case PendingOperationType::DELETE:
1151 del_statement.Reset(true);
1152 del_statement.BindString(
1153 0, reporting_endpoint_group_info.network_anonymization_key_string);
1154 del_statement.BindString(1, reporting_endpoint_group_info.origin_scheme);
1155 del_statement.BindString(2, reporting_endpoint_group_info.origin_host);
1156 del_statement.BindInt(3, reporting_endpoint_group_info.origin_port);
1157 del_statement.BindString(4, reporting_endpoint_group_info.group_name);
1158 if (!del_statement.Run()) {
1159 DLOG(WARNING)
1160 << "Could not delete a Reporting endpoint group from the DB.";
1161 return false;
1162 }
1163 break;
1164 }
1165
1166 return true;
1167 }
1168
1169 template <typename KeyType, typename DataType>
BatchOperation(KeyType key,std::unique_ptr<PendingOperation<DataType>> po,QueueType<KeyType,DataType> * queue)1170 void SQLitePersistentReportingAndNelStore::Backend::BatchOperation(
1171 KeyType key,
1172 std::unique_ptr<PendingOperation<DataType>> po,
1173 QueueType<KeyType, DataType>* queue) {
1174 DCHECK(!background_task_runner()->RunsTasksInCurrentSequence());
1175
1176 size_t num_pending;
1177 {
1178 base::AutoLock locked(lock_);
1179
1180 std::pair<typename QueueType<KeyType, DataType>::iterator, bool>
1181 iter_and_result = queue->insert(std::make_pair(
1182 std::move(key), PendingOperationsVector<DataType>()));
1183 PendingOperationsVector<DataType>* ops_for_key =
1184 &iter_and_result.first->second;
1185 // If the insert failed, then we already have operations for this
1186 // key, so we try to coalesce the new operation with the existing ones.
1187 if (!iter_and_result.second)
1188 MaybeCoalesceOperations(ops_for_key, po.get());
1189 ops_for_key->push_back(std::move(po));
1190 // Note that num_pending_ counts number of calls to Batch*Operation(), not
1191 // the current length of the queue; this is intentional to guarantee
1192 // progress, as the length of the queue may decrease in some cases.
1193 num_pending = ++num_pending_;
1194 }
1195
1196 OnOperationBatched(num_pending);
1197 }
1198
1199 template <typename DataType>
MaybeCoalesceOperations(PendingOperationsVector<DataType> * ops_for_key,PendingOperation<DataType> * new_op)1200 void SQLitePersistentReportingAndNelStore::Backend::MaybeCoalesceOperations(
1201 PendingOperationsVector<DataType>* ops_for_key,
1202 PendingOperation<DataType>* new_op) {
1203 DCHECK(!ops_for_key->empty());
1204
1205 switch (new_op->type()) {
1206 case PendingOperationType::DELETE:
1207 // A delete makes all previous operations irrelevant.
1208 ops_for_key->clear();
1209 break;
1210
1211 case PendingOperationType::UPDATE_ACCESS_TIME:
1212 if (ops_for_key->back()->type() ==
1213 PendingOperationType::UPDATE_ACCESS_TIME) {
1214 // Updating the access time twice in a row is equivalent to just the
1215 // latter update.
1216 ops_for_key->pop_back();
1217 }
1218 break;
1219
1220 case PendingOperationType::UPDATE_DETAILS:
1221 while (!ops_for_key->empty() &&
1222 // Updating the details twice in a row is equivalent to just the
1223 // latter update.
1224 (ops_for_key->back()->type() ==
1225 PendingOperationType::UPDATE_DETAILS ||
1226 // UPDATE_DETAILS also updates the access time, so either type of
1227 // update operation can be discarded.
1228 ops_for_key->back()->type() ==
1229 PendingOperationType::UPDATE_ACCESS_TIME)) {
1230 ops_for_key->pop_back();
1231 }
1232 break;
1233
1234 case PendingOperationType::ADD:
1235 // Nothing special is done for an add operation. If it is overwriting an
1236 // existing entry, it will be preceded by at most one delete.
1237 DCHECK_LE(ops_for_key->size(), 1u);
1238 break;
1239 }
1240 }
1241
OnOperationBatched(size_t num_pending)1242 void SQLitePersistentReportingAndNelStore::Backend::OnOperationBatched(
1243 size_t num_pending) {
1244 DCHECK(!background_task_runner()->RunsTasksInCurrentSequence());
1245 // Commit every 30 seconds.
1246 static const int kCommitIntervalMs = 30 * 1000;
1247 // Commit right away if we have more than 512 outstanding operations.
1248 static const size_t kCommitAfterBatchSize = 512;
1249
1250 if (num_pending == 1) {
1251 // We've gotten our first entry for this batch, fire off the timer.
1252 if (!background_task_runner()->PostDelayedTask(
1253 FROM_HERE, base::BindOnce(&Backend::Commit, this),
1254 base::Milliseconds(kCommitIntervalMs))) {
1255 NOTREACHED() << "background_task_runner_ is not running.";
1256 }
1257 } else if (num_pending >= kCommitAfterBatchSize) {
1258 // We've reached a big enough batch, fire off a commit now.
1259 PostBackgroundTask(FROM_HERE, base::BindOnce(&Backend::Commit, this));
1260 }
1261 }
1262
1263 // TODO(chlily): Discard expired policies when loading, discard and record
1264 // problem if loaded policy is malformed.
1265 void SQLitePersistentReportingAndNelStore::Backend::
LoadNelPoliciesAndNotifyInBackground(NelPoliciesLoadedCallback loaded_callback)1266 LoadNelPoliciesAndNotifyInBackground(
1267 NelPoliciesLoadedCallback loaded_callback) {
1268 DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
1269
1270 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
1271 if (!InitializeDatabase()) {
1272 PostClientTask(
1273 FROM_HERE,
1274 base::BindOnce(&Backend::CompleteLoadNelPoliciesAndNotifyInForeground,
1275 this, std::move(loaded_callback),
1276 std::move(loaded_policies), false /* load_success */));
1277 return;
1278 }
1279
1280 sql::Statement smt(db()->GetUniqueStatement(
1281 "SELECT nik, origin_scheme, origin_host, origin_port, "
1282 "received_ip_address, group_name, expires_us_since_epoch, "
1283 "success_fraction, failure_fraction, is_include_subdomains, "
1284 "last_access_us_since_epoch FROM nel_policies"));
1285 if (!smt.is_valid()) {
1286 Reset();
1287 PostClientTask(
1288 FROM_HERE,
1289 base::BindOnce(&Backend::CompleteLoadNelPoliciesAndNotifyInForeground,
1290 this, std::move(loaded_callback),
1291 std::move(loaded_policies), false /* load_success */));
1292 return;
1293 }
1294
1295 while (smt.Step()) {
1296 // Attempt to reconstitute a NEL policy from the fields stored in the
1297 // database.
1298 NetworkAnonymizationKey network_anonymization_key;
1299 if (!NetworkAnonymizationKeyFromString(smt.ColumnString(0),
1300 &network_anonymization_key))
1301 continue;
1302 NetworkErrorLoggingService::NelPolicy policy;
1303 policy.key = NetworkErrorLoggingService::NelPolicyKey(
1304 network_anonymization_key,
1305 url::Origin::CreateFromNormalizedTuple(
1306 /* origin_scheme = */ smt.ColumnString(1),
1307 /* origin_host = */ smt.ColumnString(2),
1308 /* origin_port = */ smt.ColumnInt(3)));
1309 if (!policy.received_ip_address.AssignFromIPLiteral(smt.ColumnString(4)))
1310 policy.received_ip_address = IPAddress();
1311 policy.report_to = smt.ColumnString(5);
1312 policy.expires = base::Time::FromDeltaSinceWindowsEpoch(
1313 base::Microseconds(smt.ColumnInt64(6)));
1314 policy.success_fraction = smt.ColumnDouble(7);
1315 policy.failure_fraction = smt.ColumnDouble(8);
1316 policy.include_subdomains = smt.ColumnBool(9);
1317 policy.last_used = base::Time::FromDeltaSinceWindowsEpoch(
1318 base::Microseconds(smt.ColumnInt64(10)));
1319
1320 loaded_policies.push_back(std::move(policy));
1321 }
1322
1323 PostClientTask(
1324 FROM_HERE,
1325 base::BindOnce(&Backend::CompleteLoadNelPoliciesAndNotifyInForeground,
1326 this, std::move(loaded_callback),
1327 std::move(loaded_policies), true /* load_success */));
1328 }
1329
1330 void SQLitePersistentReportingAndNelStore::Backend::
CompleteLoadNelPoliciesAndNotifyInForeground(NelPoliciesLoadedCallback loaded_callback,std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies,bool load_success)1331 CompleteLoadNelPoliciesAndNotifyInForeground(
1332 NelPoliciesLoadedCallback loaded_callback,
1333 std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies,
1334 bool load_success) {
1335 DCHECK(client_task_runner()->RunsTasksInCurrentSequence());
1336
1337 if (load_success) {
1338 RecordNumberOfLoadedNelPolicies(loaded_policies.size());
1339 } else {
1340 DCHECK(loaded_policies.empty());
1341 }
1342
1343 std::move(loaded_callback).Run(std::move(loaded_policies));
1344 }
1345
1346 void SQLitePersistentReportingAndNelStore::Backend::
LoadReportingClientsAndNotifyInBackground(ReportingClientsLoadedCallback loaded_callback)1347 LoadReportingClientsAndNotifyInBackground(
1348 ReportingClientsLoadedCallback loaded_callback) {
1349 DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
1350
1351 std::vector<ReportingEndpoint> loaded_endpoints;
1352 std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups;
1353 if (!InitializeDatabase()) {
1354 PostClientTask(
1355 FROM_HERE,
1356 base::BindOnce(
1357 &Backend::CompleteLoadReportingClientsAndNotifyInForeground, this,
1358 std::move(loaded_callback), std::move(loaded_endpoints),
1359 std::move(loaded_endpoint_groups), false /* load_success */));
1360 return;
1361 }
1362
1363 sql::Statement endpoints_statement(db()->GetUniqueStatement(
1364 "SELECT nik, origin_scheme, origin_host, origin_port, group_name, "
1365 "url, priority, weight FROM reporting_endpoints"));
1366 sql::Statement endpoint_groups_statement(db()->GetUniqueStatement(
1367 "SELECT nik, origin_scheme, origin_host, origin_port, group_name, "
1368 "is_include_subdomains, expires_us_since_epoch, "
1369 "last_access_us_since_epoch FROM reporting_endpoint_groups"));
1370 if (!endpoints_statement.is_valid() ||
1371 !endpoint_groups_statement.is_valid()) {
1372 Reset();
1373 PostClientTask(
1374 FROM_HERE,
1375 base::BindOnce(
1376 &Backend::CompleteLoadReportingClientsAndNotifyInForeground, this,
1377 std::move(loaded_callback), std::move(loaded_endpoints),
1378 std::move(loaded_endpoint_groups), false /* load_success */));
1379 return;
1380 }
1381
1382 while (endpoints_statement.Step()) {
1383 // Attempt to reconstitute a ReportingEndpoint from the fields stored in the
1384 // database.
1385 NetworkAnonymizationKey network_anonymization_key;
1386 if (!NetworkAnonymizationKeyFromString(endpoints_statement.ColumnString(0),
1387 &network_anonymization_key))
1388 continue;
1389 ReportingEndpointGroupKey group_key(
1390 network_anonymization_key,
1391 /* origin = */
1392 url::Origin::CreateFromNormalizedTuple(
1393 /* origin_scheme = */ endpoints_statement.ColumnString(1),
1394 /* origin_host = */ endpoints_statement.ColumnString(2),
1395 /* origin_port = */ endpoints_statement.ColumnInt(3)),
1396 /* group_name = */ endpoints_statement.ColumnString(4));
1397 ReportingEndpoint::EndpointInfo endpoint_info;
1398 endpoint_info.url = GURL(endpoints_statement.ColumnString(5));
1399 endpoint_info.priority = endpoints_statement.ColumnInt(6);
1400 endpoint_info.weight = endpoints_statement.ColumnInt(7);
1401
1402 loaded_endpoints.emplace_back(std::move(group_key),
1403 std::move(endpoint_info));
1404 }
1405
1406 while (endpoint_groups_statement.Step()) {
1407 // Attempt to reconstitute a CachedReportingEndpointGroup from the fields
1408 // stored in the database.
1409 NetworkAnonymizationKey network_anonymization_key;
1410 if (!NetworkAnonymizationKeyFromString(
1411 endpoint_groups_statement.ColumnString(0),
1412 &network_anonymization_key))
1413 continue;
1414 ReportingEndpointGroupKey group_key(
1415 network_anonymization_key,
1416 /* origin = */
1417 url::Origin::CreateFromNormalizedTuple(
1418 /* origin_scheme = */ endpoint_groups_statement.ColumnString(1),
1419 /* origin_host = */ endpoint_groups_statement.ColumnString(2),
1420 /* origin_port = */ endpoint_groups_statement.ColumnInt(3)),
1421 /* group_name = */ endpoint_groups_statement.ColumnString(4));
1422 OriginSubdomains include_subdomains =
1423 endpoint_groups_statement.ColumnBool(5) ? OriginSubdomains::INCLUDE
1424 : OriginSubdomains::EXCLUDE;
1425 base::Time expires = base::Time::FromDeltaSinceWindowsEpoch(
1426 base::Microseconds(endpoint_groups_statement.ColumnInt64(6)));
1427 base::Time last_used = base::Time::FromDeltaSinceWindowsEpoch(
1428 base::Microseconds(endpoint_groups_statement.ColumnInt64(7)));
1429
1430 loaded_endpoint_groups.emplace_back(std::move(group_key),
1431 include_subdomains, expires, last_used);
1432 }
1433
1434 PostClientTask(
1435 FROM_HERE,
1436 base::BindOnce(
1437 &Backend::CompleteLoadReportingClientsAndNotifyInForeground, this,
1438 std::move(loaded_callback), std::move(loaded_endpoints),
1439 std::move(loaded_endpoint_groups), true /* load_success */));
1440 }
1441
1442 void SQLitePersistentReportingAndNelStore::Backend::
CompleteLoadReportingClientsAndNotifyInForeground(ReportingClientsLoadedCallback loaded_callback,std::vector<ReportingEndpoint> loaded_endpoints,std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups,bool load_success)1443 CompleteLoadReportingClientsAndNotifyInForeground(
1444 ReportingClientsLoadedCallback loaded_callback,
1445 std::vector<ReportingEndpoint> loaded_endpoints,
1446 std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups,
1447 bool load_success) {
1448 DCHECK(client_task_runner()->RunsTasksInCurrentSequence());
1449
1450 if (load_success) {
1451 RecordNumberOfLoadedReportingEndpoints(loaded_endpoints.size());
1452 RecordNumberOfLoadedReportingEndpointGroups(loaded_endpoint_groups.size());
1453 } else {
1454 DCHECK(loaded_endpoints.empty());
1455 DCHECK(loaded_endpoint_groups.empty());
1456 }
1457
1458 std::move(loaded_callback)
1459 .Run(std::move(loaded_endpoints), std::move(loaded_endpoint_groups));
1460 }
1461
1462 void SQLitePersistentReportingAndNelStore::Backend::
RecordNumberOfLoadedNelPolicies(size_t count)1463 RecordNumberOfLoadedNelPolicies(size_t count) {
1464 // The NetworkErrorLoggingService stores up to 1000 policies.
1465 UMA_HISTOGRAM_COUNTS_1000(kNumberOfLoadedNelPoliciesHistogramName, count);
1466 // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
1467 UMA_HISTOGRAM_COUNTS_10000(kNumberOfLoadedNelPolicies2HistogramName, count);
1468 }
1469
1470 void SQLitePersistentReportingAndNelStore::Backend::
RecordNumberOfLoadedReportingEndpoints(size_t count)1471 RecordNumberOfLoadedReportingEndpoints(size_t count) {
1472 // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
1473 UMA_HISTOGRAM_COUNTS_10000(kNumberOfLoadedReportingEndpoints2HistogramName,
1474 count);
1475 }
1476
1477 void SQLitePersistentReportingAndNelStore::Backend::
RecordNumberOfLoadedReportingEndpointGroups(size_t count)1478 RecordNumberOfLoadedReportingEndpointGroups(size_t count) {
1479 // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
1480 UMA_HISTOGRAM_COUNTS_10000(
1481 kNumberOfLoadedReportingEndpointGroups2HistogramName, count);
1482 }
1483
SQLitePersistentReportingAndNelStore(const base::FilePath & path,const scoped_refptr<base::SequencedTaskRunner> & client_task_runner,const scoped_refptr<base::SequencedTaskRunner> & background_task_runner)1484 SQLitePersistentReportingAndNelStore::SQLitePersistentReportingAndNelStore(
1485 const base::FilePath& path,
1486 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
1487 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner)
1488 : backend_(base::MakeRefCounted<Backend>(path,
1489 client_task_runner,
1490 background_task_runner)) {}
1491
~SQLitePersistentReportingAndNelStore()1492 SQLitePersistentReportingAndNelStore::~SQLitePersistentReportingAndNelStore() {
1493 backend_->Close();
1494 }
1495
LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback)1496 void SQLitePersistentReportingAndNelStore::LoadNelPolicies(
1497 NelPoliciesLoadedCallback loaded_callback) {
1498 DCHECK(!loaded_callback.is_null());
1499 backend_->LoadNelPolicies(base::BindOnce(
1500 &SQLitePersistentReportingAndNelStore::CompleteLoadNelPolicies,
1501 weak_factory_.GetWeakPtr(), std::move(loaded_callback)));
1502 }
1503
AddNelPolicy(const NetworkErrorLoggingService::NelPolicy & policy)1504 void SQLitePersistentReportingAndNelStore::AddNelPolicy(
1505 const NetworkErrorLoggingService::NelPolicy& policy) {
1506 backend_->AddNelPolicy(policy);
1507 }
1508
UpdateNelPolicyAccessTime(const NetworkErrorLoggingService::NelPolicy & policy)1509 void SQLitePersistentReportingAndNelStore::UpdateNelPolicyAccessTime(
1510 const NetworkErrorLoggingService::NelPolicy& policy) {
1511 backend_->UpdateNelPolicyAccessTime(policy);
1512 }
1513
DeleteNelPolicy(const NetworkErrorLoggingService::NelPolicy & policy)1514 void SQLitePersistentReportingAndNelStore::DeleteNelPolicy(
1515 const NetworkErrorLoggingService::NelPolicy& policy) {
1516 backend_->DeleteNelPolicy(policy);
1517 }
1518
LoadReportingClients(ReportingClientsLoadedCallback loaded_callback)1519 void SQLitePersistentReportingAndNelStore::LoadReportingClients(
1520 ReportingClientsLoadedCallback loaded_callback) {
1521 DCHECK(!loaded_callback.is_null());
1522 backend_->LoadReportingClients(base::BindOnce(
1523 &SQLitePersistentReportingAndNelStore::CompleteLoadReportingClients,
1524 weak_factory_.GetWeakPtr(), std::move(loaded_callback)));
1525 }
1526
AddReportingEndpoint(const ReportingEndpoint & endpoint)1527 void SQLitePersistentReportingAndNelStore::AddReportingEndpoint(
1528 const ReportingEndpoint& endpoint) {
1529 backend_->AddReportingEndpoint(endpoint);
1530 }
1531
AddReportingEndpointGroup(const CachedReportingEndpointGroup & group)1532 void SQLitePersistentReportingAndNelStore::AddReportingEndpointGroup(
1533 const CachedReportingEndpointGroup& group) {
1534 backend_->AddReportingEndpointGroup(group);
1535 }
1536
1537 void SQLitePersistentReportingAndNelStore::
UpdateReportingEndpointGroupAccessTime(const CachedReportingEndpointGroup & group)1538 UpdateReportingEndpointGroupAccessTime(
1539 const CachedReportingEndpointGroup& group) {
1540 backend_->UpdateReportingEndpointGroupAccessTime(group);
1541 }
1542
UpdateReportingEndpointDetails(const ReportingEndpoint & endpoint)1543 void SQLitePersistentReportingAndNelStore::UpdateReportingEndpointDetails(
1544 const ReportingEndpoint& endpoint) {
1545 backend_->UpdateReportingEndpointDetails(endpoint);
1546 }
1547
UpdateReportingEndpointGroupDetails(const CachedReportingEndpointGroup & group)1548 void SQLitePersistentReportingAndNelStore::UpdateReportingEndpointGroupDetails(
1549 const CachedReportingEndpointGroup& group) {
1550 backend_->UpdateReportingEndpointGroupDetails(group);
1551 }
1552
DeleteReportingEndpoint(const ReportingEndpoint & endpoint)1553 void SQLitePersistentReportingAndNelStore::DeleteReportingEndpoint(
1554 const ReportingEndpoint& endpoint) {
1555 backend_->DeleteReportingEndpoint(endpoint);
1556 }
1557
DeleteReportingEndpointGroup(const CachedReportingEndpointGroup & group)1558 void SQLitePersistentReportingAndNelStore::DeleteReportingEndpointGroup(
1559 const CachedReportingEndpointGroup& group) {
1560 backend_->DeleteReportingEndpointGroup(group);
1561 }
1562
Flush()1563 void SQLitePersistentReportingAndNelStore::Flush() {
1564 backend_->Flush(base::DoNothing());
1565 }
1566
GetQueueLengthForTesting() const1567 size_t SQLitePersistentReportingAndNelStore::GetQueueLengthForTesting() const {
1568 return backend_->GetQueueLengthForTesting();
1569 }
1570
CompleteLoadNelPolicies(NelPoliciesLoadedCallback callback,std::vector<NetworkErrorLoggingService::NelPolicy> policies)1571 void SQLitePersistentReportingAndNelStore::CompleteLoadNelPolicies(
1572 NelPoliciesLoadedCallback callback,
1573 std::vector<NetworkErrorLoggingService::NelPolicy> policies) {
1574 std::move(callback).Run(std::move(policies));
1575 }
1576
CompleteLoadReportingClients(ReportingClientsLoadedCallback callback,std::vector<ReportingEndpoint> endpoints,std::vector<CachedReportingEndpointGroup> endpoint_groups)1577 void SQLitePersistentReportingAndNelStore::CompleteLoadReportingClients(
1578 ReportingClientsLoadedCallback callback,
1579 std::vector<ReportingEndpoint> endpoints,
1580 std::vector<CachedReportingEndpointGroup> endpoint_groups) {
1581 std::move(callback).Run(std::move(endpoints), std::move(endpoint_groups));
1582 }
1583
1584 } // namespace net
1585