Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: chrome/browser/safe_browsing/safe_browsing_database.cc

Issue 910953002: Move SafeBrowsing to the blocking pool via an experiment. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 // Find full-hash matches. 310 // Find full-hash matches.
311 std::vector<SBFullHashResult>& cached_hashes = cached_result.full_hashes; 311 std::vector<SBFullHashResult>& cached_hashes = cached_result.full_hashes;
312 for (size_t i = 0; i < cached_hashes.size(); ++i) { 312 for (size_t i = 0; i < cached_hashes.size(); ++i) {
313 if (SBFullHashEqual(full_hash, cached_hashes[i].hash)) 313 if (SBFullHashEqual(full_hash, cached_hashes[i].hash))
314 results->push_back(cached_hashes[i]); 314 results->push_back(cached_hashes[i]);
315 } 315 }
316 316
317 return true; 317 return true;
318 } 318 }
319 319
320 SafeBrowsingStoreFile* CreateStore(
321 bool enable,
322 scoped_refptr<base::SequencedTaskRunner> task_runner) {
323 if (!enable)
324 return nullptr;
325 return new SafeBrowsingStoreFile(task_runner);
326 }
327
320 } // namespace 328 } // namespace
321 329
322 // The default SafeBrowsingDatabaseFactory. 330 // The default SafeBrowsingDatabaseFactory.
323 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { 331 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory {
324 public: 332 public:
325 SafeBrowsingDatabase* CreateSafeBrowsingDatabase( 333 SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
334 scoped_refptr<base::SequencedTaskRunner> db_task_runner,
326 bool enable_download_protection, 335 bool enable_download_protection,
327 bool enable_client_side_whitelist, 336 bool enable_client_side_whitelist,
328 bool enable_download_whitelist, 337 bool enable_download_whitelist,
329 bool enable_extension_blacklist, 338 bool enable_extension_blacklist,
330 bool enable_side_effect_free_whitelist, 339 bool enable_side_effect_free_whitelist,
331 bool enable_ip_blacklist, 340 bool enable_ip_blacklist,
332 bool enable_unwanted_software_list) override { 341 bool enable_unwanted_software_list) override {
333 return new SafeBrowsingDatabaseNew( 342 return new SafeBrowsingDatabaseNew(
334 new SafeBrowsingStoreFile, // browse_store 343 db_task_runner, CreateStore(true, db_task_runner), // browse_store
335 enable_download_protection ? new SafeBrowsingStoreFile : NULL, 344 CreateStore(enable_download_protection, db_task_runner),
336 enable_client_side_whitelist ? new SafeBrowsingStoreFile : NULL, 345 CreateStore(enable_client_side_whitelist, db_task_runner),
337 enable_download_whitelist ? new SafeBrowsingStoreFile : NULL, 346 CreateStore(enable_download_whitelist, db_task_runner),
338 new SafeBrowsingStoreFile, // inclusion_whitelist_store 347 CreateStore(true, db_task_runner), // inclusion_whitelist_store
339 enable_extension_blacklist ? new SafeBrowsingStoreFile : NULL, 348 CreateStore(enable_extension_blacklist, db_task_runner),
340 enable_side_effect_free_whitelist ? new SafeBrowsingStoreFile : NULL, 349 CreateStore(enable_side_effect_free_whitelist, db_task_runner),
341 enable_ip_blacklist ? new SafeBrowsingStoreFile : NULL, 350 CreateStore(enable_ip_blacklist, db_task_runner),
342 enable_unwanted_software_list ? new SafeBrowsingStoreFile : NULL); 351 CreateStore(enable_unwanted_software_list, db_task_runner));
343 } 352 }
344 353
345 SafeBrowsingDatabaseFactoryImpl() { } 354 SafeBrowsingDatabaseFactoryImpl() { }
346 355
347 private: 356 private:
348 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactoryImpl); 357 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseFactoryImpl);
349 }; 358 };
350 359
351 // static 360 // static
352 SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL; 361 SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL;
353 362
354 // Factory method, non-thread safe. Caller has to make sure this is called 363 // Factory method, non-thread safe. Caller has to make sure this is called
355 // on SafeBrowsing Thread. 364 // on SafeBrowsing Thread.
356 // TODO(shess): There's no need for a factory any longer. Convert 365 // TODO(shess): There's no need for a factory any longer. Convert
357 // SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create() 366 // SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create()
358 // callers just construct things directly. 367 // callers just construct things directly.
359 SafeBrowsingDatabase* SafeBrowsingDatabase::Create( 368 SafeBrowsingDatabase* SafeBrowsingDatabase::Create(
369 scoped_refptr<base::SequencedTaskRunner> current_task_runner,
360 bool enable_download_protection, 370 bool enable_download_protection,
361 bool enable_client_side_whitelist, 371 bool enable_client_side_whitelist,
362 bool enable_download_whitelist, 372 bool enable_download_whitelist,
363 bool enable_extension_blacklist, 373 bool enable_extension_blacklist,
364 bool enable_side_effect_free_whitelist, 374 bool enable_side_effect_free_whitelist,
365 bool enable_ip_blacklist, 375 bool enable_ip_blacklist,
366 bool enable_unwanted_software_list) { 376 bool enable_unwanted_software_list) {
367 if (!factory_) 377 if (!factory_)
368 factory_ = new SafeBrowsingDatabaseFactoryImpl(); 378 factory_ = new SafeBrowsingDatabaseFactoryImpl();
369 return factory_->CreateSafeBrowsingDatabase(enable_download_protection, 379 return factory_->CreateSafeBrowsingDatabase(
370 enable_client_side_whitelist, 380 current_task_runner, enable_download_protection,
371 enable_download_whitelist, 381 enable_client_side_whitelist, enable_download_whitelist,
372 enable_extension_blacklist, 382 enable_extension_blacklist, enable_side_effect_free_whitelist,
373 enable_side_effect_free_whitelist, 383 enable_ip_blacklist, enable_unwanted_software_list);
374 enable_ip_blacklist,
375 enable_unwanted_software_list);
376 } 384 }
377 385
378 SafeBrowsingDatabase::~SafeBrowsingDatabase() { 386 SafeBrowsingDatabase::~SafeBrowsingDatabase() {
379 } 387 }
380 388
381 // static 389 // static
382 base::FilePath SafeBrowsingDatabase::BrowseDBFilename( 390 base::FilePath SafeBrowsingDatabase::BrowseDBFilename(
383 const base::FilePath& db_base_filename) { 391 const base::FilePath& db_base_filename) {
384 return base::FilePath(db_base_filename.value() + kBrowseDBFile); 392 return base::FilePath(db_base_filename.value() + kBrowseDBFile);
385 } 393 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 } 447 }
440 448
441 // static 449 // static
442 base::FilePath SafeBrowsingDatabase::UnwantedSoftwareDBFilename( 450 base::FilePath SafeBrowsingDatabase::UnwantedSoftwareDBFilename(
443 const base::FilePath& db_filename) { 451 const base::FilePath& db_filename) {
444 return base::FilePath(db_filename.value() + kUnwantedSoftwareDBFile); 452 return base::FilePath(db_filename.value() + kUnwantedSoftwareDBFile);
445 } 453 }
446 454
447 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) { 455 SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) {
448 // Stores are not thread safe. 456 // Stores are not thread safe.
449 DCHECK(thread_checker_.CalledOnValidThread()); 457 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
450 458
451 if (list_id == safe_browsing_util::PHISH || 459 if (list_id == safe_browsing_util::PHISH ||
452 list_id == safe_browsing_util::MALWARE) { 460 list_id == safe_browsing_util::MALWARE) {
453 return browse_store_.get(); 461 return browse_store_.get();
454 } else if (list_id == safe_browsing_util::BINURL) { 462 } else if (list_id == safe_browsing_util::BINURL) {
455 return download_store_.get(); 463 return download_store_.get();
456 } else if (list_id == safe_browsing_util::CSDWHITELIST) { 464 } else if (list_id == safe_browsing_util::CSDWHITELIST) {
457 return csd_whitelist_store_.get(); 465 return csd_whitelist_store_.get();
458 } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) { 466 } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) {
459 return download_whitelist_store_.get(); 467 return download_whitelist_store_.get();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 DONT_LOCK_ON_MAIN_THREAD 536 DONT_LOCK_ON_MAIN_THREAD
529 }; 537 };
530 538
531 ReadTransaction(const ThreadSafeStateManager* outer, 539 ReadTransaction(const ThreadSafeStateManager* outer,
532 AutoLockRequirement auto_lock_requirement) 540 AutoLockRequirement auto_lock_requirement)
533 : outer_(outer) { 541 : outer_(outer) {
534 DCHECK(outer_); 542 DCHECK(outer_);
535 if (auto_lock_requirement == AutoLockRequirement::LOCK) 543 if (auto_lock_requirement == AutoLockRequirement::LOCK)
536 transaction_lock_.reset(new base::AutoLock(outer_->lock_)); 544 transaction_lock_.reset(new base::AutoLock(outer_->lock_));
537 else 545 else
538 DCHECK(outer_->thread_checker_.CalledOnValidThread()); 546 DCHECK(outer_->db_task_runner_->RunsTasksOnCurrentThread());
539 } 547 }
540 548
541 const ThreadSafeStateManager* outer_; 549 const ThreadSafeStateManager* outer_;
542 scoped_ptr<base::AutoLock> transaction_lock_; 550 scoped_ptr<base::AutoLock> transaction_lock_;
543 551
544 DISALLOW_COPY_AND_ASSIGN(ReadTransaction); 552 DISALLOW_COPY_AND_ASSIGN(ReadTransaction);
545 }; 553 };
546 554
547 class SafeBrowsingDatabaseNew::ThreadSafeStateManager::WriteTransaction { 555 class SafeBrowsingDatabaseNew::ThreadSafeStateManager::WriteTransaction {
548 public: 556 public:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 592
585 void clear_prefix_gethash_cache() { outer_->prefix_gethash_cache_.clear(); } 593 void clear_prefix_gethash_cache() { outer_->prefix_gethash_cache_.clear(); }
586 594
587 private: 595 private:
588 // Only ThreadSafeStateManager is allowed to build a WriteTransaction. 596 // Only ThreadSafeStateManager is allowed to build a WriteTransaction.
589 friend class ThreadSafeStateManager; 597 friend class ThreadSafeStateManager;
590 598
591 explicit WriteTransaction(ThreadSafeStateManager* outer) 599 explicit WriteTransaction(ThreadSafeStateManager* outer)
592 : outer_(outer), transaction_lock_(outer_->lock_) { 600 : outer_(outer), transaction_lock_(outer_->lock_) {
593 DCHECK(outer_); 601 DCHECK(outer_);
594 DCHECK(outer_->thread_checker_.CalledOnValidThread()); 602 DCHECK(outer_->db_task_runner_->RunsTasksOnCurrentThread());
595 } 603 }
596 604
597 SBWhitelist* SBWhitelistForId(SBWhitelistId id) { 605 SBWhitelist* SBWhitelistForId(SBWhitelistId id) {
598 switch (id) { 606 switch (id) {
599 case SBWhitelistId::CSD: 607 case SBWhitelistId::CSD:
600 return &outer_->csd_whitelist_; 608 return &outer_->csd_whitelist_;
601 case SBWhitelistId::DOWNLOAD: 609 case SBWhitelistId::DOWNLOAD:
602 return &outer_->download_whitelist_; 610 return &outer_->download_whitelist_;
603 case SBWhitelistId::INCLUSION: 611 case SBWhitelistId::INCLUSION:
604 return &outer_->inclusion_whitelist_; 612 return &outer_->inclusion_whitelist_;
605 } 613 }
606 NOTREACHED(); 614 NOTREACHED();
607 return nullptr; 615 return nullptr;
608 } 616 }
609 617
610 ThreadSafeStateManager* outer_; 618 ThreadSafeStateManager* outer_;
611 base::AutoLock transaction_lock_; 619 base::AutoLock transaction_lock_;
612 620
613 DISALLOW_COPY_AND_ASSIGN(WriteTransaction); 621 DISALLOW_COPY_AND_ASSIGN(WriteTransaction);
614 }; 622 };
615 623
616 SafeBrowsingDatabaseNew::ThreadSafeStateManager::ThreadSafeStateManager( 624 SafeBrowsingDatabaseNew::ThreadSafeStateManager::ThreadSafeStateManager(
617 const base::ThreadChecker& thread_checker) 625 scoped_refptr<base::SequencedTaskRunner> db_task_runner)
618 : thread_checker_(thread_checker) { 626 : db_task_runner_(db_task_runner) {
619 } 627 }
620 628
621 SafeBrowsingDatabaseNew::ThreadSafeStateManager::~ThreadSafeStateManager() { 629 SafeBrowsingDatabaseNew::ThreadSafeStateManager::~ThreadSafeStateManager() {
622 } 630 }
623 631
624 scoped_ptr<SafeBrowsingDatabaseNew::ReadTransaction> 632 scoped_ptr<SafeBrowsingDatabaseNew::ReadTransaction>
625 SafeBrowsingDatabaseNew::ThreadSafeStateManager::BeginReadTransaction() { 633 SafeBrowsingDatabaseNew::ThreadSafeStateManager::BeginReadTransaction() {
626 return make_scoped_ptr( 634 return make_scoped_ptr(
627 new ReadTransaction(this, ReadTransaction::AutoLockRequirement::LOCK)); 635 new ReadTransaction(this, ReadTransaction::AutoLockRequirement::LOCK));
628 } 636 }
629 637
630 scoped_ptr<SafeBrowsingDatabaseNew::ReadTransaction> SafeBrowsingDatabaseNew:: 638 scoped_ptr<SafeBrowsingDatabaseNew::ReadTransaction> SafeBrowsingDatabaseNew::
631 ThreadSafeStateManager::BeginReadTransactionNoLockOnMainThread() { 639 ThreadSafeStateManager::BeginReadTransactionNoLockOnMainThread() {
632 return make_scoped_ptr(new ReadTransaction( 640 return make_scoped_ptr(new ReadTransaction(
633 this, ReadTransaction::AutoLockRequirement::DONT_LOCK_ON_MAIN_THREAD)); 641 this, ReadTransaction::AutoLockRequirement::DONT_LOCK_ON_MAIN_THREAD));
634 } 642 }
635 643
636 scoped_ptr<SafeBrowsingDatabaseNew::WriteTransaction> 644 scoped_ptr<SafeBrowsingDatabaseNew::WriteTransaction>
637 SafeBrowsingDatabaseNew::ThreadSafeStateManager::BeginWriteTransaction() { 645 SafeBrowsingDatabaseNew::ThreadSafeStateManager::BeginWriteTransaction() {
638 return make_scoped_ptr(new WriteTransaction(this)); 646 return make_scoped_ptr(new WriteTransaction(this));
639 } 647 }
640 648
641 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew()
642 : SafeBrowsingDatabaseNew(new SafeBrowsingStoreFile, // browse_store
643 NULL, // download_store
644 NULL, // csd_whitelist_store
645 NULL, // download_whitelist_store
646 NULL, // inclusion_whitelist_store
647 NULL, // extension_blacklist_store
648 NULL, // side_effect_free_whitelist_store
649 NULL, // ip_blacklist_store
650 NULL) { // unwanted_software_store
651 DCHECK(browse_store_.get());
652 DCHECK(!download_store_.get());
653 DCHECK(!csd_whitelist_store_.get());
654 DCHECK(!download_whitelist_store_.get());
655 DCHECK(!inclusion_whitelist_store_.get());
656 DCHECK(!extension_blacklist_store_.get());
657 DCHECK(!side_effect_free_whitelist_store_.get());
658 DCHECK(!ip_blacklist_store_.get());
659 DCHECK(!unwanted_software_store_.get());
660 }
661
662 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( 649 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew(
650 scoped_refptr<base::SequencedTaskRunner> db_task_runner,
663 SafeBrowsingStore* browse_store, 651 SafeBrowsingStore* browse_store,
664 SafeBrowsingStore* download_store, 652 SafeBrowsingStore* download_store,
665 SafeBrowsingStore* csd_whitelist_store, 653 SafeBrowsingStore* csd_whitelist_store,
666 SafeBrowsingStore* download_whitelist_store, 654 SafeBrowsingStore* download_whitelist_store,
667 SafeBrowsingStore* inclusion_whitelist_store, 655 SafeBrowsingStore* inclusion_whitelist_store,
668 SafeBrowsingStore* extension_blacklist_store, 656 SafeBrowsingStore* extension_blacklist_store,
669 SafeBrowsingStore* side_effect_free_whitelist_store, 657 SafeBrowsingStore* side_effect_free_whitelist_store,
670 SafeBrowsingStore* ip_blacklist_store, 658 SafeBrowsingStore* ip_blacklist_store,
671 SafeBrowsingStore* unwanted_software_store) 659 SafeBrowsingStore* unwanted_software_store)
672 : state_manager_(thread_checker_), 660 : db_task_runner_(db_task_runner),
673 db_state_manager_(thread_checker_), 661 state_manager_(db_task_runner_),
662 db_state_manager_(db_task_runner_),
674 browse_store_(browse_store), 663 browse_store_(browse_store),
675 download_store_(download_store), 664 download_store_(download_store),
676 csd_whitelist_store_(csd_whitelist_store), 665 csd_whitelist_store_(csd_whitelist_store),
677 download_whitelist_store_(download_whitelist_store), 666 download_whitelist_store_(download_whitelist_store),
678 inclusion_whitelist_store_(inclusion_whitelist_store), 667 inclusion_whitelist_store_(inclusion_whitelist_store),
679 extension_blacklist_store_(extension_blacklist_store), 668 extension_blacklist_store_(extension_blacklist_store),
680 side_effect_free_whitelist_store_(side_effect_free_whitelist_store), 669 side_effect_free_whitelist_store_(side_effect_free_whitelist_store),
681 ip_blacklist_store_(ip_blacklist_store), 670 ip_blacklist_store_(ip_blacklist_store),
682 unwanted_software_store_(unwanted_software_store), 671 unwanted_software_store_(unwanted_software_store),
683 reset_factory_(this) { 672 reset_factory_(this) {
684 DCHECK(browse_store_.get()); 673 DCHECK(browse_store_.get());
685 } 674 }
686 675
687 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() { 676 SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() {
688 // The DCHECK is disabled due to crbug.com/338486 . 677 // The DCHECK is disabled due to crbug.com/338486 .
689 // DCHECK(thread_checker_.CalledOnValidThread()); 678 // DDCHECK(db_task_runner_->RunsTasksOnCurrentThread());
gab 2015/02/19 14:38:23 s/DDCHECK/DCHECK
Alexei Svitkine (slow) 2015/02/20 15:42:44 Done.
690 } 679 }
691 680
692 void SafeBrowsingDatabaseNew::Init(const base::FilePath& filename_base) { 681 void SafeBrowsingDatabaseNew::Init(const base::FilePath& filename_base) {
693 DCHECK(thread_checker_.CalledOnValidThread()); 682 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
694 683
695 db_state_manager_.init_filename_base(filename_base); 684 db_state_manager_.init_filename_base(filename_base);
696 685
697 // TODO(shess): The various stores are really only necessary while doing 686 // TODO(shess): The various stores are really only necessary while doing
698 // updates (see |UpdateFinished()|) or when querying a store directly (see 687 // updates (see |UpdateFinished()|) or when querying a store directly (see
699 // |ContainsDownloadUrl()|). 688 // |ContainsDownloadUrl()|).
700 // The store variables are also tested to see if a list is enabled. Perhaps 689 // The store variables are also tested to see if a list is enabled. Perhaps
701 // the stores could be refactored into an update object so that they are only 690 // the stores could be refactored into an update object so that they are only
702 // live in memory while being actively used. The sense of enabled probably 691 // live in memory while being actively used. The sense of enabled probably
703 // belongs in protocol_manager or database_manager. 692 // belongs in protocol_manager or database_manager.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 std::vector<SBAddFullHash> full_hashes; 822 std::vector<SBAddFullHash> full_hashes;
834 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) { 823 if (ip_blacklist_store_->GetAddFullHashes(&full_hashes)) {
835 LoadIpBlacklist(full_hashes); 824 LoadIpBlacklist(full_hashes);
836 } else { 825 } else {
837 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. 826 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list.
838 } 827 }
839 } 828 }
840 } 829 }
841 830
842 bool SafeBrowsingDatabaseNew::ResetDatabase() { 831 bool SafeBrowsingDatabaseNew::ResetDatabase() {
843 DCHECK(thread_checker_.CalledOnValidThread()); 832 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
844 833
845 // Delete files on disk. 834 // Delete files on disk.
846 // TODO(shess): Hard to see where one might want to delete without a 835 // TODO(shess): Hard to see where one might want to delete without a
847 // reset. Perhaps inline |Delete()|? 836 // reset. Perhaps inline |Delete()|?
848 if (!Delete()) 837 if (!Delete())
849 return false; 838 return false;
850 839
851 // Reset objects in memory. 840 // Reset objects in memory.
852 scoped_ptr<WriteTransaction> txn = state_manager_.BeginWriteTransaction(); 841 scoped_ptr<WriteTransaction> txn = state_manager_.BeginWriteTransaction();
853 txn->clear_prefix_gethash_cache(); 842 txn->clear_prefix_gethash_cache();
(...skipping 15 matching lines...) Expand all
869 } 858 }
870 859
871 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl( 860 bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl(
872 const GURL& url, 861 const GURL& url,
873 std::vector<SBPrefix>* prefix_hits, 862 std::vector<SBPrefix>* prefix_hits,
874 std::vector<SBFullHashResult>* cache_hits) { 863 std::vector<SBFullHashResult>* cache_hits) {
875 return PrefixSetContainsUrl(url, PrefixSetId::UNWANTED_SOFTWARE, prefix_hits, 864 return PrefixSetContainsUrl(url, PrefixSetId::UNWANTED_SOFTWARE, prefix_hits,
876 cache_hits); 865 cache_hits);
877 } 866 }
878 867
868 SafeBrowsingDatabaseNew::DatabaseStateManager::DatabaseStateManager(
gab 2015/02/19 14:38:23 Please insert these two just below ~ThreadSafeStat
Alexei Svitkine (slow) 2015/02/20 15:42:44 Done.
869 scoped_refptr<base::SequencedTaskRunner> db_task_runner)
870 : db_task_runner_(db_task_runner),
871 corruption_detected_(false),
872 change_detected_(false) {
873 }
874
875 SafeBrowsingDatabaseNew::DatabaseStateManager::~DatabaseStateManager() {
876 }
877
879 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( 878 bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl(
880 const GURL& url, 879 const GURL& url,
881 PrefixSetId prefix_set_id, 880 PrefixSetId prefix_set_id,
882 std::vector<SBPrefix>* prefix_hits, 881 std::vector<SBPrefix>* prefix_hits,
883 std::vector<SBFullHashResult>* cache_hits) { 882 std::vector<SBFullHashResult>* cache_hits) {
884 // Clear the results first. 883 // Clear the results first.
885 prefix_hits->clear(); 884 prefix_hits->clear();
886 cache_hits->clear(); 885 cache_hits->clear();
887 886
888 std::vector<SBFullHash> full_hashes; 887 std::vector<SBFullHash> full_hashes;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 std::sort(prefix_hits->begin(), prefix_hits->end()); 932 std::sort(prefix_hits->begin(), prefix_hits->end());
934 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()), 933 prefix_hits->erase(std::unique(prefix_hits->begin(), prefix_hits->end()),
935 prefix_hits->end()); 934 prefix_hits->end());
936 935
937 return !prefix_hits->empty() || !cache_hits->empty(); 936 return !prefix_hits->empty() || !cache_hits->empty();
938 } 937 }
939 938
940 bool SafeBrowsingDatabaseNew::ContainsDownloadUrl( 939 bool SafeBrowsingDatabaseNew::ContainsDownloadUrl(
941 const std::vector<GURL>& urls, 940 const std::vector<GURL>& urls,
942 std::vector<SBPrefix>* prefix_hits) { 941 std::vector<SBPrefix>* prefix_hits) {
943 DCHECK(thread_checker_.CalledOnValidThread()); 942 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
944 943
945 // Ignore this check when download checking is not enabled. 944 // Ignore this check when download checking is not enabled.
946 if (!download_store_.get()) 945 if (!download_store_.get())
947 return false; 946 return false;
948 947
949 std::vector<SBPrefix> prefixes; 948 std::vector<SBPrefix> prefixes;
950 GetDownloadUrlPrefixes(urls, &prefixes); 949 GetDownloadUrlPrefixes(urls, &prefixes);
951 return MatchAddPrefixes(download_store_.get(), 950 return MatchAddPrefixes(download_store_.get(),
952 safe_browsing_util::BINURL % 2, 951 safe_browsing_util::BINURL % 2,
953 prefixes, 952 prefixes,
(...skipping 14 matching lines...) Expand all
968 967
969 bool SafeBrowsingDatabaseNew::ContainsInclusionWhitelistedUrl(const GURL& url) { 968 bool SafeBrowsingDatabaseNew::ContainsInclusionWhitelistedUrl(const GURL& url) {
970 std::vector<SBFullHash> full_hashes; 969 std::vector<SBFullHash> full_hashes;
971 UrlToFullHashes(url, true, &full_hashes); 970 UrlToFullHashes(url, true, &full_hashes);
972 return ContainsWhitelistedHashes(SBWhitelistId::INCLUSION, full_hashes); 971 return ContainsWhitelistedHashes(SBWhitelistId::INCLUSION, full_hashes);
973 } 972 }
974 973
975 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes( 974 bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes(
976 const std::vector<SBPrefix>& prefixes, 975 const std::vector<SBPrefix>& prefixes,
977 std::vector<SBPrefix>* prefix_hits) { 976 std::vector<SBPrefix>* prefix_hits) {
978 DCHECK(thread_checker_.CalledOnValidThread()); 977 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
979 978
980 if (!extension_blacklist_store_) 979 if (!extension_blacklist_store_)
981 return false; 980 return false;
982 981
983 return MatchAddPrefixes(extension_blacklist_store_.get(), 982 return MatchAddPrefixes(extension_blacklist_store_.get(),
984 safe_browsing_util::EXTENSIONBLACKLIST % 2, 983 safe_browsing_util::EXTENSIONBLACKLIST % 2,
985 prefixes, 984 prefixes,
986 prefix_hits); 985 prefix_hits);
987 } 986 }
988 987
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 } 1064 }
1066 } 1065 }
1067 return false; 1066 return false;
1068 } 1067 }
1069 1068
1070 // Helper to insert add-chunk entries. 1069 // Helper to insert add-chunk entries.
1071 void SafeBrowsingDatabaseNew::InsertAddChunk( 1070 void SafeBrowsingDatabaseNew::InsertAddChunk(
1072 SafeBrowsingStore* store, 1071 SafeBrowsingStore* store,
1073 const safe_browsing_util::ListType list_id, 1072 const safe_browsing_util::ListType list_id,
1074 const SBChunkData& chunk_data) { 1073 const SBChunkData& chunk_data) {
1075 DCHECK(thread_checker_.CalledOnValidThread()); 1074 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1076 DCHECK(store); 1075 DCHECK(store);
1077 1076
1078 // The server can give us a chunk that we already have because 1077 // The server can give us a chunk that we already have because
1079 // it's part of a range. Don't add it again. 1078 // it's part of a range. Don't add it again.
1080 const int chunk_id = chunk_data.ChunkNumber(); 1079 const int chunk_id = chunk_data.ChunkNumber();
1081 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id); 1080 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id);
1082 if (store->CheckAddChunk(encoded_chunk_id)) 1081 if (store->CheckAddChunk(encoded_chunk_id))
1083 return; 1082 return;
1084 1083
1085 store->SetAddChunk(encoded_chunk_id); 1084 store->SetAddChunk(encoded_chunk_id);
1086 if (chunk_data.IsPrefix()) { 1085 if (chunk_data.IsPrefix()) {
1087 const size_t c = chunk_data.PrefixCount(); 1086 const size_t c = chunk_data.PrefixCount();
1088 for (size_t i = 0; i < c; ++i) { 1087 for (size_t i = 0; i < c; ++i) {
1089 store->WriteAddPrefix(encoded_chunk_id, chunk_data.PrefixAt(i)); 1088 store->WriteAddPrefix(encoded_chunk_id, chunk_data.PrefixAt(i));
1090 } 1089 }
1091 } else { 1090 } else {
1092 const size_t c = chunk_data.FullHashCount(); 1091 const size_t c = chunk_data.FullHashCount();
1093 for (size_t i = 0; i < c; ++i) { 1092 for (size_t i = 0; i < c; ++i) {
1094 store->WriteAddHash(encoded_chunk_id, chunk_data.FullHashAt(i)); 1093 store->WriteAddHash(encoded_chunk_id, chunk_data.FullHashAt(i));
1095 } 1094 }
1096 } 1095 }
1097 } 1096 }
1098 1097
1099 // Helper to insert sub-chunk entries. 1098 // Helper to insert sub-chunk entries.
1100 void SafeBrowsingDatabaseNew::InsertSubChunk( 1099 void SafeBrowsingDatabaseNew::InsertSubChunk(
1101 SafeBrowsingStore* store, 1100 SafeBrowsingStore* store,
1102 const safe_browsing_util::ListType list_id, 1101 const safe_browsing_util::ListType list_id,
1103 const SBChunkData& chunk_data) { 1102 const SBChunkData& chunk_data) {
1104 DCHECK(thread_checker_.CalledOnValidThread()); 1103 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1105 DCHECK(store); 1104 DCHECK(store);
1106 1105
1107 // The server can give us a chunk that we already have because 1106 // The server can give us a chunk that we already have because
1108 // it's part of a range. Don't add it again. 1107 // it's part of a range. Don't add it again.
1109 const int chunk_id = chunk_data.ChunkNumber(); 1108 const int chunk_id = chunk_data.ChunkNumber();
1110 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id); 1109 const int encoded_chunk_id = EncodeChunkId(chunk_id, list_id);
1111 if (store->CheckSubChunk(encoded_chunk_id)) 1110 if (store->CheckSubChunk(encoded_chunk_id))
1112 return; 1111 return;
1113 1112
1114 store->SetSubChunk(encoded_chunk_id); 1113 store->SetSubChunk(encoded_chunk_id);
(...skipping 12 matching lines...) Expand all
1127 const int encoded_add_chunk_id = EncodeChunkId(add_chunk_id, list_id); 1126 const int encoded_add_chunk_id = EncodeChunkId(add_chunk_id, list_id);
1128 store->WriteSubHash(encoded_chunk_id, encoded_add_chunk_id, 1127 store->WriteSubHash(encoded_chunk_id, encoded_add_chunk_id,
1129 chunk_data.FullHashAt(i)); 1128 chunk_data.FullHashAt(i));
1130 } 1129 }
1131 } 1130 }
1132 } 1131 }
1133 1132
1134 void SafeBrowsingDatabaseNew::InsertChunks( 1133 void SafeBrowsingDatabaseNew::InsertChunks(
1135 const std::string& list_name, 1134 const std::string& list_name,
1136 const std::vector<SBChunkData*>& chunks) { 1135 const std::vector<SBChunkData*>& chunks) {
1137 DCHECK(thread_checker_.CalledOnValidThread()); 1136 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1138 1137
1139 if (db_state_manager_.corruption_detected() || chunks.empty()) 1138 if (db_state_manager_.corruption_detected() || chunks.empty())
1140 return; 1139 return;
1141 1140
1142 const base::TimeTicks before = base::TimeTicks::Now(); 1141 const base::TimeTicks before = base::TimeTicks::Now();
1143 1142
1144 // TODO(shess): The caller should just pass list_id. 1143 // TODO(shess): The caller should just pass list_id.
1145 const safe_browsing_util::ListType list_id = 1144 const safe_browsing_util::ListType list_id =
1146 safe_browsing_util::GetListId(list_name); 1145 safe_browsing_util::GetListId(list_name);
1147 1146
(...skipping 14 matching lines...) Expand all
1162 NOTREACHED(); 1161 NOTREACHED();
1163 } 1162 }
1164 } 1163 }
1165 store->FinishChunk(); 1164 store->FinishChunk();
1166 1165
1167 UMA_HISTOGRAM_TIMES("SB2.ChunkInsert", base::TimeTicks::Now() - before); 1166 UMA_HISTOGRAM_TIMES("SB2.ChunkInsert", base::TimeTicks::Now() - before);
1168 } 1167 }
1169 1168
1170 void SafeBrowsingDatabaseNew::DeleteChunks( 1169 void SafeBrowsingDatabaseNew::DeleteChunks(
1171 const std::vector<SBChunkDelete>& chunk_deletes) { 1170 const std::vector<SBChunkDelete>& chunk_deletes) {
1172 DCHECK(thread_checker_.CalledOnValidThread()); 1171 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1173 1172
1174 if (db_state_manager_.corruption_detected() || chunk_deletes.empty()) 1173 if (db_state_manager_.corruption_detected() || chunk_deletes.empty())
1175 return; 1174 return;
1176 1175
1177 const std::string& list_name = chunk_deletes.front().list_name; 1176 const std::string& list_name = chunk_deletes.front().list_name;
1178 const safe_browsing_util::ListType list_id = 1177 const safe_browsing_util::ListType list_id =
1179 safe_browsing_util::GetListId(list_name); 1178 safe_browsing_util::GetListId(list_name);
1180 1179
1181 SafeBrowsingStore* store = GetStore(list_id); 1180 SafeBrowsingStore* store = GetStore(list_id);
1182 if (!store) return; 1181 if (!store) return;
(...skipping 30 matching lines...) Expand all
1213 // Insert any fullhash hits. Note that there may be one, multiple, or no 1212 // Insert any fullhash hits. Note that there may be one, multiple, or no
1214 // fullhashes for any given entry in |prefixes|. 1213 // fullhashes for any given entry in |prefixes|.
1215 for (size_t i = 0; i < full_hits.size(); ++i) { 1214 for (size_t i = 0; i < full_hits.size(); ++i) {
1216 const SBPrefix prefix = full_hits[i].hash.prefix; 1215 const SBPrefix prefix = full_hits[i].hash.prefix;
1217 (*prefix_gethash_cache)[prefix].full_hashes.push_back(full_hits[i]); 1216 (*prefix_gethash_cache)[prefix].full_hashes.push_back(full_hits[i]);
1218 } 1217 }
1219 } 1218 }
1220 1219
1221 bool SafeBrowsingDatabaseNew::UpdateStarted( 1220 bool SafeBrowsingDatabaseNew::UpdateStarted(
1222 std::vector<SBListChunkRanges>* lists) { 1221 std::vector<SBListChunkRanges>* lists) {
1223 DCHECK(thread_checker_.CalledOnValidThread()); 1222 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1224 DCHECK(lists); 1223 DCHECK(lists);
1225 1224
1226 // If |BeginUpdate()| fails, reset the database. 1225 // If |BeginUpdate()| fails, reset the database.
1227 if (!browse_store_->BeginUpdate()) { 1226 if (!browse_store_->BeginUpdate()) {
1228 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_BEGIN); 1227 RecordFailure(FAILURE_BROWSE_DATABASE_UPDATE_BEGIN);
1229 HandleCorruptDatabase(); 1228 HandleCorruptDatabase();
1230 return false; 1229 return false;
1231 } 1230 }
1232 1231
1233 if (download_store_.get() && !download_store_->BeginUpdate()) { 1232 if (download_store_.get() && !download_store_->BeginUpdate()) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 UpdateChunkRangesForList(unwanted_software_store_.get(), 1318 UpdateChunkRangesForList(unwanted_software_store_.get(),
1320 safe_browsing_util::kUnwantedUrlList, 1319 safe_browsing_util::kUnwantedUrlList,
1321 lists); 1320 lists);
1322 1321
1323 db_state_manager_.reset_corruption_detected(); 1322 db_state_manager_.reset_corruption_detected();
1324 db_state_manager_.reset_change_detected(); 1323 db_state_manager_.reset_change_detected();
1325 return true; 1324 return true;
1326 } 1325 }
1327 1326
1328 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) { 1327 void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) {
1329 DCHECK(thread_checker_.CalledOnValidThread()); 1328 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1330 1329
1331 // The update may have failed due to corrupt storage (for instance, 1330 // The update may have failed due to corrupt storage (for instance,
1332 // an excessive number of invalid add_chunks and sub_chunks). 1331 // an excessive number of invalid add_chunks and sub_chunks).
1333 // Double-check that the databases are valid. 1332 // Double-check that the databases are valid.
1334 // TODO(shess): Providing a checksum for the add_chunk and sub_chunk 1333 // TODO(shess): Providing a checksum for the add_chunk and sub_chunk
1335 // sections would allow throwing a corruption error in 1334 // sections would allow throwing a corruption error in
1336 // UpdateStarted(). 1335 // UpdateStarted().
1337 if (!update_succeeded) { 1336 if (!update_succeeded) {
1338 if (!browse_store_->CheckValidity()) 1337 if (!browse_store_->CheckValidity())
1339 DLOG(ERROR) << "Safe-browsing browse database corrupt."; 1338 DLOG(ERROR) << "Safe-browsing browse database corrupt.";
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 unwanted_software_store_.get(), PrefixSetId::UNWANTED_SOFTWARE, 1450 unwanted_software_store_.get(), PrefixSetId::UNWANTED_SOFTWARE,
1452 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH, 1451 FAILURE_UNWANTED_SOFTWARE_DATABASE_UPDATE_FINISH,
1453 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE, true); 1452 FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_WRITE, true);
1454 } 1453 }
1455 } 1454 }
1456 1455
1457 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( 1456 void SafeBrowsingDatabaseNew::UpdateWhitelistStore(
1458 const base::FilePath& store_filename, 1457 const base::FilePath& store_filename,
1459 SafeBrowsingStore* store, 1458 SafeBrowsingStore* store,
1460 SBWhitelistId whitelist_id) { 1459 SBWhitelistId whitelist_id) {
1461 DCHECK(thread_checker_.CalledOnValidThread()); 1460 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1462 1461
1463 if (!store) 1462 if (!store)
1464 return; 1463 return;
1465 1464
1466 // Note: |builder| will not be empty. The current data store implementation 1465 // Note: |builder| will not be empty. The current data store implementation
1467 // stores all full-length hashes as both full and prefix hashes. 1466 // stores all full-length hashes as both full and prefix hashes.
1468 PrefixSetBuilder builder; 1467 PrefixSetBuilder builder;
1469 std::vector<SBAddFullHash> full_hashes; 1468 std::vector<SBAddFullHash> full_hashes;
1470 if (!store->FinishUpdate(&builder, &full_hashes)) { 1469 if (!store->FinishUpdate(&builder, &full_hashes)) {
1471 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH); 1470 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH);
1472 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id); 1471 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id);
1473 return; 1472 return;
1474 } 1473 }
1475 1474
1476 RecordFileSizeHistogram(store_filename); 1475 RecordFileSizeHistogram(store_filename);
1477 1476
1478 #if defined(OS_MACOSX) 1477 #if defined(OS_MACOSX)
1479 base::mac::SetFileBackupExclusion(store_filename); 1478 base::mac::SetFileBackupExclusion(store_filename);
1480 #endif 1479 #endif
1481 1480
1482 LoadWhitelist(full_hashes, whitelist_id); 1481 LoadWhitelist(full_hashes, whitelist_id);
1483 } 1482 }
1484 1483
1485 void SafeBrowsingDatabaseNew::UpdateHashPrefixStore( 1484 void SafeBrowsingDatabaseNew::UpdateHashPrefixStore(
1486 const base::FilePath& store_filename, 1485 const base::FilePath& store_filename,
1487 SafeBrowsingStore* store, 1486 SafeBrowsingStore* store,
1488 FailureType failure_type) { 1487 FailureType failure_type) {
1489 DCHECK(thread_checker_.CalledOnValidThread()); 1488 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1490 1489
1491 // These results are not used after this call. Simply ignore the 1490 // These results are not used after this call. Simply ignore the
1492 // returned value after FinishUpdate(...). 1491 // returned value after FinishUpdate(...).
1493 PrefixSetBuilder builder; 1492 PrefixSetBuilder builder;
1494 std::vector<SBAddFullHash> add_full_hashes_result; 1493 std::vector<SBAddFullHash> add_full_hashes_result;
1495 1494
1496 if (!store->FinishUpdate(&builder, &add_full_hashes_result)) 1495 if (!store->FinishUpdate(&builder, &add_full_hashes_result))
1497 RecordFailure(failure_type); 1496 RecordFailure(failure_type);
1498 1497
1499 RecordFileSizeHistogram(store_filename); 1498 RecordFileSizeHistogram(store_filename);
1500 1499
1501 #if defined(OS_MACOSX) 1500 #if defined(OS_MACOSX)
1502 base::mac::SetFileBackupExclusion(store_filename); 1501 base::mac::SetFileBackupExclusion(store_filename);
1503 #endif 1502 #endif
1504 } 1503 }
1505 1504
1506 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( 1505 void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore(
1507 const base::FilePath& db_filename, 1506 const base::FilePath& db_filename,
1508 SafeBrowsingStore* url_store, 1507 SafeBrowsingStore* url_store,
1509 PrefixSetId prefix_set_id, 1508 PrefixSetId prefix_set_id,
1510 FailureType finish_failure_type, 1509 FailureType finish_failure_type,
1511 FailureType write_failure_type, 1510 FailureType write_failure_type,
1512 bool store_full_hashes_in_prefix_set) { 1511 bool store_full_hashes_in_prefix_set) {
1513 DCHECK(thread_checker_.CalledOnValidThread()); 1512 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1514 DCHECK(url_store); 1513 DCHECK(url_store);
1515 1514
1516 // Measure the amount of IO during the filter build. 1515 // Measure the amount of IO during the filter build.
1517 base::IoCounters io_before, io_after; 1516 base::IoCounters io_before, io_after;
1518 base::ProcessHandle handle = base::GetCurrentProcessHandle(); 1517 base::ProcessHandle handle = base::GetCurrentProcessHandle();
1519 scoped_ptr<base::ProcessMetrics> metric( 1518 scoped_ptr<base::ProcessMetrics> metric(
1520 #if !defined(OS_MACOSX) 1519 #if !defined(OS_MACOSX)
1521 base::ProcessMetrics::CreateProcessMetrics(handle) 1520 base::ProcessMetrics::CreateProcessMetrics(handle)
1522 #else 1521 #else
1523 // Getting stats only for the current process is enough, so NULL is fine. 1522 // Getting stats only for the current process is enough, so NULL is fine.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 } 1582 }
1584 1583
1585 RecordFileSizeHistogram(db_filename); 1584 RecordFileSizeHistogram(db_filename);
1586 1585
1587 #if defined(OS_MACOSX) 1586 #if defined(OS_MACOSX)
1588 base::mac::SetFileBackupExclusion(db_filename); 1587 base::mac::SetFileBackupExclusion(db_filename);
1589 #endif 1588 #endif
1590 } 1589 }
1591 1590
1592 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { 1591 void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() {
1593 DCHECK(thread_checker_.CalledOnValidThread()); 1592 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1594 1593
1595 // Note: prefixes will not be empty. The current data store implementation 1594 // Note: prefixes will not be empty. The current data store implementation
1596 // stores all full-length hashes as both full and prefix hashes. 1595 // stores all full-length hashes as both full and prefix hashes.
1597 PrefixSetBuilder builder; 1596 PrefixSetBuilder builder;
1598 std::vector<SBAddFullHash> full_hashes; 1597 std::vector<SBAddFullHash> full_hashes;
1599 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) { 1598 if (!ip_blacklist_store_->FinishUpdate(&builder, &full_hashes)) {
1600 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH); 1599 RecordFailure(FAILURE_IP_BLACKLIST_UPDATE_FINISH);
1601 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list. 1600 LoadIpBlacklist(std::vector<SBAddFullHash>()); // Clear the list.
1602 return; 1601 return;
1603 } 1602 }
1604 1603
1605 const base::FilePath ip_blacklist_filename = 1604 const base::FilePath ip_blacklist_filename =
1606 IpBlacklistDBFilename(db_state_manager_.filename_base()); 1605 IpBlacklistDBFilename(db_state_manager_.filename_base());
1607 1606
1608 RecordFileSizeHistogram(ip_blacklist_filename); 1607 RecordFileSizeHistogram(ip_blacklist_filename);
1609 1608
1610 #if defined(OS_MACOSX) 1609 #if defined(OS_MACOSX)
1611 base::mac::SetFileBackupExclusion(ip_blacklist_filename); 1610 base::mac::SetFileBackupExclusion(ip_blacklist_filename);
1612 #endif 1611 #endif
1613 1612
1614 LoadIpBlacklist(full_hashes); 1613 LoadIpBlacklist(full_hashes);
1615 } 1614 }
1616 1615
1617 void SafeBrowsingDatabaseNew::HandleCorruptDatabase() { 1616 void SafeBrowsingDatabaseNew::HandleCorruptDatabase() {
1618 DCHECK(thread_checker_.CalledOnValidThread()); 1617 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1619 1618
1620 // Reset the database after the current task has unwound (but only 1619 // Reset the database after the current task has unwound (but only
1621 // reset once within the scope of a given task). 1620 // reset once within the scope of a given task).
1622 if (!reset_factory_.HasWeakPtrs()) { 1621 if (!reset_factory_.HasWeakPtrs()) {
1623 RecordFailure(FAILURE_DATABASE_CORRUPT); 1622 RecordFailure(FAILURE_DATABASE_CORRUPT);
1624 base::MessageLoop::current()->PostTask(FROM_HERE, 1623 db_task_runner_->PostTask(
gab 2015/02/19 14:41:20 Oh also, interesting that this posts back to itsel
Alexei Svitkine (slow) 2015/02/20 15:42:44 Acknowledged.
1625 base::Bind(&SafeBrowsingDatabaseNew::OnHandleCorruptDatabase, 1624 FROM_HERE, base::Bind(&SafeBrowsingDatabaseNew::OnHandleCorruptDatabase,
1626 reset_factory_.GetWeakPtr())); 1625 reset_factory_.GetWeakPtr()));
1627 } 1626 }
1628 } 1627 }
1629 1628
1630 void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() { 1629 void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() {
1631 DCHECK(thread_checker_.CalledOnValidThread()); 1630 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1632 1631
1633 RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER); 1632 RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER);
1634 db_state_manager_.set_corruption_detected(); // Stop updating the database. 1633 db_state_manager_.set_corruption_detected(); // Stop updating the database.
1635 ResetDatabase(); 1634 ResetDatabase();
1636 1635
1637 // NOTE(shess): ResetDatabase() should remove the corruption, so this should 1636 // NOTE(shess): ResetDatabase() should remove the corruption, so this should
1638 // only happen once. If you are here because you are hitting this after a 1637 // only happen once. If you are here because you are hitting this after a
1639 // restart, then I would be very interested in working with you to figure out 1638 // restart, then I would be very interested in working with you to figure out
1640 // what is happening, since it may affect real users. 1639 // what is happening, since it may affect real users.
1641 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset"; 1640 DLOG(FATAL) << "SafeBrowsing database was corrupt and reset";
1642 } 1641 }
1643 1642
1644 // TODO(shess): I'm not clear why this code doesn't have any 1643 // TODO(shess): I'm not clear why this code doesn't have any
1645 // real error-handling. 1644 // real error-handling.
1646 void SafeBrowsingDatabaseNew::LoadPrefixSet(const base::FilePath& db_filename, 1645 void SafeBrowsingDatabaseNew::LoadPrefixSet(const base::FilePath& db_filename,
1647 WriteTransaction* txn, 1646 WriteTransaction* txn,
1648 PrefixSetId prefix_set_id, 1647 PrefixSetId prefix_set_id,
1649 FailureType read_failure_type) { 1648 FailureType read_failure_type) {
1650 DCHECK(thread_checker_.CalledOnValidThread()); 1649 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1651 DCHECK(txn); 1650 DCHECK(txn);
1652 DCHECK(!db_state_manager_.filename_base().empty()); 1651 DCHECK(!db_state_manager_.filename_base().empty());
1653 1652
1654 // Only use the prefix set if database is present and non-empty. 1653 // Only use the prefix set if database is present and non-empty.
1655 if (!GetFileSizeOrZero(db_filename)) 1654 if (!GetFileSizeOrZero(db_filename))
1656 return; 1655 return;
1657 1656
1658 // Cleanup any stale bloom filter (no longer used). 1657 // Cleanup any stale bloom filter (no longer used).
1659 // TODO(shess): Track existence to drive removal of this code? 1658 // TODO(shess): Track existence to drive removal of this code?
1660 const base::FilePath bloom_filter_filename = 1659 const base::FilePath bloom_filter_filename =
1661 BloomFilterForFilename(db_filename); 1660 BloomFilterForFilename(db_filename);
1662 base::DeleteFile(bloom_filter_filename, false); 1661 base::DeleteFile(bloom_filter_filename, false);
1663 1662
1664 const base::TimeTicks before = base::TimeTicks::Now(); 1663 const base::TimeTicks before = base::TimeTicks::Now();
1665 scoped_ptr<const PrefixSet> new_prefix_set = 1664 scoped_ptr<const PrefixSet> new_prefix_set =
1666 PrefixSet::LoadFile(PrefixSetForFilename(db_filename)); 1665 PrefixSet::LoadFile(PrefixSetForFilename(db_filename));
1667 if (!new_prefix_set.get()) 1666 if (!new_prefix_set.get())
1668 RecordFailure(read_failure_type); 1667 RecordFailure(read_failure_type);
1669 txn->SwapPrefixSet(prefix_set_id, new_prefix_set.Pass()); 1668 txn->SwapPrefixSet(prefix_set_id, new_prefix_set.Pass());
1670 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before); 1669 UMA_HISTOGRAM_TIMES("SB2.PrefixSetLoad", base::TimeTicks::Now() - before);
1671 } 1670 }
1672 1671
1673 bool SafeBrowsingDatabaseNew::Delete() { 1672 bool SafeBrowsingDatabaseNew::Delete() {
1674 DCHECK(thread_checker_.CalledOnValidThread()); 1673 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1675 DCHECK(!db_state_manager_.filename_base().empty()); 1674 DCHECK(!db_state_manager_.filename_base().empty());
1676 1675
1677 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the 1676 // TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the
1678 // store before calling DeleteStore(). DeleteStore() deletes transient files 1677 // store before calling DeleteStore(). DeleteStore() deletes transient files
1679 // in addition to the main file. Probably all of these should be converted to 1678 // in addition to the main file. Probably all of these should be converted to
1680 // a helper which calls Delete() if the store exists, else DeleteStore() on 1679 // a helper which calls Delete() if the store exists, else DeleteStore() on
1681 // the generated filename. 1680 // the generated filename.
1682 1681
1683 // TODO(shess): Determine if the histograms are useful in any way. I cannot 1682 // TODO(shess): Determine if the histograms are useful in any way. I cannot
1684 // recall any action taken as a result of their values, in which case it might 1683 // recall any action taken as a result of their values, in which case it might
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 if (!r12) 1752 if (!r12)
1754 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE); 1753 RecordFailure(FAILURE_UNWANTED_SOFTWARE_PREFIX_SET_DELETE);
1755 1754
1756 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11 && 1755 return r1 && r2 && r3 && r4 && r5 && r6 && r7 && r8 && r9 && r10 && r11 &&
1757 r12; 1756 r12;
1758 } 1757 }
1759 1758
1760 void SafeBrowsingDatabaseNew::WritePrefixSet(const base::FilePath& db_filename, 1759 void SafeBrowsingDatabaseNew::WritePrefixSet(const base::FilePath& db_filename,
1761 PrefixSetId prefix_set_id, 1760 PrefixSetId prefix_set_id,
1762 FailureType write_failure_type) { 1761 FailureType write_failure_type) {
1763 DCHECK(thread_checker_.CalledOnValidThread()); 1762 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1764 1763
1765 // Do not grab the lock to avoid contention while writing to disk. This is 1764 // Do not grab the lock to avoid contention while writing to disk. This is
1766 // safe as only this thread can ever modify |state_manager_|'s prefix sets 1765 // safe as only this thread can ever modify |state_manager_|'s prefix sets
1767 // anyways. 1766 // anyways.
1768 scoped_ptr<ReadTransaction> txn = 1767 scoped_ptr<ReadTransaction> txn =
1769 state_manager_.BeginReadTransactionNoLockOnMainThread(); 1768 state_manager_.BeginReadTransactionNoLockOnMainThread();
1770 const PrefixSet* prefix_set = txn->GetPrefixSet(prefix_set_id); 1769 const PrefixSet* prefix_set = txn->GetPrefixSet(prefix_set_id);
1771 1770
1772 if (!prefix_set) 1771 if (!prefix_set)
1773 return; 1772 return;
(...skipping 10 matching lines...) Expand all
1784 RecordFailure(write_failure_type); 1783 RecordFailure(write_failure_type);
1785 1784
1786 #if defined(OS_MACOSX) 1785 #if defined(OS_MACOSX)
1787 base::mac::SetFileBackupExclusion(prefix_set_filename); 1786 base::mac::SetFileBackupExclusion(prefix_set_filename);
1788 #endif 1787 #endif
1789 } 1788 }
1790 1789
1791 void SafeBrowsingDatabaseNew::LoadWhitelist( 1790 void SafeBrowsingDatabaseNew::LoadWhitelist(
1792 const std::vector<SBAddFullHash>& full_hashes, 1791 const std::vector<SBAddFullHash>& full_hashes,
1793 SBWhitelistId whitelist_id) { 1792 SBWhitelistId whitelist_id) {
1794 DCHECK(thread_checker_.CalledOnValidThread()); 1793 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1795 1794
1796 if (full_hashes.size() > kMaxWhitelistSize) { 1795 if (full_hashes.size() > kMaxWhitelistSize) {
1797 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id); 1796 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id);
1798 return; 1797 return;
1799 } 1798 }
1800 1799
1801 std::vector<SBFullHash> new_whitelist; 1800 std::vector<SBFullHash> new_whitelist;
1802 new_whitelist.reserve(full_hashes.size()); 1801 new_whitelist.reserve(full_hashes.size());
1803 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1802 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1804 it != full_hashes.end(); ++it) { 1803 it != full_hashes.end(); ++it) {
1805 new_whitelist.push_back(it->full_hash); 1804 new_whitelist.push_back(it->full_hash);
1806 } 1805 }
1807 std::sort(new_whitelist.begin(), new_whitelist.end(), SBFullHashLess); 1806 std::sort(new_whitelist.begin(), new_whitelist.end(), SBFullHashLess);
1808 1807
1809 SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl); 1808 SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl);
1810 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), 1809 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(),
1811 kill_switch, SBFullHashLess)) { 1810 kill_switch, SBFullHashLess)) {
1812 // The kill switch is whitelisted hence we whitelist all URLs. 1811 // The kill switch is whitelisted hence we whitelist all URLs.
1813 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id); 1812 state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id);
1814 } else { 1813 } else {
1815 state_manager_.BeginWriteTransaction()->SwapSBWhitelist(whitelist_id, 1814 state_manager_.BeginWriteTransaction()->SwapSBWhitelist(whitelist_id,
1816 &new_whitelist); 1815 &new_whitelist);
1817 } 1816 }
1818 } 1817 }
1819 1818
1820 void SafeBrowsingDatabaseNew::LoadIpBlacklist( 1819 void SafeBrowsingDatabaseNew::LoadIpBlacklist(
1821 const std::vector<SBAddFullHash>& full_hashes) { 1820 const std::vector<SBAddFullHash>& full_hashes) {
1822 DCHECK(thread_checker_.CalledOnValidThread()); 1821 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
1823 1822
1824 IPBlacklist new_blacklist; 1823 IPBlacklist new_blacklist;
1825 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1824 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1826 it != full_hashes.end(); 1825 it != full_hashes.end();
1827 ++it) { 1826 ++it) {
1828 const char* full_hash = it->full_hash.full_hash; 1827 const char* full_hash = it->full_hash.full_hash;
1829 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash)); 1828 DCHECK_EQ(crypto::kSHA256Length, arraysize(it->full_hash.full_hash));
1830 // The format of the IP blacklist is: 1829 // The format of the IP blacklist is:
1831 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes. 1830 // SHA-1(IPv6 prefix) + uint8(prefix size) + 11 unused bytes.
1832 std::string hashed_ip_prefix(full_hash, base::kSHA1Length); 1831 std::string hashed_ip_prefix(full_hash, base::kSHA1Length);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1918 else 1917 else
1919 NOTREACHED(); // Add support for new lists above. 1918 NOTREACHED(); // Add support for new lists above.
1920 1919
1921 // Histogram properties as in UMA_HISTOGRAM_COUNTS macro. 1920 // Histogram properties as in UMA_HISTOGRAM_COUNTS macro.
1922 base::HistogramBase* histogram_pointer = base::Histogram::FactoryGet( 1921 base::HistogramBase* histogram_pointer = base::Histogram::FactoryGet(
1923 histogram_name, 1, 1000000, 50, 1922 histogram_name, 1, 1000000, 50,
1924 base::HistogramBase::kUmaTargetedHistogramFlag); 1923 base::HistogramBase::kUmaTargetedHistogramFlag);
1925 1924
1926 histogram_pointer->Add(file_size_kilobytes); 1925 histogram_pointer->Add(file_size_kilobytes);
1927 } 1926 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698