Line data Source code
1 : //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef Classifier_h__
7 : #define Classifier_h__
8 :
9 : #include "Entries.h"
10 : #include "HashStore.h"
11 : #include "ProtocolParser.h"
12 : #include "LookupCache.h"
13 : #include "nsCOMPtr.h"
14 : #include "nsString.h"
15 : #include "nsIFile.h"
16 : #include "nsICryptoHash.h"
17 : #include "nsDataHashtable.h"
18 :
19 : class nsIThread;
20 :
21 : namespace mozilla {
22 : namespace safebrowsing {
23 :
24 : /**
25 : * Maintains the stores and LookupCaches for the url classifier.
26 : */
27 : class Classifier {
28 : public:
29 : Classifier();
30 : ~Classifier();
31 :
32 : nsresult Open(nsIFile& aCacheDirectory);
33 : void Close();
34 : void Reset(); // Not including any intermediary for update.
35 :
36 : /**
37 : * Clear data for specific tables.
38 : * If ClearType is Clear_Cache, this function will only clear cache in lookup
39 : * cache, otherwise, it will clear data in lookup cache and data stored on disk.
40 : */
41 : enum ClearType {
42 : Clear_Cache,
43 : Clear_All,
44 : };
45 : void ResetTables(ClearType aType, const nsTArray<nsCString>& aTables);
46 :
47 : /**
48 : * Get the list of active tables and their chunks in a format
49 : * suitable for an update request.
50 : */
51 : void TableRequest(nsACString& aResult);
52 :
53 : /*
54 : * Get all tables that we know about.
55 : */
56 : nsresult ActiveTables(nsTArray<nsCString>& aTables);
57 :
58 : /**
59 : * Check a URL against the specified tables.
60 : */
61 : nsresult Check(const nsACString& aSpec,
62 : const nsACString& tables,
63 : LookupResultArray& aResults);
64 :
65 : /**
66 : * Asynchronously apply updates to the in-use databases. When the
67 : * update is complete, the caller can be notified by |aCallback|, which
68 : * will occur on the caller thread. Note that the ownership of
69 : * |aUpdates| will be transferred. This design is inherited from the
70 : * previous sync update function (ApplyUpdates) which has been removed.
71 : */
72 : using AsyncUpdateCallback = std::function<void(nsresult)>;
73 : nsresult AsyncApplyUpdates(nsTArray<TableUpdate*>* aUpdates,
74 : const AsyncUpdateCallback& aCallback);
75 :
76 : /**
77 : * Wait until the ongoing async update is finished and callback
78 : * is fired. Once this function returns, AsyncApplyUpdates is
79 : * no longer available.
80 : */
81 : void FlushAndDisableAsyncUpdate();
82 :
83 : /**
84 : * Apply full hashes retrived from gethash to cache.
85 : */
86 : nsresult ApplyFullHashes(nsTArray<TableUpdate*>* aUpdates);
87 :
88 : nsresult CacheCompletions(const CacheResultArray& aResults);
89 : uint32_t GetHashKey(void) { return mHashKey; }
90 : /*
91 : * Get a bunch of extra prefixes to query for completion
92 : * and mask the real entry being requested
93 : */
94 : nsresult ReadNoiseEntries(const Prefix& aPrefix,
95 : const nsACString& aTableName,
96 : uint32_t aCount,
97 : PrefixArray* aNoiseEntries);
98 :
99 : #ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
100 : nsresult DumpRawTableUpdates(const nsACString& aRawUpdates);
101 : #endif
102 :
103 : static void SplitTables(const nsACString& str, nsTArray<nsCString>& tables);
104 :
105 : // Given a root store directory, return a private store directory
106 : // based on the table name. To avoid migration issue, the private
107 : // store directory is only different from root directory for V4 tables.
108 : //
109 : // For V4 tables (suffixed by '-proto'), the private directory would
110 : // be [root directory path]/[provider]. The provider of V4 tables is
111 : // 'google4'.
112 : //
113 : // Note that if the table name is not owned by any provider, just use
114 : // the root directory.
115 : static nsresult GetPrivateStoreDirectory(nsIFile* aRootStoreDirectory,
116 : const nsACString& aTableName,
117 : const nsACString& aProvider,
118 : nsIFile** aPrivateStoreDirectory);
119 :
120 : // Swap in in-memory and on-disk database and remove all
121 : // update intermediaries.
122 : nsresult SwapInNewTablesAndCleanup();
123 :
124 : LookupCache *GetLookupCache(const nsACString& aTable,
125 : bool aForUpdate = false);
126 :
127 : void GetCacheInfo(const nsACString& aTable,
128 : nsIUrlClassifierCacheInfo** aCache);
129 :
130 : private:
131 : void DropStores();
132 : void DeleteTables(nsIFile* aDirectory, const nsTArray<nsCString>& aTables);
133 :
134 : nsresult CreateStoreDirectory();
135 : nsresult SetupPathNames();
136 : nsresult RecoverBackups();
137 : nsresult CleanToDelete();
138 : nsresult CopyInUseDirForUpdate();
139 : nsresult RegenActiveTables();
140 :
141 : void MergeNewLookupCaches(); // Merge mNewLookupCaches into mLookupCaches.
142 :
143 : void CopyAndInvalidateFullHashCache();
144 :
145 : // Remove any intermediary for update, including in-memory
146 : // and on-disk data.
147 : void RemoveUpdateIntermediaries();
148 :
149 : #ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
150 : already_AddRefed<nsIFile> GetFailedUpdateDirectroy();
151 : nsresult DumpFailedUpdate();
152 : #endif
153 :
154 : nsresult ScanStoreDir(nsIFile* aDirectory, nsTArray<nsCString>& aTables);
155 :
156 : nsresult UpdateHashStore(nsTArray<TableUpdate*>* aUpdates,
157 : const nsACString& aTable);
158 :
159 : nsresult UpdateTableV4(nsTArray<TableUpdate*>* aUpdates,
160 : const nsACString& aTable);
161 :
162 : nsresult UpdateCache(TableUpdate* aUpdates);
163 :
164 6 : LookupCache *GetLookupCacheForUpdate(const nsACString& aTable) {
165 6 : return GetLookupCache(aTable, true);
166 : }
167 :
168 : LookupCache *GetLookupCacheFrom(const nsACString& aTable,
169 : nsTArray<LookupCache*>& aLookupCaches,
170 : nsIFile* aRootStoreDirectory);
171 :
172 :
173 : bool CheckValidUpdate(nsTArray<TableUpdate*>* aUpdates,
174 : const nsACString& aTable);
175 :
176 : nsresult LoadMetadata(nsIFile* aDirectory, nsACString& aResult);
177 :
178 : nsCString GetProvider(const nsACString& aTableName);
179 :
180 : /**
181 : * The "background" part of ApplyUpdates. Once the background update
182 : * is called, the foreground update has to be called along with the
183 : * background result no matter whether the background update is
184 : * successful or not.
185 : */
186 : nsresult ApplyUpdatesBackground(nsTArray<TableUpdate*>* aUpdates,
187 : nsACString& aFailedTableName);
188 :
189 : /**
190 : * The "foreground" part of ApplyUpdates. The in-use data (in-memory and
191 : * on-disk) will be touched so this MUST be mutually exclusive to other
192 : * member functions.
193 : *
194 : * If |aBackgroundRv| is successful, the return value is the result of
195 : * bringing stuff to the foreground. Otherwise, the foreground table may
196 : * be reset according to the background update failed reason and
197 : * |aBackgroundRv| will be returned to forward the background update result.
198 : */
199 : nsresult ApplyUpdatesForeground(nsresult aBackgroundRv,
200 : const nsACString& aFailedTableName);
201 :
202 : // Root dir of the Local profile.
203 : nsCOMPtr<nsIFile> mCacheDirectory;
204 : // Main directory where to store the databases.
205 : nsCOMPtr<nsIFile> mRootStoreDirectory;
206 : // Used for atomically updating the other dirs.
207 : nsCOMPtr<nsIFile> mBackupDirectory;
208 : nsCOMPtr<nsIFile> mUpdatingDirectory; // For update only.
209 : nsCOMPtr<nsIFile> mToDeleteDirectory;
210 : nsCOMPtr<nsICryptoHash> mCryptoHash;
211 : nsTArray<LookupCache*> mLookupCaches; // For query only.
212 : nsTArray<nsCString> mActiveTablesCache;
213 : uint32_t mHashKey;
214 :
215 : // In-memory cache for the result of TableRequest. See
216 : // nsIUrlClassifierDBService.getTables for the format.
217 : nsCString mTableRequestResult;
218 :
219 : // Whether mTableRequestResult is outdated and needs to
220 : // be reloaded from disk.
221 : bool mIsTableRequestResultOutdated;
222 :
223 : // The copy of mLookupCaches for update only.
224 : nsTArray<LookupCache*> mNewLookupCaches;
225 :
226 : bool mUpdateInterrupted;
227 :
228 : nsCOMPtr<nsIThread> mUpdateThread; // For async update.
229 :
230 : // Identical to mRootStoreDirectory but for update only because
231 : // nsIFile is not thread safe and mRootStoreDirectory needs to
232 : // be accessed in CopyInUseDirForUpdate().
233 : // It will be initialized right before update on the worker thread.
234 : nsCOMPtr<nsIFile> mRootStoreDirectoryForUpdate;
235 : };
236 :
237 : } // namespace safebrowsing
238 : } // namespace mozilla
239 :
240 : #endif
|