Chromium Code Reviews| 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 | 4 |
| 5 #include "base/base64.h" | 5 #include "base/base64.h" |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/metrics/sparse_histogram.h" | 10 #include "base/metrics/sparse_histogram.h" |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 state_ = ""; | 181 state_ = ""; |
| 182 } | 182 } |
| 183 | 183 |
| 184 ApplyUpdateResult V4Store::ProcessPartialUpdateAndWriteToDisk( | 184 ApplyUpdateResult V4Store::ProcessPartialUpdateAndWriteToDisk( |
| 185 const HashPrefixMap& hash_prefix_map_old, | 185 const HashPrefixMap& hash_prefix_map_old, |
| 186 std::unique_ptr<ListUpdateResponse> response) { | 186 std::unique_ptr<ListUpdateResponse> response) { |
| 187 DCHECK(response->has_response_type()); | 187 DCHECK(response->has_response_type()); |
| 188 DCHECK_EQ(ListUpdateResponse::PARTIAL_UPDATE, response->response_type()); | 188 DCHECK_EQ(ListUpdateResponse::PARTIAL_UPDATE, response->response_type()); |
| 189 | 189 |
| 190 TimeTicks before = TimeTicks::Now(); | 190 TimeTicks before = TimeTicks::Now(); |
| 191 ApplyUpdateResult result = ProcessUpdate(hash_prefix_map_old, response); | 191 ApplyUpdateResult result = |
| 192 ProcessUpdate(hash_prefix_map_old, response, false); | |
|
Nathan Parker
2016/10/14 23:49:38
nit: false /* delay_checksum check */ )
| |
| 192 if (result == APPLY_UPDATE_SUCCESS) { | 193 if (result == APPLY_UPDATE_SUCCESS) { |
| 193 RecordProcessPartialUpdateTime(TimeTicks::Now() - before, store_path_); | 194 RecordProcessPartialUpdateTime(TimeTicks::Now() - before, store_path_); |
| 194 Checksum checksum = response->checksum(); | 195 Checksum checksum = response->checksum(); |
| 195 response.reset(); | 196 response.reset(); |
| 196 RecordStoreWriteResult(WriteToDisk(checksum)); | 197 RecordStoreWriteResult(WriteToDisk(checksum)); |
| 197 } | 198 } |
| 198 return result; | 199 return result; |
| 199 } | 200 } |
| 200 | 201 |
| 201 ApplyUpdateResult V4Store::ProcessFullUpdateAndWriteToDisk( | 202 ApplyUpdateResult V4Store::ProcessFullUpdateAndWriteToDisk( |
| 202 std::unique_ptr<ListUpdateResponse> response) { | 203 std::unique_ptr<ListUpdateResponse> response) { |
| 203 TimeTicks before = TimeTicks::Now(); | 204 TimeTicks before = TimeTicks::Now(); |
| 204 ApplyUpdateResult result = ProcessFullUpdate(response); | 205 ApplyUpdateResult result = ProcessFullUpdate(response, false); |
| 205 if (result == APPLY_UPDATE_SUCCESS) { | 206 if (result == APPLY_UPDATE_SUCCESS) { |
| 206 RecordProcessFullUpdateTime(TimeTicks::Now() - before, store_path_); | 207 RecordProcessFullUpdateTime(TimeTicks::Now() - before, store_path_); |
| 207 Checksum checksum = response->checksum(); | 208 Checksum checksum = response->checksum(); |
| 208 response.reset(); | 209 response.reset(); |
| 209 RecordStoreWriteResult(WriteToDisk(checksum)); | 210 RecordStoreWriteResult(WriteToDisk(checksum)); |
| 210 } | 211 } |
| 211 return result; | 212 return result; |
| 212 } | 213 } |
| 213 | 214 |
| 214 ApplyUpdateResult V4Store::ProcessFullUpdate( | 215 ApplyUpdateResult V4Store::ProcessFullUpdate( |
| 215 const std::unique_ptr<ListUpdateResponse>& response) { | 216 const std::unique_ptr<ListUpdateResponse>& response, |
| 217 bool delay_checksum_check) { | |
| 216 DCHECK(response->has_response_type()); | 218 DCHECK(response->has_response_type()); |
| 217 DCHECK_EQ(ListUpdateResponse::FULL_UPDATE, response->response_type()); | 219 DCHECK_EQ(ListUpdateResponse::FULL_UPDATE, response->response_type()); |
| 218 // TODO(vakh): For a full update, we don't need to process the update in | 220 // TODO(vakh): For a full update, we don't need to process the update in |
| 219 // lexographical order to store it, but we do need to do that for calculating | 221 // lexographical order to store it, but we do need to do that for calculating |
| 220 // checksum. It might save some CPU cycles to store the full update as-is and | 222 // checksum. It might save some CPU cycles to store the full update as-is and |
| 221 // walk the list of hash prefixes in lexographical order only for checksum | 223 // walk the list of hash prefixes in lexographical order only for checksum |
| 222 // calculation. | 224 // calculation. |
| 223 return ProcessUpdate(HashPrefixMap(), response); | 225 return ProcessUpdate(HashPrefixMap(), response, delay_checksum_check); |
| 224 } | 226 } |
| 225 | 227 |
| 226 ApplyUpdateResult V4Store::ProcessUpdate( | 228 ApplyUpdateResult V4Store::ProcessUpdate( |
| 227 const HashPrefixMap& hash_prefix_map_old, | 229 const HashPrefixMap& hash_prefix_map_old, |
| 228 const std::unique_ptr<ListUpdateResponse>& response) { | 230 const std::unique_ptr<ListUpdateResponse>& response, |
| 231 bool delay_checksum_check) { | |
| 229 const RepeatedField<int32>* raw_removals = nullptr; | 232 const RepeatedField<int32>* raw_removals = nullptr; |
| 230 RepeatedField<int32> rice_removals; | 233 RepeatedField<int32> rice_removals; |
| 231 size_t removals_size = response->removals_size(); | 234 size_t removals_size = response->removals_size(); |
| 232 DCHECK_LE(removals_size, 1u); | 235 DCHECK_LE(removals_size, 1u); |
| 233 if (removals_size == 1) { | 236 if (removals_size == 1) { |
| 234 const ThreatEntrySet& removal = response->removals().Get(0); | 237 const ThreatEntrySet& removal = response->removals().Get(0); |
| 235 const CompressionType compression_type = removal.compression_type(); | 238 const CompressionType compression_type = removal.compression_type(); |
| 236 if (compression_type == RAW) { | 239 if (compression_type == RAW) { |
| 237 raw_removals = &removal.raw_indices().indices(); | 240 raw_removals = &removal.raw_indices().indices(); |
| 238 } else if (compression_type == RICE) { | 241 } else if (compression_type == RICE) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 263 if (apply_update_result != APPLY_UPDATE_SUCCESS) { | 266 if (apply_update_result != APPLY_UPDATE_SUCCESS) { |
| 264 return apply_update_result; | 267 return apply_update_result; |
| 265 } | 268 } |
| 266 | 269 |
| 267 std::string expected_checksum; | 270 std::string expected_checksum; |
| 268 if (response->has_checksum() && response->checksum().has_sha256()) { | 271 if (response->has_checksum() && response->checksum().has_sha256()) { |
| 269 expected_checksum = response->checksum().sha256(); | 272 expected_checksum = response->checksum().sha256(); |
| 270 } | 273 } |
| 271 | 274 |
| 272 TimeTicks before = TimeTicks::Now(); | 275 TimeTicks before = TimeTicks::Now(); |
| 273 apply_update_result = MergeUpdate(hash_prefix_map_old, hash_prefix_map, | 276 apply_update_result = |
| 274 raw_removals, expected_checksum); | 277 MergeUpdate(hash_prefix_map_old, hash_prefix_map, raw_removals, |
| 278 expected_checksum, delay_checksum_check); | |
| 275 if (apply_update_result != APPLY_UPDATE_SUCCESS) { | 279 if (apply_update_result != APPLY_UPDATE_SUCCESS) { |
| 276 return apply_update_result; | 280 return apply_update_result; |
| 277 } | 281 } |
| 278 RecordMergeUpdateTime(TimeTicks::Now() - before, store_path_); | 282 RecordMergeUpdateTime(TimeTicks::Now() - before, store_path_); |
| 279 | 283 |
| 280 state_ = response->new_client_state(); | 284 state_ = response->new_client_state(); |
| 281 return APPLY_UPDATE_SUCCESS; | 285 return APPLY_UPDATE_SUCCESS; |
| 282 } | 286 } |
| 283 | 287 |
| 284 void V4Store::ApplyUpdate( | 288 void V4Store::ApplyUpdate( |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 size_t existing_capacity = existing_prefixes.capacity(); | 447 size_t existing_capacity = existing_prefixes.capacity(); |
| 444 | 448 |
| 445 (*prefix_map_to_update)[prefix_size].reserve(existing_capacity + | 449 (*prefix_map_to_update)[prefix_size].reserve(existing_capacity + |
| 446 prefix_length_to_add); | 450 prefix_length_to_add); |
| 447 } | 451 } |
| 448 } | 452 } |
| 449 | 453 |
| 450 ApplyUpdateResult V4Store::MergeUpdate(const HashPrefixMap& old_prefixes_map, | 454 ApplyUpdateResult V4Store::MergeUpdate(const HashPrefixMap& old_prefixes_map, |
| 451 const HashPrefixMap& additions_map, | 455 const HashPrefixMap& additions_map, |
| 452 const RepeatedField<int32>* raw_removals, | 456 const RepeatedField<int32>* raw_removals, |
| 453 const std::string& expected_checksum) { | 457 const std::string& expected_checksum, |
| 458 bool delay_checksum_check) { | |
| 454 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 459 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 455 DCHECK(hash_prefix_map_.empty()); | 460 DCHECK(hash_prefix_map_.empty()); |
| 456 | 461 |
| 457 bool calculate_checksum = !expected_checksum.empty(); | 462 bool calculate_checksum = !expected_checksum.empty(); |
| 458 if (calculate_checksum && | 463 if (calculate_checksum && |
| 459 (expected_checksum.size() != crypto::kSHA256Length)) { | 464 (expected_checksum.size() != crypto::kSHA256Length)) { |
| 460 return CHECKSUM_MISMATCH_FAILURE; | 465 return CHECKSUM_MISMATCH_FAILURE; |
| 461 } | 466 } |
| 462 | 467 |
| 463 if (old_prefixes_map.empty()) { | 468 if (delay_checksum_check) { |
|
Nathan Parker
2016/10/14 23:49:38
A thought: I kinda feel like this block could be r
| |
| 464 // If the old map is empty, which it is at startup, then just copy over the | 469 DCHECK(old_prefixes_map.empty()); |
| 465 // additions map. | |
| 466 DCHECK(!raw_removals); | 470 DCHECK(!raw_removals); |
| 471 // We delay the checksum check at startup to be able to load the DB | |
| 472 // quickly. In this case, the old_prefixes_map should be empty, so just | |
| 473 // copy over the additions map. | |
| 467 hash_prefix_map_ = additions_map; | 474 hash_prefix_map_ = additions_map; |
| 468 | 475 |
| 469 // Calculate the checksum asynchronously later and if it doesn't match, | 476 // Calculate the checksum asynchronously later and if it doesn't match, |
| 470 // reset the store. | 477 // reset the store. |
| 471 expected_checksum_ = expected_checksum; | 478 expected_checksum_ = expected_checksum; |
| 472 | 479 |
| 473 return APPLY_UPDATE_SUCCESS; | 480 return APPLY_UPDATE_SUCCESS; |
| 474 } | 481 } |
| 475 | 482 |
| 476 hash_prefix_map_.clear(); | 483 hash_prefix_map_.clear(); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 if (file_format.version_number() != kFileVersion) { | 631 if (file_format.version_number() != kFileVersion) { |
| 625 return FILE_VERSION_INCOMPATIBLE_FAILURE; | 632 return FILE_VERSION_INCOMPATIBLE_FAILURE; |
| 626 } | 633 } |
| 627 | 634 |
| 628 if (!file_format.has_list_update_response()) { | 635 if (!file_format.has_list_update_response()) { |
| 629 return HASH_PREFIX_INFO_MISSING_FAILURE; | 636 return HASH_PREFIX_INFO_MISSING_FAILURE; |
| 630 } | 637 } |
| 631 | 638 |
| 632 std::unique_ptr<ListUpdateResponse> response(new ListUpdateResponse); | 639 std::unique_ptr<ListUpdateResponse> response(new ListUpdateResponse); |
| 633 response->Swap(file_format.mutable_list_update_response()); | 640 response->Swap(file_format.mutable_list_update_response()); |
| 634 ApplyUpdateResult apply_update_result = ProcessFullUpdate(response); | 641 ApplyUpdateResult apply_update_result = ProcessFullUpdate(response, true); |
|
Nathan Parker
2016/10/14 23:49:38
true /* delay_checksum_check */
| |
| 635 RecordApplyUpdateResultWhenReadingFromDisk(apply_update_result); | 642 RecordApplyUpdateResultWhenReadingFromDisk(apply_update_result); |
| 636 if (apply_update_result != APPLY_UPDATE_SUCCESS) { | 643 if (apply_update_result != APPLY_UPDATE_SUCCESS) { |
| 637 hash_prefix_map_.clear(); | 644 hash_prefix_map_.clear(); |
| 638 return HASH_PREFIX_MAP_GENERATION_FAILURE; | 645 return HASH_PREFIX_MAP_GENERATION_FAILURE; |
| 639 } | 646 } |
| 640 RecordReadFromDiskTime(TimeTicks::Now() - before, store_path_); | 647 RecordReadFromDiskTime(TimeTicks::Now() - before, store_path_); |
| 641 | 648 |
| 642 return READ_SUCCESS; | 649 return READ_SUCCESS; |
| 643 } | 650 } |
| 644 | 651 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 763 << "; expected: " << expected_checksum_b64 | 770 << "; expected: " << expected_checksum_b64 |
| 764 << "; store: " << *this; | 771 << "; store: " << *this; |
| 765 #endif | 772 #endif |
| 766 return false; | 773 return false; |
| 767 } | 774 } |
| 768 } | 775 } |
| 769 return true; | 776 return true; |
| 770 } | 777 } |
| 771 | 778 |
| 772 } // namespace safe_browsing | 779 } // namespace safe_browsing |
| OLD | NEW |