LCOV - code coverage report
Current view: top level - toolkit/components/url-classifier - LookupCache.h (source / functions) Hit Total Coverage
Test: output.info Lines: 9 53 17.0 %
Date: 2017-07-14 16:53:18 Functions: 9 34 26.5 %
Legend: Lines: hit not hit

          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 LookupCache_h__
       7             : #define LookupCache_h__
       8             : 
       9             : #include "Entries.h"
      10             : #include "nsString.h"
      11             : #include "nsTArray.h"
      12             : #include "nsCOMPtr.h"
      13             : #include "nsIFile.h"
      14             : #include "nsIFileStreams.h"
      15             : #include "mozilla/RefPtr.h"
      16             : #include "nsUrlClassifierPrefixSet.h"
      17             : #include "VariableLengthPrefixSet.h"
      18             : #include "mozilla/Logging.h"
      19             : #include "mozilla/TypedEnumBits.h"
      20             : #include "nsIUrlClassifierInfo.h"
      21             : 
      22             : namespace mozilla {
      23             : namespace safebrowsing {
      24             : 
      25             : #define MAX_HOST_COMPONENTS 5
      26             : #define MAX_PATH_COMPONENTS 4
      27             : 
      28           0 : class LookupResult {
      29             : public:
      30           0 :   LookupResult() : mNoise(false), mProtocolConfirmed(false),
      31             :                    mPartialHashLength(0), mConfirmed(false),
      32           0 :                    mProtocolV2(true) {}
      33             : 
      34             :   // The fragment that matched in the LookupCache
      35             :   union {
      36             :     Prefix fixedLengthPrefix;
      37             :     Completion complete;
      38             :   } hash;
      39             : 
      40           0 :   const Completion &CompleteHash() {
      41           0 :     MOZ_ASSERT(!mNoise);
      42           0 :     return hash.complete;
      43             :   }
      44             : 
      45           0 :   nsCString PartialHash() {
      46           0 :     MOZ_ASSERT(mPartialHashLength <= COMPLETE_SIZE);
      47           0 :     if (mNoise) {
      48             :       return nsCString(reinterpret_cast<char*>(hash.fixedLengthPrefix.buf),
      49           0 :                        PREFIX_SIZE);
      50             :     } else {
      51             :       return nsCString(reinterpret_cast<char*>(hash.complete.buf),
      52           0 :                        mPartialHashLength);
      53             :     }
      54             :   }
      55             : 
      56           0 :   nsCString PartialHashHex() {
      57           0 :     nsAutoCString hex;
      58           0 :     for (size_t i = 0; i < mPartialHashLength; i++) {
      59           0 :       hex.AppendPrintf("%.2X", hash.complete.buf[i]);
      60             :     }
      61           0 :     return hex;
      62             :   }
      63             : 
      64           0 :   bool Confirmed() const { return mConfirmed || mProtocolConfirmed; }
      65             : 
      66             :   // True if we have a complete match for this hash in the table.
      67           0 :   bool Complete() const { return mPartialHashLength == COMPLETE_SIZE; }
      68             : 
      69             :   // True if this is a noise entry, i.e. an extra entry
      70             :   // that is inserted to mask the true URL we are requesting.
      71             :   // Noise entries will not have a complete 256-bit hash as
      72             :   // they are fetched from the local 32-bit database and we
      73             :   // don't know the corresponding full URL.
      74             :   bool mNoise;
      75             : 
      76             :   bool mProtocolConfirmed;
      77             : 
      78             :   nsCString mTableName;
      79             : 
      80             :   uint32_t mPartialHashLength;
      81             : 
      82             :   // True as long as this lookup is complete and hasn't expired.
      83             :   bool mConfirmed;
      84             : 
      85             :   // TODO : Is this necessary
      86             :   bool mProtocolV2;
      87             : };
      88             : 
      89             : typedef nsTArray<LookupResult> LookupResultArray;
      90             : 
      91           0 : class CacheResult {
      92             : public:
      93             :   enum { V2, V4 };
      94             : 
      95             :   virtual int Ver() const = 0;
      96             :   virtual bool findCompletion(const Completion& aCompletion) const = 0;
      97             : 
      98           0 :   virtual ~CacheResult() {}
      99             : 
     100             :   template<typename T>
     101           0 :   static T* Cast(CacheResult* aThat) {
     102           0 :     return ((aThat && T::VER == aThat->Ver()) ?
     103           0 :       reinterpret_cast<T*>(aThat) : nullptr);
     104             :   }
     105             : 
     106             :   nsCString table;
     107             :   Prefix prefix;
     108             : };
     109             : 
     110           0 : class CacheResultV2 final : public CacheResult
     111             : {
     112             : public:
     113             :   static const int VER;
     114             : 
     115             :   // True when 'prefix' in CacheResult indicates a prefix that
     116             :   // cannot be completed.
     117             :   bool miss = false;
     118             : 
     119             :   // 'completion' and 'addChunk' are used when 'miss' field is false.
     120             :   Completion completion;
     121             :   uint32_t addChunk;
     122             : 
     123           0 :   bool operator==(const CacheResultV2& aOther) const {
     124           0 :     if (table != aOther.table ||
     125           0 :         prefix != aOther.prefix ||
     126           0 :         miss != aOther.miss) {
     127           0 :       return false;
     128             :     }
     129             : 
     130           0 :     if (miss) {
     131           0 :       return true;
     132             :     }
     133           0 :     return completion == aOther.completion && addChunk == aOther.addChunk;
     134             :   }
     135             : 
     136           0 :   bool findCompletion(const Completion& aCompletion) const override {
     137           0 :     return completion == aCompletion;
     138             :   }
     139             : 
     140           0 :   virtual int Ver() const override { return VER; }
     141             : };
     142             : 
     143           0 : class CacheResultV4 final : public CacheResult
     144             : {
     145             : public:
     146             :   static const int VER;
     147             : 
     148             :   CachedFullHashResponse response;
     149             : 
     150           0 :   bool operator==(const CacheResultV4& aOther) const {
     151           0 :     return table == aOther.table &&
     152           0 :            prefix == aOther.prefix &&
     153           0 :            response == aOther.response;
     154             :   }
     155             : 
     156           0 :   bool findCompletion(const Completion& aCompletion) const override {
     157             :     nsDependentCSubstring completion(
     158           0 :       reinterpret_cast<const char*>(aCompletion.buf), COMPLETE_SIZE);
     159           0 :     return response.fullHashes.Contains(completion);
     160             :   }
     161             : 
     162           0 :   virtual int Ver() const override { return VER; }
     163             : };
     164             : 
     165             : typedef nsTArray<UniquePtr<CacheResult>> CacheResultArray;
     166             : 
     167             : class LookupCache {
     168             : public:
     169             :   // Check for a canonicalized IP address.
     170             :   static bool IsCanonicalizedIP(const nsACString& aHost);
     171             : 
     172             :   // take a lookup string (www.hostname.com/path/to/resource.html) and
     173             :   // expand it into the set of fragments that should be searched for in an
     174             :   // entry
     175             :   static nsresult GetLookupFragments(const nsACString& aSpec,
     176             :                                      nsTArray<nsCString>* aFragments);
     177             :   // Similar to GetKey(), but if the domain contains three or more components,
     178             :   // two keys will be returned:
     179             :   //  hostname.com/foo/bar -> [hostname.com]
     180             :   //  mail.hostname.com/foo/bar -> [hostname.com, mail.hostname.com]
     181             :   //  www.mail.hostname.com/foo/bar -> [hostname.com, mail.hostname.com]
     182             :   static nsresult GetHostKeys(const nsACString& aSpec,
     183             :                               nsTArray<nsCString>* aHostKeys);
     184             : 
     185             :   LookupCache(const nsACString& aTableName,
     186             :               const nsACString& aProvider,
     187             :               nsIFile* aStoreFile);
     188           6 :   virtual ~LookupCache() {}
     189             : 
     190         145 :   const nsCString &TableName() const { return mTableName; }
     191             : 
     192             :   // The directory handle where we operate will
     193             :   // be moved away when a backup is made.
     194             :   nsresult UpdateRootDirHandle(nsIFile* aRootStoreDirectory);
     195             : 
     196             :   // Write data stored in lookup cache to disk.
     197             :   nsresult WriteFile();
     198             : 
     199          12 :   bool IsPrimed() const { return mPrimed; };
     200             : 
     201             :   // Called when update to clear expired entries.
     202             :   void InvalidateExpiredCacheEntries();
     203             : 
     204             :   // Copy fullhash cache from another LookupCache.
     205             :   void CopyFullHashCache(const LookupCache* aSource);
     206             : 
     207             :   // Clear fullhash cache from fullhash/gethash response.
     208             :   void ClearCache();
     209             : 
     210             :   // Check if completions can be found in cache.
     211             :   // Currently this is only used by testcase.
     212             :   bool IsInCache(uint32_t key) { return mFullHashCache.Get(key); };
     213             : 
     214             : #if DEBUG
     215             :   void DumpCache();
     216             : #endif
     217             : 
     218             :   void GetCacheInfo(nsIUrlClassifierCacheInfo** aCache);
     219             : 
     220             :   virtual nsresult Open();
     221             :   virtual nsresult Init() = 0;
     222             :   virtual nsresult ClearPrefixes() = 0;
     223             :   virtual nsresult Has(const Completion& aCompletion,
     224             :                        bool* aHas,
     225             :                        uint32_t* aMatchLength,
     226             :                        bool* aConfirmed) = 0;
     227             : 
     228             :   virtual bool IsEmpty() = 0;
     229             : 
     230             :   virtual void ClearAll();
     231             : 
     232             :   template<typename T>
     233          18 :   static T* Cast(LookupCache* aThat) {
     234          18 :     return ((aThat && T::VER == aThat->Ver()) ? reinterpret_cast<T*>(aThat) : nullptr);
     235             :   }
     236             : 
     237             : private:
     238             :   nsresult LoadPrefixSet();
     239             : 
     240             :   virtual nsresult StoreToFile(nsIFile* aFile) = 0;
     241             :   virtual nsresult LoadFromFile(nsIFile* aFile) = 0;
     242             :   virtual size_t SizeOfPrefixSet() = 0;
     243             : 
     244             :   virtual int Ver() const = 0;
     245             : 
     246             : protected:
     247             :   // Check completions in positive cache and prefix in negative cache.
     248             :   // 'aHas' and 'aConfirmed' are output parameters.
     249             :   nsresult CheckCache(const Completion& aCompletion,
     250             :                       bool* aHas,
     251             :                       bool* aConfirmed);
     252             : 
     253             :   bool mPrimed;
     254             :   nsCString mTableName;
     255             :   nsCString mProvider;
     256             :   nsCOMPtr<nsIFile> mRootStoreDirectory;
     257             :   nsCOMPtr<nsIFile> mStoreDirectory;
     258             : 
     259             :   // For gtest to inspect private members.
     260             :   friend class PerProviderDirectoryTestUtils;
     261             : 
     262             :   // Cache stores fullhash response(V4)/gethash response(V2)
     263             :   FullHashResponseMap mFullHashCache;
     264             : };
     265             : 
     266             : class LookupCacheV2 final : public LookupCache
     267             : {
     268             : public:
     269          13 :   explicit LookupCacheV2(const nsACString& aTableName,
     270             :                          const nsACString& aProvider,
     271             :                          nsIFile* aStoreFile)
     272          13 :     : LookupCache(aTableName, aProvider, aStoreFile) {}
     273          18 :   ~LookupCacheV2() {}
     274             : 
     275             :   virtual nsresult Init() override;
     276             :   virtual nsresult Open() override;
     277             :   virtual void ClearAll() override;
     278             :   virtual nsresult Has(const Completion& aCompletion,
     279             :                        bool* aHas,
     280             :                        uint32_t* aMatchLength,
     281             :                        bool* aConfirmed) override;
     282             : 
     283             :   virtual bool IsEmpty() override;
     284             : 
     285             :   nsresult Build(AddPrefixArray& aAddPrefixes,
     286             :                  AddCompleteArray& aAddCompletes);
     287             : 
     288             :   nsresult GetPrefixes(FallibleTArray<uint32_t>& aAddPrefixes);
     289             : 
     290             :   // This will Clear() the passed arrays when done.
     291             :   // 'aExpirySec' is used by testcase to config an expired time.
     292             :   void AddGethashResultToCache(AddCompleteArray& aAddCompletes,
     293             :                                MissPrefixArray& aMissPrefixes,
     294             :                                int64_t aExpirySec = 0);
     295             : 
     296             : #if DEBUG
     297             :   void DumpCompletions();
     298             : #endif
     299             : 
     300             :   static const int VER;
     301             : 
     302             : protected:
     303             :   nsresult ReadCompletions();
     304             : 
     305             :   virtual nsresult ClearPrefixes() override;
     306             :   virtual nsresult StoreToFile(nsIFile* aFile) override;
     307             :   virtual nsresult LoadFromFile(nsIFile* aFile) override;
     308             :   virtual size_t SizeOfPrefixSet() override;
     309             : 
     310             : private:
     311          18 :   virtual int Ver() const override { return VER; }
     312             : 
     313             :   // Construct a Prefix Set with known prefixes.
     314             :   // This will Clear() aAddPrefixes when done.
     315             :   nsresult ConstructPrefixSet(AddPrefixArray& aAddPrefixes);
     316             : 
     317             :   // Full length hashes obtained in update request
     318             :   CompletionArray mUpdateCompletions;
     319             : 
     320             :   // Set of prefixes known to be in the database
     321             :   RefPtr<nsUrlClassifierPrefixSet> mPrefixSet;
     322             : };
     323             : 
     324             : } // namespace safebrowsing
     325             : } // namespace mozilla
     326             : 
     327             : #endif

Generated by: LCOV version 1.13