Merge mozilla-beta to b2g34. a=merge
[gecko.git] / netwerk / dns / nsHostResolver.h
blob3c60152eab5b5cad4d0561ca7497fa93d037b003
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
36 const char *host;
37 uint16_t flags;
38 uint16_t af;
41 /**
42 * nsHostRecord - ref counted object type stored in host resolver cache.
44 class nsHostRecord : public PRCList, public nsHostKey
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.
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|.
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 explicit nsHostRecord(const nsHostKey *key); /* use Create() instead */
110 ~nsHostRecord();
114 * ResolveHost callback object. It's PRCList members are used by
115 * the nsHostResolver and should not be used by anything else.
117 class NS_NO_VTABLE nsResolveHostCallback : public PRCList
119 public:
121 * OnLookupComplete
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.
127 * NOTE: it is the responsibility of the implementor of this method
128 * to handle the callback in a thread safe manner.
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
137 virtual void OnLookupComplete(nsHostResolver *resolver,
138 nsHostRecord *record,
139 nsresult status) = 0;
141 * EqualsAsyncListener
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.
150 * @param aListener
151 * nsIDNSListener object associated with the original request
153 virtual bool EqualsAsyncListener(nsIDNSListener *aListener) = 0;
155 virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const = 0;
159 * nsHostResolver - an asynchronous host name resolver.
161 class nsHostResolver
163 typedef mozilla::CondVar CondVar;
164 typedef mozilla::Mutex Mutex;
166 public:
168 * host resolver instances are reference counted.
170 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHostResolver)
173 * creates an addref'd instance of a nsHostResolver object.
175 static nsresult Create(uint32_t maxCacheEntries, // zero disables cache
176 uint32_t maxCacheLifetime, // seconds
177 uint32_t lifetimeGracePeriod, // seconds
178 nsHostResolver **resolver);
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.
184 void Shutdown();
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).
193 nsresult ResolveHost(const char *hostname,
194 uint16_t flags,
195 uint16_t af,
196 nsResolveHostCallback *callback);
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.
204 void DetachCallback(const char *hostname,
205 uint16_t flags,
206 uint16_t af,
207 nsResolveHostCallback *callback,
208 nsresult status);
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.
217 void CancelAsyncRequest(const char *host,
218 uint16_t flags,
219 uint16_t af,
220 nsIDNSListener *aListener,
221 nsresult status);
223 * values for the flags parameter passed to ResolveHost and DetachCallback
224 * that may be bitwise OR'd together.
226 * NOTE: in this implementation, these flags correspond exactly in value
227 * to the flags defined on nsIDNSService.
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
239 size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
241 private:
242 explicit 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);
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.
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
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:
296 * Called by the networking dashboard via the DnsService2
298 void GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries> *);
301 #endif // nsHostResolver_h__