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

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: Remove more tests from db_manager. Simplify another test. 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_ttl;
58
59 // Any metadata for this full hash for a particular store.
60 ThreatMetadata metadata;
61
62 explicit FullHashInfo(const FullHash& full_hash,
Nathan Parker 2016/09/09 21:26:21 nit: I don't think you need explicit if the ctor h
vakh (use Gerrit instead) 2016/09/09 23:25:18 Good catch. Also not for copy constructors so remo
63 const UpdateListIdentifier& list_id,
64 const base::Time& positive_ttl);
65 explicit 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_ttl;
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.
96 // Parameters:
97 // - The vector of full hash results. If empty, indicates that there
98 // were no matches, and that the resource is safe.
99 typedef base::Callback<void(const std::vector<FullHashInfo>&)> FullHashCallback;
100
101 // Information needed to update the cache and call the callback to post the
102 // results.
103 struct FullHashCallbackInfo {
104 FullHashCallbackInfo();
105 explicit FullHashCallbackInfo(
Nathan Parker 2016/09/09 21:26:21 nit: don't need explicit
vakh (use Gerrit instead) 2016/09/09 23:25:18 Done.
106 const std::vector<FullHashInfo>& cached_full_hash_infos,
107 const std::vector<HashPrefix>& prefixes_requested,
108 std::unique_ptr<net::URLFetcher> fetcher,
109 const FullHashToStoreAndHashPrefixesMap&
110 full_hash_to_store_and_hash_prefixes,
111 FullHashCallback callback);
Nathan Parker 2016/09/09 21:26:21 nit: Pass callbacks by const-reference (they do re
vakh (use Gerrit instead) 2016/09/09 23:25:18 Done.
112 ~FullHashCallbackInfo();
113
114 // The FullHashInfo objects retrieved from cache. These are merged with the
115 // results received from the server before invoking the callback.
116 std::vector<FullHashInfo> cached_full_hash_infos;
117
118 // The callback method to call after collecting the full hashes for given
119 // hash prefixes.
120 FullHashCallback callback;
121
122 // The fetcher that will return the response from the server.
Nathan Parker 2016/09/09 21:26:21 Maybe comment on why it's here (so you can delete
vakh (use Gerrit instead) 2016/09/09 23:25:18 Done.
123 std::unique_ptr<net::URLFetcher> fetcher;
124
125 // The generated full hashes and the corresponding prefixes and the stores in
126 // which to look for a full hash match.
127 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes;
128
129 // The prefixes that were requested from the server.
130 std::vector<HashPrefix> prefixes_requested;
131 };
132
133 // ----------------------------------------------------------------
134
40 class V4GetHashProtocolManagerFactory; 135 class V4GetHashProtocolManagerFactory;
41 136
42 class V4GetHashProtocolManager : public net::URLFetcherDelegate, 137 class V4GetHashProtocolManager : public net::URLFetcherDelegate,
43 public base::NonThreadSafe { 138 public base::NonThreadSafe {
44 public: 139 public:
45 // FullHashCallback is invoked when GetFullHashes completes. 140 // Invoked when GetFullHashesWithApis completes.
46 // Parameters: 141 // Parameters:
47 // - The vector of full hash results. If empty, indicates that there 142 // - The API threat metadata for the given URL.
48 // were no matches, and that the resource is safe. 143 typedef base::Callback<void(const ThreatMetadata& md)>
49 // - The negative cache expire time of the result. This value may be 144 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 145
55 ~V4GetHashProtocolManager() override; 146 ~V4GetHashProtocolManager() override;
56 147
148 // Create an instance of the safe browsing v4 protocol manager.
149 static std::unique_ptr<V4GetHashProtocolManager> Create(
150 net::URLRequestContextGetter* request_context_getter,
151 const base::hash_set<UpdateListIdentifier>& stores_to_request,
152 const V4ProtocolConfig& config);
153
57 // Makes the passed |factory| the factory used to instantiate 154 // Makes the passed |factory| the factory used to instantiate
58 // a V4GetHashProtocolManager. Useful for tests. 155 // a V4GetHashProtocolManager. Useful for tests.
59 static void RegisterFactory( 156 static void RegisterFactory(
60 std::unique_ptr<V4GetHashProtocolManagerFactory> factory); 157 std::unique_ptr<V4GetHashProtocolManagerFactory> factory);
61 158
62 // Create an instance of the safe browsing v4 protocol manager. 159 // Empties the cache.
63 static V4GetHashProtocolManager* Create( 160 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 161
70 // Retrieve the full hash for a set of prefixes, and invoke the callback 162 // 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 163 // argument when the results are retrieved. The callback may be invoked
72 // synchronously. 164 // synchronously.
73 virtual void GetFullHashes(const std::vector<SBPrefix>& prefixes, 165 virtual void GetFullHashes(const FullHashToStoreAndHashPrefixesMap&
74 const std::vector<PlatformType>& platforms, 166 full_hash_to_matching_hash_prefixes,
75 ThreatType threat_type,
76 FullHashCallback callback); 167 FullHashCallback callback);
77 168
78 // Retrieve the full hash and API metadata for a set of prefixes, and invoke 169 // 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 170 // argument when the results are retrieved. The callback may be invoked
80 // invoked synchronously. 171 // synchronously.
Nathan Parker 2016/09/09 21:26:21 Add a comment on what "apis" is and why it's diffe
vakh (use Gerrit instead) 2016/09/09 23:25:18 Done.
81 virtual void GetFullHashesWithApis(const std::vector<SBPrefix>& prefixes, 172 virtual void GetFullHashesWithApis(const GURL& url,
82 FullHashCallback callback); 173 ThreatMetadataForApiCallback api_callback);
83 174
84 // Overrides the clock used to check the time. 175 // net::URLFetcherDelegate interface.
85 void SetClockForTests(std::unique_ptr<base::Clock> clock); 176 void OnURLFetchComplete(const net::URLFetcher* source) override;
86 177
87 protected: 178 protected:
88 // Constructs a V4GetHashProtocolManager that issues 179 // Constructs a V4GetHashProtocolManager that issues
89 // network requests using |request_context_getter|. 180 // network requests using |request_context_getter|.
90 V4GetHashProtocolManager(net::URLRequestContextGetter* request_context_getter, 181 V4GetHashProtocolManager(
91 const V4ProtocolConfig& config); 182 net::URLRequestContextGetter* request_context_getter,
183 const base::hash_set<UpdateListIdentifier>& stores_to_request,
184 const V4ProtocolConfig& config);
92 185
93 private: 186 private:
94 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 187 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest, TestGetHashRequest);
95 TestGetHashRequest); 188 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest, TestParseHashResponse);
96 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 189 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
97 TestParseHashResponse);
98 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest,
99 TestParseHashResponseWrongThreatEntryType); 190 TestParseHashResponseWrongThreatEntryType);
100 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 191 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
101 TestParseHashThreatPatternType); 192 TestParseHashThreatPatternType);
102 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 193 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
103 TestParseHashResponseNonPermissionMetadata); 194 TestParseHashResponseNonPermissionMetadata);
104 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 195 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
105 TestParseHashResponseInconsistentThreatTypes); 196 TestParseHashResponseInconsistentThreatTypes);
106 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 197 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
107 TestGetHashErrorHandlingOK); 198 TestGetHashErrorHandlingOK);
108 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 199 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
200 TestResultsNotCachedForNegativeCacheDuration);
201 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
109 TestGetHashErrorHandlingNetwork); 202 TestGetHashErrorHandlingNetwork);
110 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingV4GetHashProtocolManagerTest, 203 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest,
111 TestGetHashErrorHandlingResponseCode); 204 TestGetHashErrorHandlingResponseCode);
205 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest, GetCachedResults);
206 FRIEND_TEST_ALL_PREFIXES(V4GetHashProtocolManagerTest, TestUpdatesAreMerged);
207 friend class V4GetHashProtocolManagerTest;
112 friend class V4GetHashProtocolManagerFactoryImpl; 208 friend class V4GetHashProtocolManagerFactoryImpl;
113 209
210 FullHashCache* full_hash_cache_for_tests() { return &full_hash_cache_; }
211
212 // Looks up the cached results for full hashes in
213 // |full_hash_to_store_and_hash_prefixes|. Fills |prefixes_to_request| with
214 // the prefixes that need to be requested. Fills |cached_full_hash_infos|
215 // with the cached results.
216 // Note: It is valid for both |prefixes_to_request| and
217 // |cached_full_hash_infos| to be empty after this function finishes.
218 void GetFullHashCachedResults(
219 const FullHashToStoreAndHashPrefixesMap&
220 full_hash_to_store_and_hash_prefixes,
221 const base::Time& now,
222 std::vector<HashPrefix>* prefixes_to_request,
223 std::vector<FullHashInfo>* cached_full_hash_infos) const;
224
225 // Fills a FindFullHashesRequest protocol buffer for a request.
226 // Returns the serialized and base 64 encoded request as a string.
227 std::string GetHashRequest(
228 const std::vector<HashPrefix>& prefixes_to_request);
229
114 void GetHashUrlAndHeaders(const std::string& request_base64, 230 void GetHashUrlAndHeaders(const std::string& request_base64,
115 GURL* gurl, 231 GURL* gurl,
116 net::HttpRequestHeaders* headers) const; 232 net::HttpRequestHeaders* headers) const;
117 233
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 234 // Updates internal state for each GetHash response error, assuming that
137 // the current time is |now|. 235 // the current time is |now|.
138 void HandleGetHashError(const base::Time& now); 236 void HandleGetHashError(const base::Time& now);
139 237
238 // Merges the results from the cache and the results from the server. The
239 // response from the server may include information for full hashes from
240 // stores other than those required by this client so it filters out those
241 // results that the client did not ask for.
242 void MergeResults(const FullHashToStoreAndHashPrefixesMap&
243 full_hash_to_store_and_hash_prefixes,
244 const std::vector<FullHashInfo>& full_hash_infos,
245 std::vector<FullHashInfo>* merged_full_hash_infos);
246
247 // Calls |api_callback| with a an object of ThreatMetadata that contains
248 // permission api metadata for full hashes in those |full_hash_infos| that
Nathan Parker 2016/09/09 21:26:21 nit: capitalize API (And TTL for that matter) when
vakh (use Gerrit instead) 2016/09/09 23:25:18 Done.
249 // have a full hash in |full_hashes|.
250 void OnFullHashForApi(ThreatMetadataForApiCallback api_callback,
Nathan Parker 2016/09/09 21:26:21 pass callbacks by const ref.
vakh (use Gerrit instead) 2016/09/09 23:25:18 Done.
251 const base::hash_set<FullHash>& full_hashes,
252 const std::vector<FullHashInfo>& full_hash_infos);
253
254 // Parses a FindFullHashesResponse protocol buffer and fills the results in
255 // |full_hash_infos| and |negative_cache_expire|. |data| is a serialized
256 // FindFullHashes protocol buffer. |negative_cache_expire| is the cache
257 // expiry time of the hash prefixes that were requested. Returns true if
258 // parsing is successful; false otherwise.
259 bool ParseHashResponse(const std::string& data,
Nathan Parker 2016/09/09 21:26:21 nit: How about response_data instead of data?
vakh (use Gerrit instead) 2016/09/09 23:25:18 Done.
260 std::vector<FullHashInfo>* full_hash_infos,
261 base::Time* negative_cache_expire);
262
263 // Parses the store specific |metadata| information from the |match|.
Nathan Parker 2016/09/09 21:26:21 nit: describe what it returns
vakh (use Gerrit instead) 2016/09/09 23:25:18 Done.
264 bool ParseMetadata(const ThreatMatch& match, ThreatMetadata* metadata);
265
266 // Resets the gethash error counter and multiplier.
267 void ResetGetHashErrors();
268
269 // Overrides the clock used to check the time.
270 void SetClockForTests(std::unique_ptr<base::Clock> clock);
271
272 // Updates the state of the full hash cache upon receiving a valid response
273 // from the server.
274 void UpdateCache(const std::vector<HashPrefix>& prefixes_requested,
275 const std::vector<FullHashInfo>& full_hash_infos,
276 const base::Time& negative_cache_expire);
277
140 private: 278 private:
141 // Map of GetHash requests to parameters which created it. 279 // Map of GetHash requests to parameters which created it.
142 using HashRequests = base::hash_map< 280 using PendingHashRequests =
143 const net::URLFetcher*, 281 base::hash_map<const net::URLFetcher*,
144 std::pair<std::unique_ptr<net::URLFetcher>, FullHashCallback>>; 282 std::unique_ptr<FullHashCallbackInfo>>;
145 283
146 // The factory that controls the creation of V4GetHashProtocolManager. 284 // The factory that controls the creation of V4GetHashProtocolManager.
147 // This is used by tests. 285 // This is used by tests.
148 static V4GetHashProtocolManagerFactory* factory_; 286 static V4GetHashProtocolManagerFactory* factory_;
149 287
150 // Current active request (in case we need to cancel) for updates or chunks 288 // 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 289 // from the SafeBrowsing service. We can only have one of these outstanding
152 // at any given time unlike GetHash requests, which are tracked separately. 290 // at any given time unlike GetHash requests, which are tracked separately.
153 std::unique_ptr<net::URLFetcher> request_; 291 std::unique_ptr<net::URLFetcher> request_;
154 292
155 // The number of HTTP response errors since the the last successful HTTP 293 // The number of HTTP response errors since the the last successful HTTP
156 // response, used for request backoff timing. 294 // response, used for request backoff timing.
157 size_t gethash_error_count_; 295 size_t gethash_error_count_;
158 296
159 // Multiplier for the backoff error after the second. 297 // Multiplier for the backoff error after the second.
160 size_t gethash_back_off_mult_; 298 size_t gethash_back_off_mult_;
161 299
162 HashRequests hash_requests_; 300 PendingHashRequests pending_hash_requests_;
163 301
164 // For v4, the next gethash time is set to the backoff time is the last 302 // 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 303 // response was an error, or the minimum wait time if the last response was
166 // successful. 304 // successful.
167 base::Time next_gethash_time_; 305 base::Time next_gethash_time_;
168 306
169 // The config of the client making Pver4 requests. 307 // The config of the client making Pver4 requests.
170 const V4ProtocolConfig config_; 308 const V4ProtocolConfig config_;
171 309
172 // The context we use to issue network requests. 310 // The context we use to issue network requests.
173 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 311 scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
174 312
175 // ID for URLFetchers for testing. 313 // ID for URLFetchers for testing.
176 int url_fetcher_id_; 314 int url_fetcher_id_;
177 315
178 // The clock used to vend times. 316 // The clock used to vend times.
179 std::unique_ptr<base::Clock> clock_; 317 std::unique_ptr<base::Clock> clock_;
180 318
319 // A cache of full hash results.
320 FullHashCache full_hash_cache_;
321
322 // The following sets represent the combination of lists that we would always
323 // request from the server, irrespective of which list we found the hash
324 // prefix match in.
325 base::hash_set<PlatformType> platform_types_;
326 base::hash_set<ThreatEntryType> threat_entry_types_;
327 base::hash_set<ThreatType> threat_types_;
328
181 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManager); 329 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManager);
182 }; 330 };
183 331
184 // Interface of a factory to create V4GetHashProtocolManager. Useful for tests. 332 // Interface of a factory to create V4GetHashProtocolManager. Useful for tests.
185 class V4GetHashProtocolManagerFactory { 333 class V4GetHashProtocolManagerFactory {
186 public: 334 public:
187 V4GetHashProtocolManagerFactory() {} 335 V4GetHashProtocolManagerFactory() {}
188 virtual ~V4GetHashProtocolManagerFactory() {} 336 virtual ~V4GetHashProtocolManagerFactory() {}
189 virtual V4GetHashProtocolManager* CreateProtocolManager( 337 virtual std::unique_ptr<V4GetHashProtocolManager> CreateProtocolManager(
190 net::URLRequestContextGetter* request_context_getter, 338 net::URLRequestContextGetter* request_context_getter,
339 const base::hash_set<UpdateListIdentifier>& stores_to_request,
191 const V4ProtocolConfig& config) = 0; 340 const V4ProtocolConfig& config) = 0;
192 341
193 private: 342 private:
194 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManagerFactory); 343 DISALLOW_COPY_AND_ASSIGN(V4GetHashProtocolManagerFactory);
195 }; 344 };
196 345
346 #ifndef NDEBUG
347 std::ostream& operator<<(std::ostream& os, const FullHashInfo& id);
348 #endif
349
197 } // namespace safe_browsing 350 } // namespace safe_browsing
198 351
199 #endif // COMPONENTS_SAFE_BROWSING_DB_V4_GET_HASH_PROTOCOL_MANAGER_H_ 352 #endif // COMPONENTS_SAFE_BROWSING_DB_V4_GET_HASH_PROTOCOL_MANAGER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698