OLD | NEW |
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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 if (prefix == iter->prefix && | 178 if (prefix == iter->prefix && |
179 GetListIdBit(iter->chunk_id) == list_bit) { | 179 GetListIdBit(iter->chunk_id) == list_bit) { |
180 prefix_hits->push_back(prefix); | 180 prefix_hits->push_back(prefix); |
181 found_match = true; | 181 found_match = true; |
182 } | 182 } |
183 } | 183 } |
184 } | 184 } |
185 return found_match; | 185 return found_match; |
186 } | 186 } |
187 | 187 |
| 188 // Order |SBFullHash| on the prefix part. This differs from SBFullHashLess on |
| 189 // little-endian platforms. |
| 190 bool SBFullHashPrefixLess(const SBFullHash& a, const SBFullHash& b) { |
| 191 return a.prefix < b.prefix; |
| 192 } |
| 193 |
| 194 // Remove items from |full_hashes| which have no prefix match in |db_hashes|. |
| 195 // |db_hashes| should be ordered by prefix. |
| 196 void TrimFullHashesByPrefix( |
| 197 const std::vector<SBAddFullHash>& db_hashes, |
| 198 std::vector<SBFullHash>* full_hashes) { |
| 199 std::sort(full_hashes->begin(), full_hashes->end(), SBFullHashPrefixLess); |
| 200 |
| 201 // |db_iter| steps through |db_hashes|. |
| 202 std::vector<SBAddFullHash>::const_iterator db_iter = db_hashes.begin(); |
| 203 |
| 204 // |check_iter| steps through |full_hashes|, |out_iter| only steps forward |
| 205 // when retaining values. |
| 206 std::vector<SBFullHash>::iterator check_iter = full_hashes->begin(); |
| 207 std::vector<SBFullHash>::iterator out_iter = full_hashes->begin(); |
| 208 |
| 209 // Process until the end of either vector. If |db_hashes| ends first, then |
| 210 // the remaining elements of |full_hashes| cannot match. |
| 211 while (check_iter != full_hashes->end() && db_iter != db_hashes.end()) { |
| 212 // Bump |db_iter| forward until the first element which is not less than |
| 213 // |check_iter|. |
| 214 while (db_iter != db_hashes.end() && |
| 215 db_iter->full_hash.prefix < check_iter->prefix) { |
| 216 ++db_iter; |
| 217 } |
| 218 |
| 219 // Keep |check_iter| if the prefix is equal to |db_iter|. |
| 220 if (db_iter != db_hashes.end() && |
| 221 check_iter->prefix == db_iter->full_hash.prefix) { |
| 222 *out_iter = *check_iter; |
| 223 out_iter++; |
| 224 } |
| 225 |
| 226 check_iter++; |
| 227 } |
| 228 |
| 229 // Erase any elements which did not match. |
| 230 full_hashes->erase(out_iter, full_hashes->end()); |
| 231 } |
| 232 |
188 // Find the entries in |full_hashes| with prefix in |prefix_hits|, and | 233 // Find the entries in |full_hashes| with prefix in |prefix_hits|, and |
189 // add them to |full_hits| if not expired. "Not expired" is when | 234 // add them to |full_hits| if not expired. "Not expired" is when |
190 // either |last_update| was recent enough, or the item has been | 235 // either |last_update| was recent enough, or the item has been |
191 // received recently enough. Expired items are not deleted because a | 236 // received recently enough. Expired items are not deleted because a |
192 // future update may make them acceptable again. | 237 // future update may make them acceptable again. |
193 // | 238 // |
194 // For efficiency reasons the code walks |prefix_hits| and | 239 // For efficiency reasons the code walks |prefix_hits| and |
195 // |full_hashes| in parallel, so they must be sorted by prefix. | 240 // |full_hashes| in parallel, so they must be sorted by prefix. |
196 void GetCachedFullHashesForBrowse(const std::vector<SBPrefix>& prefix_hits, | 241 void GetCachedFullHashesForBrowse(const std::vector<SBPrefix>& prefix_hits, |
197 const std::vector<SBAddFullHash>& full_hashes, | 242 const std::vector<SBAddFullHash>& full_hashes, |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 size_t miss_count = 0; | 742 size_t miss_count = 0; |
698 for (size_t i = 0; i < full_hashes.size(); ++i) { | 743 for (size_t i = 0; i < full_hashes.size(); ++i) { |
699 const SBPrefix prefix = full_hashes[i].prefix; | 744 const SBPrefix prefix = full_hashes[i].prefix; |
700 if (browse_prefix_set_->Exists(prefix)) { | 745 if (browse_prefix_set_->Exists(prefix)) { |
701 prefix_hits->push_back(prefix); | 746 prefix_hits->push_back(prefix); |
702 if (prefix_miss_cache_.count(prefix) > 0) | 747 if (prefix_miss_cache_.count(prefix) > 0) |
703 ++miss_count; | 748 ++miss_count; |
704 } | 749 } |
705 } | 750 } |
706 | 751 |
| 752 // Older code injected a prefix for each fullhash, which is now stripped on |
| 753 // update. Temporarily inject the removed |prefix_hits| to match the previous |
| 754 // code's results. The prefix-set check is to allow reads from older |
| 755 // databases (where the set contains the prefix) to match reads from updated |
| 756 // databases (where the set does not contain the prefix) until this code is |
| 757 // replaced. |
| 758 // |
| 759 // See <http://crbug.com/361248> |
| 760 TrimFullHashesByPrefix(full_browse_hashes_, &full_hashes); |
| 761 for (size_t i = 0; i < full_hashes.size(); ++i) { |
| 762 const SBPrefix prefix = full_hashes[i].prefix; |
| 763 if (!browse_prefix_set_->Exists(prefix)) { |
| 764 prefix_hits->push_back(prefix); |
| 765 if (prefix_miss_cache_.count(prefix) > 0) |
| 766 ++miss_count; |
| 767 } |
| 768 } |
| 769 |
707 // If all the prefixes are cached as 'misses', don't issue a GetHash. | 770 // If all the prefixes are cached as 'misses', don't issue a GetHash. |
708 if (miss_count == prefix_hits->size()) | 771 if (miss_count == prefix_hits->size()) |
709 return false; | 772 return false; |
710 | 773 |
711 // Find the matching full-hash results. |full_browse_hashes_| are from the | 774 // Find the matching full-hash results. |full_browse_hashes_| are from the |
712 // database, |pending_browse_hashes_| are from GetHash requests between | 775 // database, |pending_browse_hashes_| are from GetHash requests between |
713 // updates. | 776 // updates. |
714 std::sort(prefix_hits->begin(), prefix_hits->end()); | 777 std::sort(prefix_hits->begin(), prefix_hits->end()); |
715 | 778 |
716 GetCachedFullHashesForBrowse(*prefix_hits, full_browse_hashes_, | 779 GetCachedFullHashesForBrowse(*prefix_hits, full_browse_hashes_, |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 for (int i = 0; i < count; i++) { | 935 for (int i = 0; i < count; i++) { |
873 const SBPrefix prefix = entry->PrefixAt(i); | 936 const SBPrefix prefix = entry->PrefixAt(i); |
874 STATS_COUNTER("SB.PrefixAdd", 1); | 937 STATS_COUNTER("SB.PrefixAdd", 1); |
875 store->WriteAddPrefix(encoded_chunk_id, prefix); | 938 store->WriteAddPrefix(encoded_chunk_id, prefix); |
876 } | 939 } |
877 } else { | 940 } else { |
878 // Prefixes and hashes. | 941 // Prefixes and hashes. |
879 const base::Time receive_time = base::Time::Now(); | 942 const base::Time receive_time = base::Time::Now(); |
880 for (int i = 0; i < count; ++i) { | 943 for (int i = 0; i < count; ++i) { |
881 const SBFullHash full_hash = entry->FullHashAt(i); | 944 const SBFullHash full_hash = entry->FullHashAt(i); |
882 const SBPrefix prefix = full_hash.prefix; | |
883 | |
884 STATS_COUNTER("SB.PrefixAdd", 1); | |
885 store->WriteAddPrefix(encoded_chunk_id, prefix); | |
886 | 945 |
887 STATS_COUNTER("SB.PrefixAddFull", 1); | 946 STATS_COUNTER("SB.PrefixAddFull", 1); |
888 store->WriteAddHash(encoded_chunk_id, receive_time, full_hash); | 947 store->WriteAddHash(encoded_chunk_id, receive_time, full_hash); |
889 } | 948 } |
890 } | 949 } |
891 } | 950 } |
892 | 951 |
893 // Helper to iterate over all the entries in the hosts in |chunks| and | 952 // Helper to iterate over all the entries in the hosts in |chunks| and |
894 // add them to the store. | 953 // add them to the store. |
895 void SafeBrowsingDatabaseNew::InsertAddChunks( | 954 void SafeBrowsingDatabaseNew::InsertAddChunks( |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 STATS_COUNTER("SB.PrefixSub", 1); | 1008 STATS_COUNTER("SB.PrefixSub", 1); |
950 store->WriteSubPrefix(encoded_chunk_id, add_chunk_id, prefix); | 1009 store->WriteSubPrefix(encoded_chunk_id, add_chunk_id, prefix); |
951 } | 1010 } |
952 } else { | 1011 } else { |
953 // Prefixes and hashes. | 1012 // Prefixes and hashes. |
954 for (int i = 0; i < count; ++i) { | 1013 for (int i = 0; i < count; ++i) { |
955 const SBFullHash full_hash = entry->FullHashAt(i); | 1014 const SBFullHash full_hash = entry->FullHashAt(i); |
956 const int add_chunk_id = | 1015 const int add_chunk_id = |
957 EncodeChunkId(entry->ChunkIdAtPrefix(i), list_id); | 1016 EncodeChunkId(entry->ChunkIdAtPrefix(i), list_id); |
958 | 1017 |
959 STATS_COUNTER("SB.PrefixSub", 1); | |
960 store->WriteSubPrefix(encoded_chunk_id, add_chunk_id, full_hash.prefix); | |
961 | |
962 STATS_COUNTER("SB.PrefixSubFull", 1); | 1018 STATS_COUNTER("SB.PrefixSubFull", 1); |
963 store->WriteSubHash(encoded_chunk_id, add_chunk_id, full_hash); | 1019 store->WriteSubHash(encoded_chunk_id, add_chunk_id, full_hash); |
964 } | 1020 } |
965 } | 1021 } |
966 } | 1022 } |
967 | 1023 |
968 // Helper to iterate over all the entries in the hosts in |chunks| and | 1024 // Helper to iterate over all the entries in the hosts in |chunks| and |
969 // add them to the store. | 1025 // add them to the store. |
970 void SafeBrowsingDatabaseNew::InsertSubChunks( | 1026 void SafeBrowsingDatabaseNew::InsertSubChunks( |
971 safe_browsing_util::ListType list_id, | 1027 safe_browsing_util::ListType list_id, |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1683 base::AutoLock locked(lookup_lock_); | 1739 base::AutoLock locked(lookup_lock_); |
1684 ip_blacklist_.swap(new_blacklist); | 1740 ip_blacklist_.swap(new_blacklist); |
1685 } | 1741 } |
1686 | 1742 |
1687 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { | 1743 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { |
1688 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); | 1744 SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); |
1689 std::vector<SBFullHash> full_hashes; | 1745 std::vector<SBFullHash> full_hashes; |
1690 full_hashes.push_back(malware_kill_switch); | 1746 full_hashes.push_back(malware_kill_switch); |
1691 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); | 1747 return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); |
1692 } | 1748 } |
OLD | NEW |