netwerk/dns/nsHostResolver.h

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     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/. */
     6 #ifndef nsHostResolver_h__
     7 #define nsHostResolver_h__
     9 #include "nscore.h"
    10 #include "prclist.h"
    11 #include "prnetdb.h"
    12 #include "pldhash.h"
    13 #include "mozilla/CondVar.h"
    14 #include "mozilla/Mutex.h"
    15 #include "nsISupportsImpl.h"
    16 #include "nsIDNSListener.h"
    17 #include "nsString.h"
    18 #include "nsTArray.h"
    19 #include "mozilla/net/DNS.h"
    20 #include "mozilla/net/DashboardTypes.h"
    21 #include "mozilla/TimeStamp.h"
    23 class nsHostResolver;
    24 class nsHostRecord;
    25 class nsResolveHostCallback;
    27 #define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY  3
    28 #define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 5
    29 #define MAX_NON_PRIORITY_REQUESTS 150
    31 #define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \
    32                               MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)
    34 struct nsHostKey
    35 {
    36     const char *host;
    37     uint16_t    flags;
    38     uint16_t    af;
    39 };
    41 /**
    42  * nsHostRecord - ref counted object type stored in host resolver cache.
    43  */
    44 class nsHostRecord : public PRCList, public nsHostKey
    45 {
    46     typedef mozilla::Mutex Mutex;
    48 public:
    49     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHostRecord)
    51     /* instantiates a new host record */
    52     static nsresult Create(const nsHostKey *key, nsHostRecord **record);
    54     /* a fully resolved host record has either a non-null |addr_info| or |addr|
    55      * field.  if |addr_info| is null, it implies that the |host| is an IP
    56      * address literal.  in which case, |addr| contains the parsed address.
    57      * otherwise, if |addr_info| is non-null, then it contains one or many
    58      * IP addresses corresponding to the given host name.  if both |addr_info|
    59      * and |addr| are null, then the given host has not yet been fully resolved.
    60      * |af| is the address family of the record we are querying for.
    61      */
    63     /* the lock protects |addr_info| and |addr_info_gencnt| because they
    64      * are mutable and accessed by the resolver worker thread and the
    65      * nsDNSService2 class.  |addr| doesn't change after it has been
    66      * assigned a value.  only the resolver worker thread modifies
    67      * nsHostRecord (and only in nsHostResolver::OnLookupComplete);
    68      * the other threads just read it.  therefore the resolver worker
    69      * thread doesn't need to lock when reading |addr_info|.
    70      */
    71     Mutex        addr_info_lock;
    72     int          addr_info_gencnt; /* generation count of |addr_info| */
    73     mozilla::net::AddrInfo *addr_info;
    74     mozilla::net::NetAddr  *addr;
    75     bool         negative;   /* True if this record is a cache of a failed lookup.
    76                                 Negative cache entries are valid just like any other
    77                                 (though never for more than 60 seconds), but a use
    78                                 of that negative entry forces an asynchronous refresh. */
    80     mozilla::TimeStamp expiration;
    82     bool HasUsableResult(uint16_t queryFlags) const;
    84     // hold addr_info_lock when calling the blacklist functions
    85     bool   Blacklisted(mozilla::net::NetAddr *query);
    86     void   ResetBlacklist();
    87     void   ReportUnusable(mozilla::net::NetAddr *addr);
    89     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
    91 private:
    92     friend class nsHostResolver;
    94     PRCList callbacks; /* list of callbacks */
    96     bool    resolving; /* true if this record is being resolved, which means
    97                         * that it is either on the pending queue or owned by
    98                         * one of the worker threads. */
   100     bool    onQueue;  /* true if pending and on the queue (not yet given to getaddrinfo())*/
   101     bool    usingAnyThread; /* true if off queue and contributing to mActiveAnyThreadCount */
   102     bool    mDoomed; /* explicitly expired */
   104     // a list of addresses associated with this record that have been reported
   105     // as unusable. the list is kept as a set of strings to make it independent
   106     // of gencnt.
   107     nsTArray<nsCString> mBlacklistedItems;
   109     nsHostRecord(const nsHostKey *key);           /* use Create() instead */
   110    ~nsHostRecord();
   111 };
   113 /**
   114  * ResolveHost callback object.  It's PRCList members are used by
   115  * the nsHostResolver and should not be used by anything else.
   116  */
   117 class NS_NO_VTABLE nsResolveHostCallback : public PRCList
   118 {
   119 public:
   120     /**
   121      * OnLookupComplete
   122      * 
   123      * this function is called to complete a host lookup initiated by
   124      * nsHostResolver::ResolveHost.  it may be invoked recursively from
   125      * ResolveHost or on an unspecified background thread.
   126      * 
   127      * NOTE: it is the responsibility of the implementor of this method
   128      * to handle the callback in a thread safe manner.
   129      *
   130      * @param resolver
   131      *        nsHostResolver object associated with this result
   132      * @param record
   133      *        the host record containing the results of the lookup
   134      * @param status
   135      *        if successful, |record| contains non-null results
   136      */
   137     virtual void OnLookupComplete(nsHostResolver *resolver,
   138                                   nsHostRecord   *record,
   139                                   nsresult        status) = 0;
   140     /**
   141      * EqualsAsyncListener
   142      *
   143      * Determines if the listener argument matches the listener member var.
   144      * For subclasses not implementing a member listener, should return false.
   145      * For subclasses having a member listener, the function should check if
   146      * they are the same.  Used for cases where a pointer to an object
   147      * implementing nsResolveHostCallback is unknown, but a pointer to
   148      * the original listener is known.
   149      *
   150      * @param aListener
   151      *        nsIDNSListener object associated with the original request
   152      */
   153     virtual bool EqualsAsyncListener(nsIDNSListener *aListener) = 0;
   155     virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const = 0;
   156 };
   158 /**
   159  * nsHostResolver - an asynchronous host name resolver.
   160  */
   161 class nsHostResolver
   162 {
   163     typedef mozilla::CondVar CondVar;
   164     typedef mozilla::Mutex Mutex;
   166 public:
   167     /**
   168      * host resolver instances are reference counted.
   169      */
   170     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHostResolver)
   172     /**
   173      * creates an addref'd instance of a nsHostResolver object.
   174      */
   175     static nsresult Create(uint32_t         maxCacheEntries,  // zero disables cache
   176                            uint32_t         maxCacheLifetime, // seconds
   177                            uint32_t         lifetimeGracePeriod, // seconds
   178                            nsHostResolver **resolver);
   180     /**
   181      * puts the resolver in the shutdown state, which will cause any pending
   182      * callbacks to be detached.  any future calls to ResolveHost will fail.
   183      */
   184     void Shutdown();
   186     /**
   187      * resolve the given hostname asynchronously.  the caller can synthesize
   188      * a synchronous host lookup using a lock and a cvar.  as noted above
   189      * the callback will occur re-entrantly from an unspecified thread.  the
   190      * host lookup cannot be canceled (cancelation can be layered above this
   191      * by having the callback implementation return without doing anything).
   192      */
   193     nsresult ResolveHost(const char            *hostname,
   194                          uint16_t               flags,
   195                          uint16_t               af,
   196                          nsResolveHostCallback *callback);
   198     /**
   199      * removes the specified callback from the nsHostRecord for the given
   200      * hostname, flags, and address family.  these parameters should correspond
   201      * to the parameters passed to ResolveHost.  this function executes the
   202      * callback if the callback is still pending with the given status.
   203      */
   204     void DetachCallback(const char            *hostname,
   205                         uint16_t               flags,
   206                         uint16_t               af,
   207                         nsResolveHostCallback *callback,
   208                         nsresult               status);
   210     /**
   211      * Cancels an async request associated with the hostname, flags,
   212      * address family and listener.  Cancels first callback found which matches
   213      * these criteria.  These parameters should correspond to the parameters
   214      * passed to ResolveHost.  If this is the last callback associated with the
   215      * host record, it is removed from any request queues it might be on. 
   216      */
   217     void CancelAsyncRequest(const char            *host,
   218                             uint16_t               flags,
   219                             uint16_t               af,
   220                             nsIDNSListener        *aListener,
   221                             nsresult               status);
   222     /**
   223      * values for the flags parameter passed to ResolveHost and DetachCallback
   224      * that may be bitwise OR'd together.
   225      *
   226      * NOTE: in this implementation, these flags correspond exactly in value
   227      *       to the flags defined on nsIDNSService.
   228      */
   229     enum {
   230         RES_BYPASS_CACHE = 1 << 0,
   231         RES_CANON_NAME   = 1 << 1,
   232         RES_PRIORITY_MEDIUM   = 1 << 2,
   233         RES_PRIORITY_LOW  = 1 << 3,
   234         RES_SPECULATE     = 1 << 4,
   235         //RES_DISABLE_IPV6 = 1 << 5, // Not used
   236         RES_OFFLINE       = 1 << 6
   237     };
   239     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
   241 private:
   242     nsHostResolver(uint32_t maxCacheEntries = 50, uint32_t maxCacheLifetime = 60,
   243                    uint32_t lifetimeGracePeriod = 0);
   244    ~nsHostResolver();
   246     nsresult Init();
   247     nsresult IssueLookup(nsHostRecord *);
   248     bool     GetHostToLookup(nsHostRecord **m);
   249     void     OnLookupComplete(nsHostRecord *, nsresult, mozilla::net::AddrInfo *);
   250     void     DeQueue(PRCList &aQ, nsHostRecord **aResult);
   251     void     ClearPendingQueue(PRCList *aPendingQueue);
   252     nsresult ConditionallyCreateThread(nsHostRecord *rec);
   254     /**
   255      * Starts a new lookup in the background for entries that are in the grace
   256      * period with a failed connect or all cached entries are negative.
   257      */
   258     nsresult ConditionallyRefreshRecord(nsHostRecord *rec, const char *host);
   260     static void  MoveQueue(nsHostRecord *aRec, PRCList &aDestQ);
   262     static void ThreadFunc(void *);
   264     enum {
   265         METHOD_HIT = 1,
   266         METHOD_RENEWAL = 2,
   267         METHOD_NEGATIVE_HIT = 3,
   268         METHOD_LITERAL = 4,
   269         METHOD_OVERFLOW = 5,
   270         METHOD_NETWORK_FIRST = 6,
   271         METHOD_NETWORK_SHARED = 7
   272     };
   274     uint32_t      mMaxCacheEntries;
   275     mozilla::TimeDuration mMaxCacheLifetime; // granularity seconds
   276     mozilla::TimeDuration mGracePeriod; // granularity seconds
   277     mutable Mutex mLock;    // mutable so SizeOfIncludingThis can be const
   278     CondVar       mIdleThreadCV;
   279     uint32_t      mNumIdleThreads;
   280     uint32_t      mThreadCount;
   281     uint32_t      mActiveAnyThreadCount;
   282     PLDHashTable  mDB;
   283     PRCList       mHighQ;
   284     PRCList       mMediumQ;
   285     PRCList       mLowQ;
   286     PRCList       mEvictionQ;
   287     uint32_t      mEvictionQSize;
   288     uint32_t      mPendingCount;
   289     PRTime        mCreationTime;
   290     bool          mShutdown;
   291     PRIntervalTime mLongIdleTimeout;
   292     PRIntervalTime mShortIdleTimeout;
   294 public:
   295     /*
   296      * Called by the networking dashboard via the DnsService2
   297      */
   298     void GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries> *);
   299 };
   301 #endif // nsHostResolver_h__

mercurial