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

Side by Side Diff: components/safe_browsing_db/v4_get_hash_protocol_manager.h

Issue 2233103002: Move full hash caching logic to v4_get_hash_protocol_manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: shess@ feedback - part 2. Created 4 years, 3 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 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 #ifndef COMPONENTS_SAFE_BROWSING_DB_V4_GET_HASH_PROTOCOL_MANAGER_H_ 5 #ifndef COMPONENTS_SAFE_BROWSING_DB_V4_GET_HASH_PROTOCOL_MANAGER_H_
6 #define COMPONENTS_SAFE_BROWSING_DB_V4_GET_HASH_PROTOCOL_MANAGER_H_ 6 #define COMPONENTS_SAFE_BROWSING_DB_V4_GET_HASH_PROTOCOL_MANAGER_H_
7 7
8 // A class that implements Chrome's interface with the SafeBrowsing V4 protocol. 8 // A class that implements Chrome's interface with the SafeBrowsing V4 protocol.
9 // 9 //
10 // The V4GetHashProtocolManager handles formatting and making requests of, and 10 // The V4GetHashProtocolManager handles formatting and making requests of, and
(...skipping 19 matching lines...) Expand all
30 30
31 class GURL; 31 class GURL;
32 32
33 namespace net { 33 namespace net {
34 class URLFetcher; 34 class URLFetcher;
35 class URLRequestContextGetter; 35 class URLRequestContextGetter;
36 } // namespace net 36 } // namespace net
37 37
38 namespace safe_browsing { 38 namespace safe_browsing {
39 39
40 // The matching hash prefixes and corresponding stores, for each full hash
41 // generated for a given URL.
42 typedef base::hash_map<FullHash, StoreAndHashPrefixes>
43 FullHashToStoreAndHashPrefixesMap;
44
45 // ----------------------------------------------------------------
46
47 // All information about a particular full hash i.e. negative TTL, store for
48 // which it is valid, and metadata associated with that store.
49 struct FullHashInfo {
50 public:
51 FullHash full_hash;
52
53 // The list for which this full hash is applicable.
54 UpdateListIdentifier list_id;
55
56 // The expiration time of the full hash for a particular store.
57 base::Time positive_expiry;
58
59 // Any metadata for this full hash for a particular store.
60 ThreatMetadata metadata;
61
62 FullHashInfo(const FullHash& full_hash,
63 const UpdateListIdentifier& list_id,
64 const base::Time& positive_expiry);
65 FullHashInfo(const FullHashInfo& other);
66 ~FullHashInfo();
67
68 bool operator==(const FullHashInfo& other) const;
69 bool operator!=(const FullHashInfo& other) const;
70
71 private:
72 FullHashInfo();
73 };
74
75 // Caches individual response from GETHASH response.
76 struct CachedHashPrefixInfo {
77 // The negative TTL for the hash prefix that leads to this
78 // CachedHashPrefixInfo. The client should not send any more requests for that
79 // hash prefix until this time.
80 base::Time negative_expiry;
81
82 // The list of all full hashes (and related info) that start with a
83 // particular hash prefix and are known to be unsafe.
84 std::vector<FullHashInfo> full_hash_infos;
85
86 CachedHashPrefixInfo();
87 CachedHashPrefixInfo(const CachedHashPrefixInfo& other);
88 ~CachedHashPrefixInfo();
89 };
90
91 // Cached full hashes received from the server for the corresponding hash
92 // prefixes.
93 typedef base::hash_map<HashPrefix, CachedHashPrefixInfo> FullHashCache;
94
95 // FullHashCallback is invoked when GetFullHashes completes. The parameter is
96 // the vector of full hash results. If empty, indicates that there were no
97 // matches, and that the resource is safe.
98 typedef base::Callback<void(const std::vector<FullHashInfo>&)> FullHashCallback;
99
100 // Information needed to update the cache and call the callback to post the
101 // results.
102 struct FullHashCallbackInfo {
103 FullHashCallbackInfo();
104 FullHashCallbackInfo(const std::vector<FullHashInfo>& cached_full_hash_infos,
105 const std::vector<HashPrefix>& prefixes_requested,
106 std::unique_ptr<net::URLFetcher> fetcher,
107 const FullHashToStoreAndHashPrefixesMap&
108 full_hash_to_store_and_hash_prefixes,
109 const FullHashCallback& callback);
110 ~FullHashCallbackInfo();
111
112 // The FullHashInfo objects retrieved from cache. These are merged with the
113 // results received from the server before invoking the callback.
114 std::vector<FullHashInfo> cached_full_hash_infos;
115
116 // The callback method to call after collecting the full hashes for given
117 // hash prefixes.
118 FullHashCallback callback;
119
120 // The fetcher that will return the response from the server. This is stored
121 // here as a unique pointer to be able to reason about its lifetime easily.
122 std::unique_ptr<net::URLFetcher> fetcher;
123
124 // The generated full hashes and the corresponding prefixes and the stores in
125 // which to look for a full hash match.
126 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes;
127
128 // The prefixes that were requested from the server.
129 std::vector<HashPrefix> prefixes_requested;
130 };
131
132 // ----------------------------------------------------------------
133
40 class V4GetHashProtocolManagerFactory; 134 class V4GetHashProtocolManagerFactory;
41 135
42 class V4GetHashProtocolManager : public net::URLFetcherDelegate, 136 class V4GetHashProtocolManager : public net::URLFetcherDelegate,
43 public base::NonThreadSafe { 137 public base::NonThreadSafe {
44 public: 138 public:
45 // FullHashCallback is invoked when GetFullHashes completes. 139 // Invoked when GetFullHashesWithApis completes.
46 // Parameters: 140 // Parameters:
47 // - The vector of full hash results. If empty, indicates that there 141 // - The API threat metadata for the given URL.
48 // were no matches, and that the resource is safe. 142 typedef base::Callback<void(const ThreatMetadata& md)>
49 // - The negative cache expire time of the result. This value may be 143 ThreatMetadataForApiCallback;
50 // uninitialized, and the results should not be cached in this case.
51 typedef base::Callback<void(const std::vector<SBFullHashResult>&,
52 const base::Time&)>
53 FullHashCallback;
54 144
55 ~V4GetHashProtocolManager() override; 145 ~V4GetHashProtocolManager() override;
56 146
147 // Create an instance of the safe browsing v4 protocol manager.
148 static std::unique_ptr<V4GetHashProtocolManager> Create(
149 net::URLRequestContextGetter* request_context_getter,
150 const base::hash_set<UpdateListIdentifier>& stores_to_request,
151 const V4ProtocolConfig& config);
152
57 // Makes the passed |factory| the factory used to instantiate 153 // Makes the passed |factory| the factory used to instantiate
58 // a V4GetHashProtocolManager. Useful for tests. 154 // a V4GetHashProtocolManager. Useful for tests.
59 static void RegisterFactory( 155 static void RegisterFactory(
60 std::unique_ptr<V4GetHashProtocolManagerFactory> factory); 156 std::unique_ptr<V4GetHashProtocolManagerFactory> factory);
61 157
62 // Create an instance of the safe browsing v4 protocol manager. 158 // Empties the cache.
63 static V4GetHashProtocolManager* Create( 159 void ClearCache();
64 net::URLRequestContextGetter* request_context_getter,
65 const V4ProtocolConfig& config);
66
67 // net::URLFetcherDelegate interface.
68 void OnURLFetchComplete(const net::URLFetcher* source) override;
69 160
70 // Retrieve the full hash for a set of prefixes, and invoke the callback 161 // Retrieve the full hash for a set of prefixes, and invoke the callback
71 // argument when the results are retrieved. The callback may be invoked 162 // argument when the results are retrieved. The callback may be invoked
72 // synchronously. 163 // synchronously.
73 virtual void GetFullHashes(const std::vector<SBPrefix>& prefixes, 164 virtual void GetFullHashes(const FullHashToStoreAndHashPrefixesMap&
74 const std::vector<PlatformType>& platforms, 165 full_hash_to_matching_hash_prefixes,
75 ThreatType threat_type,
76 FullHashCallback callback); 166 FullHashCallback callback);
77 167
78 // Retrieve the full hash and API metadata for a set of prefixes, and invoke 168 // Retrieve the full hash and API metadata for a URL, and invoke the callback
79 // the callback argument when the results are retrieved. The callback may be 169 // argument when the results are retrieved. The callback may be invoked
80 // invoked synchronously. 170 // synchronously.
81 virtual void GetFullHashesWithApis(const std::vector<SBPrefix>& prefixes, 171 // GetFullHashesWithApis is a special case of GetFullHashes. It is here
82 FullHashCallback callback); 172 // primarily for legacy reasons: so that DatabaseManager, which speaks PVer3,
83 173 // and V4LocalDatabaseManager, which speaks PVer4, can both use this class to
84 // Overrides the clock used to check the time. 174 // perform API lookups. Once PVer4 migration is complete, DatabaseManager
85 void SetClockForTests(std::unique_ptr<base::Clock> clock); 175 // should be deleted and then this method can be moved to the
176 // V4LocalDatabaseManager class.
177 // TODO(vakh): Move this method to V4LocalDatabaseManager after launching
178 // PVer4 in Chromium.
179 virtual void GetFullHashesWithApis(const GURL& url,
180 ThreatMetadataForApiCallback api_callback);
181
182 // net::URLFetcherDelegate interface.
183 void OnURLFetchComplete(const net::URLFetcher* source) override;
86 184
87 protected: 185 protected:
88 // Constructs a V4GetHashProtocolManager that issues 186 // Constructs a V4GetHashProtocolManager that issues
89 // network requests using |request_context_getter|. 187 // network requests using |request_context_getter|.
90 V4GetHashProtocolManager(net::URLRequestContextGetter* request_context_getter, 188 V4GetHashProtocolManager(
91 const V4ProtocolConfig& config); 189 net::URLRequestContextGetter* request_context_getter,
190 const base::hash_set<UpdateListIdentifier>& stores_to_request,
191 const V4ProtocolConfig& config);
92 192
93 private: 193 private:
94 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 194 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest, TestGetHashRequest);
95 TestGetHashRequest); 195 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest, TestParseHashResponse);
96 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 196 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
97 TestParseHashResponse);
98 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest,
99 TestParseHashResponseWrongThreatEntryType); 197 TestParseHashResponseWrongThreatEntryType);
100 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 198 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
101 TestParseHashThreatPatternType); 199 TestParseHashThreatPatternType);
102 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 200 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
103 TestParseHashResponseNonPermissionMetadata); 201 TestParseHashResponseNonPermissionMetadata);
104 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 202 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
105 TestParseHashResponseInconsistentThreatTypes); 203 TestParseHashResponseInconsistentThreatTypes);
106 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 204 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
107 TestGetHashErrorHandlingOK); 205 TestGetHashErrorHandlingOK);
108 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 206 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
207 TestResultsNotCachedForNegativeCacheDuration);
208 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
109 TestGetHashErrorHandlingNetwork); 209 TestGetHashErrorHandlingNetwork);
110 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 210 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
111 TestGetHashErrorHandlingResponseCode); 211 TestGetHashErrorHandlingResponseCode);
212 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest, GetCachedResults);
213 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest, TestUpdatesAreMerged);
214 friend class V4GetHashProtocolManagerTest;
112 friend class V4GetHashProtocolManagerFactoryImpl; 215 friend class V4GetHashProtocolManagerFactoryImpl;
113 216
217 FullHashCache* full_hash_cache_for_tests() { return &full_hash_cache_; }
218
219 // Looks up the cached results for full hashes in
220 // |full_hash_to_store_and_hash_prefixes|. Fills |prefixes_to_request| with
221 // the prefixes that need to be requested. Fills |cached_full_hash_infos|
222 // with the cached results.
223 // Note: It is valid for both |prefixes_to_request| and
224 // |cached_full_hash_infos| to be empty after this function finishes.
225 void GetFullHashCachedResults(
226 const FullHashToStoreAndHashPrefixesMap&
227 full_hash_to_store_and_hash_prefixes,
228 const base::Time& now,
229 std::vector<HashPrefix>* prefixes_to_request,
230 std::vector<FullHashInfo>* cached_full_hash_infos) const;
231
232 // Fills a FindFullHashesRequest protocol buffer for a request.
233 // Returns the serialized and base 64 encoded request as a string.
234 std::string GetHashRequest(
235 const std::vector<HashPrefix>& prefixes_to_request);
236
114 void GetHashUrlAndHeaders(const std::string& request_base64, 237 void GetHashUrlAndHeaders(const std::string& request_base64,
115 GURL* gurl, 238 GURL* gurl,
116 net::HttpRequestHeaders* headers) const; 239 net::HttpRequestHeaders* headers) const;
117 240
118 // Fills a FindFullHashesRequest protocol buffer for a request.
119 // Returns the serialized and base 64 encoded request as a string.
120 std::string GetHashRequest(const std::vector<SBPrefix>& prefixes,
121 const std::vector<PlatformType>& platforms,
122 ThreatType threat_type);
123
124 // Parses a FindFullHashesResponse protocol buffer and fills the results in
125 // |full_hashes| and |negative_cache_expire|. |data| is a serialized
126 // FindFullHashes protocol buffer. |negative_cache_expire| is the cache expiry
127 // time of the response for entities that did not match the threat list.
128 // Returns true if parsing is successful, false otherwise.
129 bool ParseHashResponse(const std::string& data_base64,
130 std::vector<SBFullHashResult>* full_hashes,
131 base::Time* negative_cache_expire);
132
133 // Resets the gethash error counter and multiplier.
134 void ResetGetHashErrors();
135
136 // Updates internal state for each GetHash response error, assuming that 241 // Updates internal state for each GetHash response error, assuming that
137 // the current time is |now|. 242 // the current time is |now|.
138 void HandleGetHashError(const base::Time& now); 243 void HandleGetHashError(const base::Time& now);
139 244
245 // Merges the results from the cache and the results from the server. The
246 // response from the server may include information for full hashes from
247 // stores other than those required by this client so it filters out those
248 // results that the client did not ask for.
249 void MergeResults(const FullHashToStoreAndHashPrefixesMap&
250 full_hash_to_store_and_hash_prefixes,
251 const std::vector<FullHashInfo>& full_hash_infos,
252 std::vector<FullHashInfo>* merged_full_hash_infos);
253
254 // Calls |api_callback| with an object of ThreatMetadata that contains
255 // permission API metadata for full hashes in those |full_hash_infos| that
256 // have a full hash in |full_hashes|.
257 void OnFullHashForApi(const ThreatMetadataForApiCallback& api_callback,
258 const base::hash_set<FullHash>& full_hashes,
259 const std::vector<FullHashInfo>& full_hash_infos);
260
261 // Parses a FindFullHashesResponse protocol buffer and fills the results in
262 // |full_hash_infos| and |negative_cache_expire|. |response_data| is a
263 // serialized FindFullHashes protocol buffer. |negative_cache_expire| is the
264 // cache expiry time of the hash prefixes that were requested. Returns true if
265 // parsing is successful; false otherwise.
266 bool ParseHashResponse(const std::string& response_data,
267 std::vector<FullHashInfo>* full_hash_infos,
268 base::Time* negative_cache_expire);
269
270 // Parses the store specific |metadata| information from |match|. Returns
271 // true if the metadata information was parsed correctly and was consistent
272 // with what's expected from that corresponding store; false otherwise.
273 bool ParseMetadata(const ThreatMatch& match, ThreatMetadata* metadata);
274
275 // Resets the gethash error counter and multiplier.
276 void ResetGetHashErrors();
277
278 // Overrides the clock used to check the time.
279 void SetClockForTests(std::unique_ptr<base::Clock> clock);
280
281 // Updates the state of the full hash cache upon receiving a valid response
282 // from the server.
283 void UpdateCache(const std::vector<HashPrefix>& prefixes_requested,
284 const std::vector<FullHashInfo>& full_hash_infos,
285 const base::Time& negative_cache_expire);
286
140 private: 287 private:
141 // Map of GetHash requests to parameters which created it. 288 // Map of GetHash requests to parameters which created it.
142 using HashRequests = base::hash_map< 289 using PendingHashRequests =
143 const net::URLFetcher*, 290 base::hash_map<const net::URLFetcher*,
144 std::pair<std::unique_ptr<net::URLFetcher>, FullHashCallback>>; 291 std::unique_ptr<FullHashCallbackInfo>>;
145 292
146 // The factory that controls the creation of V4GetHashProtocolManager. 293 // The factory that controls the creation of V4GetHashProtocolManager.
147 // This is used by tests. 294 // This is used by tests.
148 static V4GetHashProtocolManagerFactory* factory_; 295 static V4GetHashProtocolManagerFactory* factory_;
149 296
150 // Current active request (in case we need to cancel) for updates or chunks 297 // Current active request (in case we need to cancel) for updates or chunks
151 // from the SafeBrowsing service. We can only have one of these outstanding 298 // from the SafeBrowsing service. We can only have one of these outstanding
152 // at any given time unlike GetHash requests, which are tracked separately. 299 // at any given time unlike GetHash requests, which are tracked separately.
153 std::unique_ptr<net::URLFetcher> request_; 300 std::unique_ptr<net::URLFetcher> request_;
154 301
155 // The number of HTTP response errors since the the last successful HTTP 302 // The number of HTTP response errors since the the last successful HTTP
156 // response, used for request backoff timing. 303 // response, used for request backoff timing.
157 size_t gethash_error_count_; 304 size_t gethash_error_count_;
158 305
159 // Multiplier for the backoff error after the second. 306 // Multiplier for the backoff error after the second.
160 size_t gethash_back_off_mult_; 307 size_t gethash_back_off_mult_;
161 308
162 HashRequests hash_requests_; 309 PendingHashRequests pending_hash_requests_;
163 310
164 // For v4, the next gethash time is set to the backoff time is the last 311 // For v4, the next gethash time is set to the backoff time is the last
165 // response was an error, or the minimum wait time if the last response was 312 // response was an error, or the minimum wait time if the last response was
166 // successful. 313 // successful.
167 base::Time next_gethash_time_; 314 base::Time next_gethash_time_;
168 315
169 // The config of the client making Pver4 requests. 316 // The config of the client making Pver4 requests.
170 const V4ProtocolConfig config_; 317 const V4ProtocolConfig config_;
171 318
172 // The context we use to issue network requests. 319 // The context we use to issue network requests.
173 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 320 scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
174 321
175 // ID for URLFetchers for testing. 322 // ID for URLFetchers for testing.
176 int url_fetcher_id_; 323 int url_fetcher_id_;
177 324
178 // The clock used to vend times. 325 // The clock used to vend times.
179 std::unique_ptr<base::Clock> clock_; 326 std::unique_ptr<base::Clock> clock_;
180 327
328 // A cache of full hash results.
329 FullHashCache full_hash_cache_;
330
331 // The following sets represent the combination of lists that we would always
332 // request from the server, irrespective of which list we found the hash
333 // prefix match in.
334 base::hash_set<PlatformType> platform_types_;
335 base::hash_set<ThreatEntryType> threat_entry_types_;
336 base::hash_set<ThreatType> threat_types_;
337
181 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManager); 338 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManager);
182 }; 339 };
183 340
184 // Interface of a factory to create V4GetHashProtocolManager. Useful for tests. 341 // Interface of a factory to create V4GetHashProtocolManager. Useful for tests.
185 class V4GetHashProtocolManagerFactory { 342 class V4GetHashProtocolManagerFactory {
186 public: 343 public:
187 V4GetHashProtocolManagerFactory() {} 344 V4GetHashProtocolManagerFactory() {}
188 virtual ~V4GetHashProtocolManagerFactory() {} 345 virtual ~V4GetHashProtocolManagerFactory() {}
189 virtual V4GetHashProtocolManager* CreateProtocolManager( 346 virtual std::unique_ptr<V4GetHashProtocolManager> CreateProtocolManager(
190 net::URLRequestContextGetter* request_context_getter, 347 net::URLRequestContextGetter* request_context_getter,
348 const base::hash_set<UpdateListIdentifier>& stores_to_request,
191 const V4ProtocolConfig& config) = 0; 349 const V4ProtocolConfig& config) = 0;
192 350
193 private: 351 private:
194 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManagerFactory); 352 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManagerFactory);
195 }; 353 };
196 354
355 #ifndef NDEBUG
356 std::ostream& operator<<(std::ostream& os, const FullHashInfo& id);
357 #endif
358
197 } // namespace safe_browsing 359 } // namespace safe_browsing
198 360
199 #endif // COMPONENTS_SAFE_BROWSING_DB_V4_GET_HASH_PROTOCOL_MANAGER_H_ 361 #endif // COMPONENTS_SAFE_BROWSING_DB_V4_GET_HASH_PROTOCOL_MANAGER_H_
OLDNEW
« no previous file with comments | « components/safe_browsing_db/v4_database_unittest.cc ('k') | components/safe_browsing_db/v4_get_hash_protocol_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698