LCOV - code coverage report
Current view: top level - netwerk/dns - nsHostResolver.h (source / functions) Hit Total Coverage
Test: output.info Lines: 5 5 100.0 %
Date: 2017-07-14 16:53:18 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* vim:set ts=4 sw=4 sts=4 et cin: */
       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 nsHostResolver_h__
       7             : #define nsHostResolver_h__
       8             : 
       9             : #include "nscore.h"
      10             : #include "prclist.h"
      11             : #include "prnetdb.h"
      12             : #include "PLDHashTable.h"
      13             : #include "mozilla/CondVar.h"
      14             : #include "mozilla/Mutex.h"
      15             : #include "nsISupportsImpl.h"
      16             : #include "nsIDNSListener.h"
      17             : #include "nsIDNSService.h"
      18             : #include "nsString.h"
      19             : #include "nsTArray.h"
      20             : #include "GetAddrInfo.h"
      21             : #include "mozilla/net/DNS.h"
      22             : #include "mozilla/net/DashboardTypes.h"
      23             : #include "mozilla/TimeStamp.h"
      24             : 
      25             : class nsHostResolver;
      26             : class nsHostRecord;
      27             : class nsResolveHostCallback;
      28             : 
      29             : #define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY  3
      30             : #define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 5
      31             : #define MAX_NON_PRIORITY_REQUESTS 150
      32             : 
      33             : #define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \
      34             :                               MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)
      35             : 
      36           3 : struct nsHostKey
      37             : {
      38             :     const char *host;
      39             :     uint16_t    flags;
      40             :     uint16_t    af;
      41             :     const char *netInterface;
      42             :     const char *originSuffix;
      43             : };
      44             : 
      45             : /**
      46             :  * nsHostRecord - ref counted object type stored in host resolver cache.
      47             :  */
      48             : class nsHostRecord : public PRCList, public nsHostKey
      49             : {
      50             :     typedef mozilla::Mutex Mutex;
      51             : 
      52             : public:
      53          15 :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHostRecord)
      54             : 
      55             :     /* instantiates a new host record */
      56             :     static nsresult Create(const nsHostKey *key, nsHostRecord **record);
      57             : 
      58             :     /* a fully resolved host record has either a non-null |addr_info| or |addr|
      59             :      * field.  if |addr_info| is null, it implies that the |host| is an IP
      60             :      * address literal.  in which case, |addr| contains the parsed address.
      61             :      * otherwise, if |addr_info| is non-null, then it contains one or many
      62             :      * IP addresses corresponding to the given host name.  if both |addr_info|
      63             :      * and |addr| are null, then the given host has not yet been fully resolved.
      64             :      * |af| is the address family of the record we are querying for.
      65             :      */
      66             : 
      67             :     /* the lock protects |addr_info| and |addr_info_gencnt| because they
      68             :      * are mutable and accessed by the resolver worker thread and the
      69             :      * nsDNSService2 class.  |addr| doesn't change after it has been
      70             :      * assigned a value.  only the resolver worker thread modifies
      71             :      * nsHostRecord (and only in nsHostResolver::OnLookupComplete);
      72             :      * the other threads just read it.  therefore the resolver worker
      73             :      * thread doesn't need to lock when reading |addr_info|.
      74             :      */
      75             :     Mutex        addr_info_lock;
      76             :     int          addr_info_gencnt; /* generation count of |addr_info| */
      77             :     mozilla::net::AddrInfo *addr_info;
      78             :     mozilla::net::NetAddr  *addr;
      79             :     bool         negative;   /* True if this record is a cache of a failed lookup.
      80             :                                 Negative cache entries are valid just like any other
      81             :                                 (though never for more than 60 seconds), but a use
      82             :                                 of that negative entry forces an asynchronous refresh. */
      83             : 
      84             :     enum ExpirationStatus {
      85             :         EXP_VALID,
      86             :         EXP_GRACE,
      87             :         EXP_EXPIRED,
      88             :     };
      89             : 
      90             :     ExpirationStatus CheckExpiration(const mozilla::TimeStamp& now) const;
      91             : 
      92             :     // When the record began being valid. Used mainly for bookkeeping.
      93             :     mozilla::TimeStamp mValidStart;
      94             : 
      95             :     // When the record is no longer valid (it's time of expiration)
      96             :     mozilla::TimeStamp mValidEnd;
      97             : 
      98             :     // When the record enters its grace period. This must be before mValidEnd.
      99             :     // If a record is in its grace period (and not expired), it will be used
     100             :     // but a request to refresh it will be made.
     101             :     mozilla::TimeStamp mGraceStart;
     102             : 
     103             :     // Convenience function for setting the timestamps above (mValidStart,
     104             :     // mValidEnd, and mGraceStart). valid and grace are durations in seconds.
     105             :     void SetExpiration(const mozilla::TimeStamp& now, unsigned int valid,
     106             :                        unsigned int grace);
     107             :     void CopyExpirationTimesAndFlagsFrom(const nsHostRecord *aFromHostRecord);
     108             : 
     109             :     // Checks if the record is usable (not expired and has a value)
     110             :     bool HasUsableResult(const mozilla::TimeStamp& now, uint16_t queryFlags = 0) const;
     111             : 
     112             :     // hold addr_info_lock when calling the blacklist functions
     113             :     bool   Blacklisted(mozilla::net::NetAddr *query);
     114             :     void   ResetBlacklist();
     115             :     void   ReportUnusable(mozilla::net::NetAddr *addr);
     116             : 
     117             :     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
     118             : 
     119             :     enum DnsPriority {
     120             :         DNS_PRIORITY_LOW,
     121             :         DNS_PRIORITY_MEDIUM,
     122             :         DNS_PRIORITY_HIGH,
     123             :     };
     124             :     static DnsPriority GetPriority(uint16_t aFlags);
     125             : 
     126             :     bool RemoveOrRefresh(); // Mark records currently being resolved as needed
     127             :                             // to resolve again.
     128             : 
     129             : private:
     130             :     friend class nsHostResolver;
     131             : 
     132             : 
     133             :     PRCList callbacks; /* list of callbacks */
     134             : 
     135             :     bool    resolving; /* true if this record is being resolved, which means
     136             :                         * that it is either on the pending queue or owned by
     137             :                         * one of the worker threads. */
     138             : 
     139             :     bool    onQueue;  /* true if pending and on the queue (not yet given to getaddrinfo())*/
     140             :     bool    usingAnyThread; /* true if off queue and contributing to mActiveAnyThreadCount */
     141             :     bool    mDoomed; /* explicitly expired */
     142             : 
     143             : #if TTL_AVAILABLE
     144             :     bool    mGetTtl;
     145             : #endif
     146             : 
     147             :     // The number of times ReportUnusable() has been called in the record's
     148             :     // lifetime.
     149             :     uint32_t mBlacklistedCount;
     150             : 
     151             :     // when the results from this resolve is returned, it is not to be
     152             :     // trusted, but instead a new resolve must be made!
     153             :     bool    mResolveAgain;
     154             : 
     155             :     // a list of addresses associated with this record that have been reported
     156             :     // as unusable. the list is kept as a set of strings to make it independent
     157             :     // of gencnt.
     158             :     nsTArray<nsCString> mBlacklistedItems;
     159             : 
     160             :     explicit nsHostRecord(const nsHostKey *key);           /* use Create() instead */
     161             :    ~nsHostRecord();
     162             : };
     163             : 
     164             : /**
     165             :  * ResolveHost callback object.  It's PRCList members are used by
     166             :  * the nsHostResolver and should not be used by anything else.
     167             :  */
     168           3 : class NS_NO_VTABLE nsResolveHostCallback : public PRCList
     169             : {
     170             : public:
     171             :     /**
     172             :      * OnLookupComplete
     173             :      *
     174             :      * this function is called to complete a host lookup initiated by
     175             :      * nsHostResolver::ResolveHost.  it may be invoked recursively from
     176             :      * ResolveHost or on an unspecified background thread.
     177             :      *
     178             :      * NOTE: it is the responsibility of the implementor of this method
     179             :      * to handle the callback in a thread safe manner.
     180             :      *
     181             :      * @param resolver
     182             :      *        nsHostResolver object associated with this result
     183             :      * @param record
     184             :      *        the host record containing the results of the lookup
     185             :      * @param status
     186             :      *        if successful, |record| contains non-null results
     187             :      */
     188             :     virtual void OnLookupComplete(nsHostResolver *resolver,
     189             :                                   nsHostRecord   *record,
     190             :                                   nsresult        status) = 0;
     191             :     /**
     192             :      * EqualsAsyncListener
     193             :      *
     194             :      * Determines if the listener argument matches the listener member var.
     195             :      * For subclasses not implementing a member listener, should return false.
     196             :      * For subclasses having a member listener, the function should check if
     197             :      * they are the same.  Used for cases where a pointer to an object
     198             :      * implementing nsResolveHostCallback is unknown, but a pointer to
     199             :      * the original listener is known.
     200             :      *
     201             :      * @param aListener
     202             :      *        nsIDNSListener object associated with the original request
     203             :      */
     204             :     virtual bool EqualsAsyncListener(nsIDNSListener *aListener) = 0;
     205             : 
     206             :     virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const = 0;
     207             : };
     208             : 
     209             : /**
     210             :  * nsHostResolver - an asynchronous host name resolver.
     211             :  */
     212           1 : class nsHostResolver
     213             : {
     214             :     typedef mozilla::CondVar CondVar;
     215             :     typedef mozilla::Mutex Mutex;
     216             : 
     217             : public:
     218             :     /**
     219             :      * host resolver instances are reference counted.
     220             :      */
     221          23 :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHostResolver)
     222             : 
     223             :     /**
     224             :      * creates an addref'd instance of a nsHostResolver object.
     225             :      */
     226             :     static nsresult Create(uint32_t maxCacheEntries, // zero disables cache
     227             :                            uint32_t defaultCacheEntryLifetime, // seconds
     228             :                            uint32_t defaultGracePeriod, // seconds
     229             :                            nsHostResolver **resolver);
     230             : 
     231             :     /**
     232             :      * puts the resolver in the shutdown state, which will cause any pending
     233             :      * callbacks to be detached.  any future calls to ResolveHost will fail.
     234             :      */
     235             :     void Shutdown();
     236             : 
     237             :     /**
     238             :      * resolve the given hostname and originAttributes asynchronously.  the caller
     239             :      * can synthesize a synchronous host lookup using a lock and a cvar.  as noted
     240             :      * above the callback will occur re-entrantly from an unspecified thread.  the
     241             :      * host lookup cannot be canceled (cancelation can be layered above this by
     242             :      * having the callback implementation return without doing anything).
     243             :      */
     244             :     nsresult ResolveHost(const char                      *hostname,
     245             :                          const mozilla::OriginAttributes &aOriginAttributes,
     246             :                          uint16_t                         flags,
     247             :                          uint16_t                         af,
     248             :                          const char                      *netInterface,
     249             :                          nsResolveHostCallback           *callback);
     250             : 
     251             :     /**
     252             :      * removes the specified callback from the nsHostRecord for the given
     253             :      * hostname, originAttributes, flags, and address family.  these parameters
     254             :      * should correspond to the parameters passed to ResolveHost.  this function
     255             :      * executes the callback if the callback is still pending with the given status.
     256             :      */
     257             :     void DetachCallback(const char                      *hostname,
     258             :                         const mozilla::OriginAttributes &aOriginAttributes,
     259             :                         uint16_t                         flags,
     260             :                         uint16_t                         af,
     261             :                         const char                      *netInterface,
     262             :                         nsResolveHostCallback           *callback,
     263             :                         nsresult                         status);
     264             : 
     265             :     /**
     266             :      * Cancels an async request associated with the hostname, originAttributes, flags,
     267             :      * address family and listener.  Cancels first callback found which matches
     268             :      * these criteria.  These parameters should correspond to the parameters
     269             :      * passed to ResolveHost.  If this is the last callback associated with the
     270             :      * host record, it is removed from any request queues it might be on.
     271             :      */
     272             :     void CancelAsyncRequest(const char                      *host,
     273             :                             const mozilla::OriginAttributes &aOriginAttributes,
     274             :                             uint16_t                         flags,
     275             :                             uint16_t                         af,
     276             :                             const char                      *netInterface,
     277             :                             nsIDNSListener                  *aListener,
     278             :                             nsresult                         status);
     279             :     /**
     280             :      * values for the flags parameter passed to ResolveHost and DetachCallback
     281             :      * that may be bitwise OR'd together.
     282             :      *
     283             :      * NOTE: in this implementation, these flags correspond exactly in value
     284             :      *       to the flags defined on nsIDNSService.
     285             :      */
     286             :     enum {
     287             :         RES_BYPASS_CACHE = nsIDNSService::RESOLVE_BYPASS_CACHE,
     288             :         RES_CANON_NAME = nsIDNSService::RESOLVE_CANONICAL_NAME,
     289             :         RES_PRIORITY_MEDIUM = nsIDNSService::RESOLVE_PRIORITY_MEDIUM,
     290             :         RES_PRIORITY_LOW = nsIDNSService::RESOLVE_PRIORITY_LOW,
     291             :         RES_SPECULATE = nsIDNSService::RESOLVE_SPECULATE,
     292             :         //RES_DISABLE_IPV6 = nsIDNSService::RESOLVE_DISABLE_IPV6, // Not used
     293             :         RES_OFFLINE = nsIDNSService::RESOLVE_OFFLINE,
     294             :         //RES_DISABLE_IPv4 = nsIDNSService::RESOLVE_DISABLE_IPV4, // Not Used
     295             :         RES_ALLOW_NAME_COLLISION = nsIDNSService::RESOLVE_ALLOW_NAME_COLLISION
     296             :     };
     297             : 
     298             :     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
     299             : 
     300             :     /**
     301             :      * Flush the DNS cache.
     302             :      */
     303             :     void FlushCache();
     304             : 
     305             : private:
     306             :    explicit nsHostResolver(uint32_t maxCacheEntries,
     307             :                            uint32_t defaultCacheEntryLifetime,
     308             :                            uint32_t defaultGracePeriod);
     309             :    ~nsHostResolver();
     310             : 
     311             :     nsresult Init();
     312             :     nsresult IssueLookup(nsHostRecord *);
     313             :     bool     GetHostToLookup(nsHostRecord **m);
     314             : 
     315             :     enum LookupStatus {
     316             :       LOOKUP_OK,
     317             :       LOOKUP_RESOLVEAGAIN,
     318             :     };
     319             : 
     320             :     LookupStatus OnLookupComplete(nsHostRecord *, nsresult, mozilla::net::AddrInfo *);
     321             :     void     DeQueue(PRCList &aQ, nsHostRecord **aResult);
     322             :     void     ClearPendingQueue(PRCList *aPendingQueue);
     323             :     nsresult ConditionallyCreateThread(nsHostRecord *rec);
     324             : 
     325             :     /**
     326             :      * Starts a new lookup in the background for entries that are in the grace
     327             :      * period with a failed connect or all cached entries are negative.
     328             :      */
     329             :     nsresult ConditionallyRefreshRecord(nsHostRecord *rec, const char *host);
     330             : 
     331             :     static void  MoveQueue(nsHostRecord *aRec, PRCList &aDestQ);
     332             : 
     333             :     static void ThreadFunc(void *);
     334             : 
     335             :     enum {
     336             :         METHOD_HIT = 1,
     337             :         METHOD_RENEWAL = 2,
     338             :         METHOD_NEGATIVE_HIT = 3,
     339             :         METHOD_LITERAL = 4,
     340             :         METHOD_OVERFLOW = 5,
     341             :         METHOD_NETWORK_FIRST = 6,
     342             :         METHOD_NETWORK_SHARED = 7
     343             :     };
     344             : 
     345             :     uint32_t      mMaxCacheEntries;
     346             :     uint32_t      mDefaultCacheLifetime; // granularity seconds
     347             :     uint32_t      mDefaultGracePeriod; // granularity seconds
     348             :     mutable Mutex mLock;    // mutable so SizeOfIncludingThis can be const
     349             :     CondVar       mIdleThreadCV;
     350             :     PLDHashTable  mDB;
     351             :     PRCList       mHighQ;
     352             :     PRCList       mMediumQ;
     353             :     PRCList       mLowQ;
     354             :     PRCList       mEvictionQ;
     355             :     uint32_t      mEvictionQSize;
     356             :     PRTime        mCreationTime;
     357             :     PRIntervalTime mLongIdleTimeout;
     358             :     PRIntervalTime mShortIdleTimeout;
     359             : 
     360             :     mozilla::Atomic<bool>     mShutdown;
     361             :     mozilla::Atomic<uint32_t> mNumIdleThreads;
     362             :     mozilla::Atomic<uint32_t> mThreadCount;
     363             :     mozilla::Atomic<uint32_t> mActiveAnyThreadCount;
     364             :     mozilla::Atomic<uint32_t> mPendingCount;
     365             : 
     366             :     // Set the expiration time stamps appropriately.
     367             :     void PrepareRecordExpiration(nsHostRecord* rec) const;
     368             : 
     369             : public:
     370             :     /*
     371             :      * Called by the networking dashboard via the DnsService2
     372             :      */
     373             :     void GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries> *);
     374             : };
     375             : 
     376             : #endif // nsHostResolver_h__

Generated by: LCOV version 1.13