OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/safe_browsing/safe_browsing_database.h" | 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/metrics/stats_counters.h" | 9 #include "base/metrics/stats_counters.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 DCHECK_EQ(creation_loop_, MessageLoop::current()); | 280 DCHECK_EQ(creation_loop_, MessageLoop::current()); |
281 } | 281 } |
282 | 282 |
283 void SafeBrowsingDatabaseNew::Init(const FilePath& filename_base) { | 283 void SafeBrowsingDatabaseNew::Init(const FilePath& filename_base) { |
284 DCHECK_EQ(creation_loop_, MessageLoop::current()); | 284 DCHECK_EQ(creation_loop_, MessageLoop::current()); |
285 | 285 |
286 // NOTE: There is no need to grab the lock in this function, since | 286 // NOTE: There is no need to grab the lock in this function, since |
287 // until it returns, there are no pointers to this class on other | 287 // until it returns, there are no pointers to this class on other |
288 // threads. Then again, that means there is no possibility of | 288 // threads. Then again, that means there is no possibility of |
289 // contention on the lock... | 289 // contention on the lock... |
290 AutoLock locked(lookup_lock_); | 290 base::AutoLock locked(lookup_lock_); |
291 | 291 |
292 DCHECK(browse_filename_.empty()); // Ensure we haven't been run before. | 292 DCHECK(browse_filename_.empty()); // Ensure we haven't been run before. |
293 DCHECK(download_filename_.empty()); // Ensure we haven't been run before. | 293 DCHECK(download_filename_.empty()); // Ensure we haven't been run before. |
294 | 294 |
295 browse_filename_ = BrowseDBFilename(filename_base); | 295 browse_filename_ = BrowseDBFilename(filename_base); |
296 browse_store_->Init( | 296 browse_store_->Init( |
297 browse_filename_, | 297 browse_filename_, |
298 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase)); | 298 NewCallback(this, &SafeBrowsingDatabaseNew::HandleCorruptDatabase)); |
299 | 299 |
300 full_browse_hashes_.clear(); | 300 full_browse_hashes_.clear(); |
(...skipping 16 matching lines...) Expand all Loading... |
317 DCHECK_EQ(creation_loop_, MessageLoop::current()); | 317 DCHECK_EQ(creation_loop_, MessageLoop::current()); |
318 | 318 |
319 // Delete files on disk. | 319 // Delete files on disk. |
320 // TODO(shess): Hard to see where one might want to delete without a | 320 // TODO(shess): Hard to see where one might want to delete without a |
321 // reset. Perhaps inline |Delete()|? | 321 // reset. Perhaps inline |Delete()|? |
322 if (!Delete()) | 322 if (!Delete()) |
323 return false; | 323 return false; |
324 | 324 |
325 // Reset objects in memory. | 325 // Reset objects in memory. |
326 { | 326 { |
327 AutoLock locked(lookup_lock_); | 327 base::AutoLock locked(lookup_lock_); |
328 full_browse_hashes_.clear(); | 328 full_browse_hashes_.clear(); |
329 pending_browse_hashes_.clear(); | 329 pending_browse_hashes_.clear(); |
330 prefix_miss_cache_.clear(); | 330 prefix_miss_cache_.clear(); |
331 // TODO(shess): This could probably be |bloom_filter_.reset()|. | 331 // TODO(shess): This could probably be |bloom_filter_.reset()|. |
332 browse_bloom_filter_ = new BloomFilter(BloomFilter::kBloomFilterMinSize * | 332 browse_bloom_filter_ = new BloomFilter(BloomFilter::kBloomFilterMinSize * |
333 BloomFilter::kBloomFilterSizeRatio); | 333 BloomFilter::kBloomFilterSizeRatio); |
334 } | 334 } |
335 | 335 |
336 return true; | 336 return true; |
337 } | 337 } |
(...skipping 10 matching lines...) Expand all Loading... |
348 prefix_hits->clear(); | 348 prefix_hits->clear(); |
349 full_hits->clear(); | 349 full_hits->clear(); |
350 | 350 |
351 std::vector<SBPrefix> prefixes; | 351 std::vector<SBPrefix> prefixes; |
352 BrowsePrefixesToCheck(url, &prefixes); | 352 BrowsePrefixesToCheck(url, &prefixes); |
353 if (prefixes.empty()) | 353 if (prefixes.empty()) |
354 return false; | 354 return false; |
355 | 355 |
356 // This function is called on the I/O thread, prevent changes to | 356 // This function is called on the I/O thread, prevent changes to |
357 // bloom filter and caches. | 357 // bloom filter and caches. |
358 AutoLock locked(lookup_lock_); | 358 base::AutoLock locked(lookup_lock_); |
359 | 359 |
360 if (!browse_bloom_filter_.get()) | 360 if (!browse_bloom_filter_.get()) |
361 return false; | 361 return false; |
362 | 362 |
363 size_t miss_count = 0; | 363 size_t miss_count = 0; |
364 for (size_t i = 0; i < prefixes.size(); ++i) { | 364 for (size_t i = 0; i < prefixes.size(); ++i) { |
365 if (browse_bloom_filter_->Exists(prefixes[i])) { | 365 if (browse_bloom_filter_->Exists(prefixes[i])) { |
366 prefix_hits->push_back(prefixes[i]); | 366 prefix_hits->push_back(prefixes[i]); |
367 if (prefix_miss_cache_.count(prefixes[i]) > 0) | 367 if (prefix_miss_cache_.count(prefixes[i]) > 0) |
368 ++miss_count; | 368 ++miss_count; |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 else | 600 else |
601 store->DeleteAddChunk(encoded_chunk_id); | 601 store->DeleteAddChunk(encoded_chunk_id); |
602 } | 602 } |
603 } | 603 } |
604 } | 604 } |
605 | 605 |
606 void SafeBrowsingDatabaseNew::CacheHashResults( | 606 void SafeBrowsingDatabaseNew::CacheHashResults( |
607 const std::vector<SBPrefix>& prefixes, | 607 const std::vector<SBPrefix>& prefixes, |
608 const std::vector<SBFullHashResult>& full_hits) { | 608 const std::vector<SBFullHashResult>& full_hits) { |
609 // This is called on the I/O thread, lock against updates. | 609 // This is called on the I/O thread, lock against updates. |
610 AutoLock locked(lookup_lock_); | 610 base::AutoLock locked(lookup_lock_); |
611 | 611 |
612 if (full_hits.empty()) { | 612 if (full_hits.empty()) { |
613 prefix_miss_cache_.insert(prefixes.begin(), prefixes.end()); | 613 prefix_miss_cache_.insert(prefixes.begin(), prefixes.end()); |
614 return; | 614 return; |
615 } | 615 } |
616 | 616 |
617 // TODO(shess): SBFullHashResult and SBAddFullHash are very similar. | 617 // TODO(shess): SBFullHashResult and SBAddFullHash are very similar. |
618 // Refactor to make them identical. | 618 // Refactor to make them identical. |
619 const base::Time now = base::Time::Now(); | 619 const base::Time now = base::Time::Now(); |
620 const size_t orig_size = pending_browse_hashes_.size(); | 620 const size_t orig_size = pending_browse_hashes_.size(); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 &add_full_hashes_result)) | 722 &add_full_hashes_result)) |
723 RecordFailure(FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH); | 723 RecordFailure(FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH); |
724 return; | 724 return; |
725 } | 725 } |
726 | 726 |
727 void SafeBrowsingDatabaseNew::UpdateBrowseStore() { | 727 void SafeBrowsingDatabaseNew::UpdateBrowseStore() { |
728 // Copy out the pending add hashes. Copy rather than swapping in | 728 // Copy out the pending add hashes. Copy rather than swapping in |
729 // case |ContainsBrowseURL()| is called before the new filter is complete. | 729 // case |ContainsBrowseURL()| is called before the new filter is complete. |
730 std::vector<SBAddFullHash> pending_add_hashes; | 730 std::vector<SBAddFullHash> pending_add_hashes; |
731 { | 731 { |
732 AutoLock locked(lookup_lock_); | 732 base::AutoLock locked(lookup_lock_); |
733 pending_add_hashes.insert(pending_add_hashes.end(), | 733 pending_add_hashes.insert(pending_add_hashes.end(), |
734 pending_browse_hashes_.begin(), | 734 pending_browse_hashes_.begin(), |
735 pending_browse_hashes_.end()); | 735 pending_browse_hashes_.end()); |
736 } | 736 } |
737 | 737 |
738 // Measure the amount of IO during the bloom filter build. | 738 // Measure the amount of IO during the bloom filter build. |
739 base::IoCounters io_before, io_after; | 739 base::IoCounters io_before, io_after; |
740 base::ProcessHandle handle = base::Process::Current().handle(); | 740 base::ProcessHandle handle = base::Process::Current().handle(); |
741 scoped_ptr<base::ProcessMetrics> metric( | 741 scoped_ptr<base::ProcessMetrics> metric( |
742 #if !defined(OS_MACOSX) | 742 #if !defined(OS_MACOSX) |
(...skipping 28 matching lines...) Expand all Loading... |
771 for (size_t i = 0; i < add_prefixes.size(); ++i) { | 771 for (size_t i = 0; i < add_prefixes.size(); ++i) { |
772 filter->Insert(add_prefixes[i].prefix); | 772 filter->Insert(add_prefixes[i].prefix); |
773 } | 773 } |
774 | 774 |
775 // This needs to be in sorted order by prefix for efficient access. | 775 // This needs to be in sorted order by prefix for efficient access. |
776 std::sort(add_full_hashes.begin(), add_full_hashes.end(), | 776 std::sort(add_full_hashes.begin(), add_full_hashes.end(), |
777 SBAddFullHashPrefixLess); | 777 SBAddFullHashPrefixLess); |
778 | 778 |
779 // Swap in the newly built filter and cache. | 779 // Swap in the newly built filter and cache. |
780 { | 780 { |
781 AutoLock locked(lookup_lock_); | 781 base::AutoLock locked(lookup_lock_); |
782 full_browse_hashes_.swap(add_full_hashes); | 782 full_browse_hashes_.swap(add_full_hashes); |
783 | 783 |
784 // TODO(shess): If |CacheHashResults()| is posted between the | 784 // TODO(shess): If |CacheHashResults()| is posted between the |
785 // earlier lock and this clear, those pending hashes will be lost. | 785 // earlier lock and this clear, those pending hashes will be lost. |
786 // It could be fixed by only removing hashes which were collected | 786 // It could be fixed by only removing hashes which were collected |
787 // at the earlier point. I believe that is fail-safe as-is (the | 787 // at the earlier point. I believe that is fail-safe as-is (the |
788 // hash will be fetched again). | 788 // hash will be fetched again). |
789 pending_browse_hashes_.clear(); | 789 pending_browse_hashes_.clear(); |
790 prefix_miss_cache_.clear(); | 790 prefix_miss_cache_.clear(); |
791 browse_bloom_filter_.swap(filter); | 791 browse_bloom_filter_.swap(filter); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 return; | 898 return; |
899 | 899 |
900 const base::TimeTicks before = base::TimeTicks::Now(); | 900 const base::TimeTicks before = base::TimeTicks::Now(); |
901 const bool write_ok = browse_bloom_filter_->WriteFile(bloom_filter_filename_); | 901 const bool write_ok = browse_bloom_filter_->WriteFile(bloom_filter_filename_); |
902 DVLOG(1) << "SafeBrowsingDatabaseNew wrote bloom filter in " | 902 DVLOG(1) << "SafeBrowsingDatabaseNew wrote bloom filter in " |
903 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; | 903 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; |
904 | 904 |
905 if (!write_ok) | 905 if (!write_ok) |
906 RecordFailure(FAILURE_DATABASE_FILTER_WRITE); | 906 RecordFailure(FAILURE_DATABASE_FILTER_WRITE); |
907 } | 907 } |
OLD | NEW |