toolkit/components/url-classifier/HashStore.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #ifndef HashStore_h__
     6 #define HashStore_h__
     8 #include "Entries.h"
     9 #include "ChunkSet.h"
    11 #include "nsString.h"
    12 #include "nsTArray.h"
    13 #include "nsIFile.h"
    14 #include "nsIFileStreams.h"
    15 #include "nsCOMPtr.h"
    17 namespace mozilla {
    18 namespace safebrowsing {
    20 // A table update is built from a single update chunk from the server. As the
    21 // protocol parser processes each chunk, it constructs a table update with the
    22 // new hashes.
    23 class TableUpdate {
    24 public:
    25   TableUpdate(const nsACString& aTable)
    26       : mTable(aTable), mLocalUpdate(false) {}
    27   const nsCString& TableName() const { return mTable; }
    29   bool Empty() const {
    30     return mAddChunks.Length() == 0 &&
    31       mSubChunks.Length() == 0 &&
    32       mAddExpirations.Length() == 0 &&
    33       mSubExpirations.Length() == 0 &&
    34       mAddPrefixes.Length() == 0 &&
    35       mSubPrefixes.Length() == 0 &&
    36       mAddCompletes.Length() == 0 &&
    37       mSubCompletes.Length() == 0;
    38   }
    40   // Throughout, uint32_t aChunk refers only to the chunk number. Chunk data is
    41   // stored in the Prefix structures.
    42   void NewAddChunk(uint32_t aChunk) { mAddChunks.Set(aChunk); }
    43   void NewSubChunk(uint32_t aChunk) { mSubChunks.Set(aChunk); }
    45   void NewAddExpiration(uint32_t aChunk) { mAddExpirations.Set(aChunk); }
    46   void NewSubExpiration(uint32_t aChunk) { mSubExpirations.Set(aChunk); }
    48   void NewAddPrefix(uint32_t aAddChunk, const Prefix& aPrefix);
    49   void NewSubPrefix(uint32_t aAddChunk, const Prefix& aPrefix, uint32_t aSubChunk);
    51   void NewAddComplete(uint32_t aChunk, const Completion& aCompletion);
    52   void NewSubComplete(uint32_t aAddChunk, const Completion& aCompletion,
    53                       uint32_t aSubChunk);
    54   void SetLocalUpdate(void) { mLocalUpdate = true; }
    55   bool IsLocalUpdate(void) { return mLocalUpdate; }
    57   ChunkSet& AddChunks() { return mAddChunks; }
    58   ChunkSet& SubChunks() { return mSubChunks; }
    60   // Expirations for chunks.
    61   ChunkSet& AddExpirations() { return mAddExpirations; }
    62   ChunkSet& SubExpirations() { return mSubExpirations; }
    64   // Hashes associated with this chunk.
    65   AddPrefixArray& AddPrefixes() { return mAddPrefixes; }
    66   SubPrefixArray& SubPrefixes() { return mSubPrefixes; }
    67   AddCompleteArray& AddCompletes() { return mAddCompletes; }
    68   SubCompleteArray& SubCompletes() { return mSubCompletes; }
    70 private:
    71   nsCString mTable;
    72   // Update not from the remote server (no freshness)
    73   bool mLocalUpdate;
    75   // The list of chunk numbers that we have for each of the type of chunks.
    76   ChunkSet mAddChunks;
    77   ChunkSet mSubChunks;
    78   ChunkSet mAddExpirations;
    79   ChunkSet mSubExpirations;
    81   // 4-byte sha256 prefixes.
    82   AddPrefixArray mAddPrefixes;
    83   SubPrefixArray mSubPrefixes;
    85   // 32-byte hashes.
    86   AddCompleteArray mAddCompletes;
    87   SubCompleteArray mSubCompletes;
    88 };
    90 // There is one hash store per table.
    91 class HashStore {
    92 public:
    93   HashStore(const nsACString& aTableName, nsIFile* aStoreFile);
    94   ~HashStore();
    96   const nsCString& TableName() const { return mTableName; }
    98   nsresult Open();
    99   // Add Prefixes are stored partly in the PrefixSet (contains the
   100   // Prefix data organized for fast lookup/low RAM usage) and partly in the
   101   // HashStore (Add Chunk numbers - only used for updates, slow retrieval).
   102   // AugmentAdds function joins the separate datasets into one complete
   103   // prefixes+chunknumbers dataset.
   104   nsresult AugmentAdds(const nsTArray<uint32_t>& aPrefixes);
   106   ChunkSet& AddChunks() { return mAddChunks; }
   107   ChunkSet& SubChunks() { return mSubChunks; }
   108   AddPrefixArray& AddPrefixes() { return mAddPrefixes; }
   109   AddCompleteArray& AddCompletes() { return mAddCompletes; }
   110   SubPrefixArray& SubPrefixes() { return mSubPrefixes; }
   111   SubCompleteArray& SubCompletes() { return mSubCompletes; }
   113   // =======
   114   // Updates
   115   // =======
   116   // Begin the update process.  Reads the store into memory.
   117   nsresult BeginUpdate();
   119   // Imports the data from a TableUpdate.
   120   nsresult ApplyUpdate(TableUpdate &aUpdate);
   122   // Process expired chunks
   123   nsresult Expire();
   125   // Rebuild the store, Incorporating all the applied updates.
   126   nsresult Rebuild();
   128   // Write the current state of the store to disk.
   129   // If you call between ApplyUpdate() and Rebuild(), you'll
   130   // have a mess on your hands.
   131   nsresult WriteFile();
   133   // Wipe out all Completes.
   134   void ClearCompletes();
   136 private:
   137   nsresult Reset();
   139   nsresult ReadHeader();
   140   nsresult SanityCheck();
   141   nsresult CalculateChecksum(nsAutoCString& aChecksum, uint32_t aFileSize,
   142                              bool aChecksumPresent);
   143   nsresult CheckChecksum(nsIFile* aStoreFile, uint32_t aFileSize);
   144   void UpdateHeader();
   146   nsresult ReadChunkNumbers();
   147   nsresult ReadHashes();
   149   nsresult ReadAddPrefixes();
   150   nsresult ReadSubPrefixes();
   152   nsresult WriteAddPrefixes(nsIOutputStream* aOut);
   153   nsresult WriteSubPrefixes(nsIOutputStream* aOut);
   155   nsresult ProcessSubs();
   157  // This is used for checking that the database is correct and for figuring out
   158  // the number of chunks, etc. to read from disk on restart.
   159   struct Header {
   160     uint32_t magic;
   161     uint32_t version;
   162     uint32_t numAddChunks;
   163     uint32_t numSubChunks;
   164     uint32_t numAddPrefixes;
   165     uint32_t numSubPrefixes;
   166     uint32_t numAddCompletes;
   167     uint32_t numSubCompletes;
   168   };
   170   Header mHeader;
   172   // The name of the table (must end in -shavar or -digest256, or evidently
   173   // -simple for unittesting.
   174   nsCString mTableName;
   175   nsCOMPtr<nsIFile> mStoreDirectory;
   177   bool mInUpdate;
   179   nsCOMPtr<nsIInputStream> mInputStream;
   181   // Chunk numbers, stored as uint32_t arrays.
   182   ChunkSet mAddChunks;
   183   ChunkSet mSubChunks;
   185   ChunkSet mAddExpirations;
   186   ChunkSet mSubExpirations;
   188   // Chunk data for shavar tables. See Entries.h for format.
   189   AddPrefixArray mAddPrefixes;
   190   SubPrefixArray mSubPrefixes;
   192   // See bug 806422 for background. We must be able to distinguish between
   193   // updates from the completion server and updates from the regular server.
   194   AddCompleteArray mAddCompletes;
   195   SubCompleteArray mSubCompletes;
   196 };
   198 }
   199 }
   200 #endif

mercurial