LookupCache.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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. #ifndef LookupCache_h__
  6. #define LookupCache_h__
  7. #include "Entries.h"
  8. #include "nsString.h"
  9. #include "nsTArray.h"
  10. #include "nsCOMPtr.h"
  11. #include "nsIFile.h"
  12. #include "nsIFileStreams.h"
  13. #include "mozilla/RefPtr.h"
  14. #include "nsUrlClassifierPrefixSet.h"
  15. #include "VariableLengthPrefixSet.h"
  16. #include "mozilla/Logging.h"
  17. namespace mozilla {
  18. namespace safebrowsing {
  19. #define MAX_HOST_COMPONENTS 5
  20. #define MAX_PATH_COMPONENTS 4
  21. class LookupResult {
  22. public:
  23. LookupResult() : mComplete(false), mNoise(false),
  24. mFresh(false), mProtocolConfirmed(false) {}
  25. // The fragment that matched in the LookupCache
  26. union {
  27. Prefix prefix;
  28. Completion complete;
  29. } hash;
  30. const Prefix &PrefixHash() {
  31. return hash.prefix;
  32. }
  33. const Completion &CompleteHash() {
  34. MOZ_ASSERT(!mNoise);
  35. return hash.complete;
  36. }
  37. bool Confirmed() const { return (mComplete && mFresh) || mProtocolConfirmed; }
  38. bool Complete() const { return mComplete; }
  39. // True if we have a complete match for this hash in the table.
  40. bool mComplete;
  41. // True if this is a noise entry, i.e. an extra entry
  42. // that is inserted to mask the true URL we are requesting.
  43. // Noise entries will not have a complete 256-bit hash as
  44. // they are fetched from the local 32-bit database and we
  45. // don't know the corresponding full URL.
  46. bool mNoise;
  47. // True if we've updated this table recently-enough.
  48. bool mFresh;
  49. bool mProtocolConfirmed;
  50. nsCString mTableName;
  51. };
  52. typedef nsTArray<LookupResult> LookupResultArray;
  53. struct CacheResult {
  54. AddComplete entry;
  55. nsCString table;
  56. bool operator==(const CacheResult& aOther) const {
  57. if (entry != aOther.entry) {
  58. return false;
  59. }
  60. return table == aOther.table;
  61. }
  62. };
  63. typedef nsTArray<CacheResult> CacheResultArray;
  64. class LookupCache {
  65. public:
  66. // Check for a canonicalized IP address.
  67. static bool IsCanonicalizedIP(const nsACString& aHost);
  68. // take a lookup string (www.hostname.com/path/to/resource.html) and
  69. // expand it into the set of fragments that should be searched for in an
  70. // entry
  71. static nsresult GetLookupFragments(const nsACString& aSpec,
  72. nsTArray<nsCString>* aFragments);
  73. // Similar to GetKey(), but if the domain contains three or more components,
  74. // two keys will be returned:
  75. // hostname.com/foo/bar -> [hostname.com]
  76. // mail.hostname.com/foo/bar -> [hostname.com, mail.hostname.com]
  77. // www.mail.hostname.com/foo/bar -> [hostname.com, mail.hostname.com]
  78. static nsresult GetHostKeys(const nsACString& aSpec,
  79. nsTArray<nsCString>* aHostKeys);
  80. LookupCache(const nsACString& aTableName,
  81. const nsACString& aProvider,
  82. nsIFile* aStoreFile);
  83. virtual ~LookupCache() {}
  84. const nsCString &TableName() const { return mTableName; }
  85. // The directory handle where we operate will
  86. // be moved away when a backup is made.
  87. nsresult UpdateRootDirHandle(nsIFile* aRootStoreDirectory);
  88. // This will Clear() the passed arrays when done.
  89. nsresult AddCompletionsToCache(AddCompleteArray& aAddCompletes);
  90. // Write data stored in lookup cache to disk.
  91. nsresult WriteFile();
  92. // Clear completions retrieved from gethash request.
  93. void ClearCache();
  94. bool IsPrimed() const { return mPrimed; };
  95. #if DEBUG
  96. void DumpCache();
  97. #endif
  98. virtual nsresult Open();
  99. virtual nsresult Init() = 0;
  100. virtual nsresult ClearPrefixes() = 0;
  101. virtual nsresult Has(const Completion& aCompletion,
  102. bool* aHas, bool* aComplete) = 0;
  103. virtual void ClearAll();
  104. template<typename T>
  105. static T* Cast(LookupCache* aThat) {
  106. return ((aThat && T::VER == aThat->Ver()) ? reinterpret_cast<T*>(aThat) : nullptr);
  107. }
  108. private:
  109. nsresult Reset();
  110. nsresult LoadPrefixSet();
  111. virtual nsresult StoreToFile(nsIFile* aFile) = 0;
  112. virtual nsresult LoadFromFile(nsIFile* aFile) = 0;
  113. virtual size_t SizeOfPrefixSet() = 0;
  114. virtual int Ver() const = 0;
  115. protected:
  116. bool mPrimed;
  117. nsCString mTableName;
  118. nsCString mProvider;
  119. nsCOMPtr<nsIFile> mRootStoreDirectory;
  120. nsCOMPtr<nsIFile> mStoreDirectory;
  121. // Full length hashes obtained in gethash request
  122. CompletionArray mGetHashCache;
  123. // For gtest to inspect private members.
  124. friend class PerProviderDirectoryTestUtils;
  125. };
  126. class LookupCacheV2 final : public LookupCache
  127. {
  128. public:
  129. explicit LookupCacheV2(const nsACString& aTableName,
  130. const nsACString& aProvider,
  131. nsIFile* aStoreFile)
  132. : LookupCache(aTableName, aProvider, aStoreFile) {}
  133. ~LookupCacheV2() {}
  134. virtual nsresult Init() override;
  135. virtual nsresult Open() override;
  136. virtual void ClearAll() override;
  137. virtual nsresult Has(const Completion& aCompletion,
  138. bool* aHas, bool* aComplete) override;
  139. nsresult Build(AddPrefixArray& aAddPrefixes,
  140. AddCompleteArray& aAddCompletes);
  141. nsresult GetPrefixes(FallibleTArray<uint32_t>& aAddPrefixes);
  142. #if DEBUG
  143. void DumpCompletions();
  144. #endif
  145. static const int VER;
  146. protected:
  147. nsresult ReadCompletions();
  148. virtual nsresult ClearPrefixes() override;
  149. virtual nsresult StoreToFile(nsIFile* aFile) override;
  150. virtual nsresult LoadFromFile(nsIFile* aFile) override;
  151. virtual size_t SizeOfPrefixSet() override;
  152. private:
  153. virtual int Ver() const override { return VER; }
  154. // Construct a Prefix Set with known prefixes.
  155. // This will Clear() aAddPrefixes when done.
  156. nsresult ConstructPrefixSet(AddPrefixArray& aAddPrefixes);
  157. // Full length hashes obtained in update request
  158. CompletionArray mUpdateCompletions;
  159. // Set of prefixes known to be in the database
  160. RefPtr<nsUrlClassifierPrefixSet> mPrefixSet;
  161. };
  162. } // namespace safebrowsing
  163. } // namespace mozilla
  164. #endif