Bug 1807268 - Re-enable verifyShowClipboardSuggestionsToggleTest UI test r=jajohnson
[gecko.git] / netwerk / dns / nsHostResolver.h
blob02e6a343f80ed2ddc5fc1c8cf7d7886536a5f889
1 /* vim:set ts=4 sw=2 sts=2 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 "prnetdb.h"
11 #include "PLDHashTable.h"
12 #include "mozilla/CondVar.h"
13 #include "mozilla/DataMutex.h"
14 #include "nsISupportsImpl.h"
15 #include "nsIDNSListener.h"
16 #include "nsTArray.h"
17 #include "GetAddrInfo.h"
18 #include "HostRecordQueue.h"
19 #include "mozilla/net/DNS.h"
20 #include "mozilla/net/DashboardTypes.h"
21 #include "mozilla/Atomics.h"
22 #include "mozilla/TimeStamp.h"
23 #include "mozilla/UniquePtr.h"
24 #include "nsHostRecord.h"
25 #include "nsRefPtrHashtable.h"
26 #include "nsIThreadPool.h"
27 #include "mozilla/net/NetworkConnectivityService.h"
28 #include "mozilla/net/DNSByTypeRecord.h"
29 #include "mozilla/Maybe.h"
30 #include "mozilla/StaticPrefs_network.h"
32 namespace mozilla {
33 namespace net {
34 class TRR;
35 class TRRQuery;
37 static inline uint32_t MaxResolverThreadsAnyPriority() {
38 return StaticPrefs::network_dns_max_any_priority_threads();
41 static inline uint32_t MaxResolverThreadsHighPriority() {
42 return StaticPrefs::network_dns_max_high_priority_threads();
45 static inline uint32_t MaxResolverThreads() {
46 return MaxResolverThreadsAnyPriority() + MaxResolverThreadsHighPriority();
49 } // namespace net
50 } // namespace mozilla
52 #define TRR_DISABLED(x) \
53 (((x) == nsIDNSService::MODE_NATIVEONLY) || \
54 ((x) == nsIDNSService::MODE_TRROFF))
56 extern mozilla::Atomic<bool, mozilla::Relaxed> gNativeIsLocalhost;
58 #define MAX_NON_PRIORITY_REQUESTS 150
60 class AHostResolver {
61 public:
62 AHostResolver() = default;
63 virtual ~AHostResolver() = default;
64 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
66 enum LookupStatus {
67 LOOKUP_OK,
68 LOOKUP_RESOLVEAGAIN,
71 virtual LookupStatus CompleteLookup(nsHostRecord*, nsresult,
72 mozilla::net::AddrInfo*, bool pb,
73 const nsACString& aOriginsuffix,
74 mozilla::net::TRRSkippedReason aReason,
75 mozilla::net::TRR*) = 0;
76 virtual LookupStatus CompleteLookupByType(
77 nsHostRecord*, nsresult, mozilla::net::TypeRecordResultType& aResult,
78 mozilla::net::TRRSkippedReason aReason, uint32_t aTtl, bool pb) = 0;
79 virtual nsresult GetHostRecord(const nsACString& host,
80 const nsACString& aTrrServer, uint16_t type,
81 nsIDNSService::DNSFlags flags, uint16_t af,
82 bool pb, const nsCString& originSuffix,
83 nsHostRecord** result) {
84 return NS_ERROR_FAILURE;
86 virtual nsresult TrrLookup_unlocked(nsHostRecord*,
87 mozilla::net::TRR* pushedTRR = nullptr) {
88 return NS_ERROR_FAILURE;
90 virtual void MaybeRenewHostRecord(nsHostRecord* aRec) {}
93 /**
94 * nsHostResolver - an asynchronous host name resolver.
96 class nsHostResolver : public nsISupports, public AHostResolver {
97 using CondVar = mozilla::CondVar;
98 using Mutex = mozilla::Mutex;
100 public:
101 NS_DECL_THREADSAFE_ISUPPORTS
104 * creates an addref'd instance of a nsHostResolver object.
106 static nsresult Create(uint32_t maxCacheEntries, // zero disables cache
107 uint32_t defaultCacheEntryLifetime, // seconds
108 uint32_t defaultGracePeriod, // seconds
109 nsHostResolver** result);
112 * Set (new) cache limits.
114 void SetCacheLimits(uint32_t maxCacheEntries, // zero disables cache
115 uint32_t defaultCacheEntryLifetime, // seconds
116 uint32_t defaultGracePeriod); // seconds
119 * puts the resolver in the shutdown state, which will cause any pending
120 * callbacks to be detached. any future calls to ResolveHost will fail.
122 void Shutdown();
125 * resolve the given hostname and originAttributes asynchronously. the caller
126 * can synthesize a synchronous host lookup using a lock and a cvar. as noted
127 * above the callback will occur re-entrantly from an unspecified thread. the
128 * host lookup cannot be canceled (cancelation can be layered above this by
129 * having the callback implementation return without doing anything).
131 nsresult ResolveHost(const nsACString& aHost, const nsACString& trrServer,
132 int32_t aPort, uint16_t type,
133 const mozilla::OriginAttributes& aOriginAttributes,
134 nsIDNSService::DNSFlags flags, uint16_t af,
135 nsResolveHostCallback* callback);
137 nsHostRecord* InitRecord(const nsHostKey& key);
138 mozilla::net::NetworkConnectivityService* GetNCS() {
139 return mNCS;
140 } // This is actually a singleton
143 * return a resolved hard coded loopback dns record for the specified key
145 already_AddRefed<nsHostRecord> InitLoopbackRecord(const nsHostKey& key,
146 nsresult* aRv);
149 * removes the specified callback from the nsHostRecord for the given
150 * hostname, originAttributes, flags, and address family. these parameters
151 * should correspond to the parameters passed to ResolveHost. this function
152 * executes the callback if the callback is still pending with the given
153 * status.
155 void DetachCallback(const nsACString& hostname, const nsACString& trrServer,
156 uint16_t type,
157 const mozilla::OriginAttributes& aOriginAttributes,
158 nsIDNSService::DNSFlags flags, uint16_t af,
159 nsResolveHostCallback* callback, nsresult status);
162 * Cancels an async request associated with the hostname, originAttributes,
163 * flags, address family and listener. Cancels first callback found which
164 * matches these criteria. These parameters should correspond to the
165 * parameters passed to ResolveHost. If this is the last callback associated
166 * with the host record, it is removed from any request queues it might be on.
168 void CancelAsyncRequest(const nsACString& host, const nsACString& trrServer,
169 uint16_t type,
170 const mozilla::OriginAttributes& aOriginAttributes,
171 nsIDNSService::DNSFlags flags, uint16_t af,
172 nsIDNSListener* aListener, nsresult status);
174 * values for the flags parameter passed to ResolveHost and DetachCallback
175 * that may be bitwise OR'd together.
177 * NOTE: in this implementation, these flags correspond exactly in value
178 * to the flags defined on nsIDNSService.
180 enum {
181 RES_BYPASS_CACHE = nsIDNSService::RESOLVE_BYPASS_CACHE,
182 RES_CANON_NAME = nsIDNSService::RESOLVE_CANONICAL_NAME,
183 RES_PRIORITY_MEDIUM = nsHostRecord::DNS_PRIORITY_MEDIUM,
184 RES_PRIORITY_LOW = nsHostRecord::DNS_PRIORITY_LOW,
185 RES_SPECULATE = nsIDNSService::RESOLVE_SPECULATE,
186 // RES_DISABLE_IPV6 = nsIDNSService::RESOLVE_DISABLE_IPV6, // Not used
187 RES_OFFLINE = nsIDNSService::RESOLVE_OFFLINE,
188 // RES_DISABLE_IPv4 = nsIDNSService::RESOLVE_DISABLE_IPV4, // Not Used
189 RES_ALLOW_NAME_COLLISION = nsIDNSService::RESOLVE_ALLOW_NAME_COLLISION,
190 RES_DISABLE_TRR = nsIDNSService::RESOLVE_DISABLE_TRR,
191 RES_REFRESH_CACHE = nsIDNSService::RESOLVE_REFRESH_CACHE,
192 RES_IP_HINT = nsIDNSService::RESOLVE_IP_HINT
195 size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
198 * Flush the DNS cache.
200 void FlushCache(bool aTrrToo);
202 LookupStatus CompleteLookup(nsHostRecord*, nsresult, mozilla::net::AddrInfo*,
203 bool pb, const nsACString& aOriginsuffix,
204 mozilla::net::TRRSkippedReason aReason,
205 mozilla::net::TRR* aTRRRequest) override;
206 LookupStatus CompleteLookupByType(nsHostRecord*, nsresult,
207 mozilla::net::TypeRecordResultType& aResult,
208 mozilla::net::TRRSkippedReason aReason,
209 uint32_t aTtl, bool pb) override;
210 nsresult GetHostRecord(const nsACString& host, const nsACString& trrServer,
211 uint16_t type, nsIDNSService::DNSFlags flags,
212 uint16_t af, bool pb, const nsCString& originSuffix,
213 nsHostRecord** result) override;
214 nsresult TrrLookup_unlocked(nsHostRecord*,
215 mozilla::net::TRR* pushedTRR = nullptr) override;
216 static nsIDNSService::ResolverMode Mode();
218 virtual void MaybeRenewHostRecord(nsHostRecord* aRec) override;
220 // Records true if the TRR service is enabled for the record's effective
221 // TRR mode. Also records the TRRSkipReason when the TRR service is not
222 // available/enabled.
223 bool TRRServiceEnabledForRecord(nsHostRecord* aRec) MOZ_REQUIRES(mLock);
225 private:
226 explicit nsHostResolver(uint32_t maxCacheEntries,
227 uint32_t defaultCacheEntryLifetime,
228 uint32_t defaultGracePeriod);
229 virtual ~nsHostResolver();
231 bool DoRetryTRR(AddrHostRecord* aAddrRec,
232 const mozilla::MutexAutoLock& aLock);
233 bool MaybeRetryTRRLookup(
234 AddrHostRecord* aAddrRec, nsresult aFirstAttemptStatus,
235 mozilla::net::TRRSkippedReason aFirstAttemptSkipReason,
236 nsresult aChannelStatus, const mozilla::MutexAutoLock& aLock);
238 LookupStatus CompleteLookupLocked(nsHostRecord*, nsresult,
239 mozilla::net::AddrInfo*, bool pb,
240 const nsACString& aOriginsuffix,
241 mozilla::net::TRRSkippedReason aReason,
242 mozilla::net::TRR* aTRRRequest,
243 const mozilla::MutexAutoLock& aLock)
244 MOZ_REQUIRES(mLock);
245 LookupStatus CompleteLookupByTypeLocked(
246 nsHostRecord*, nsresult, mozilla::net::TypeRecordResultType& aResult,
247 mozilla::net::TRRSkippedReason aReason, uint32_t aTtl, bool pb,
248 const mozilla::MutexAutoLock& aLock) MOZ_REQUIRES(mLock);
249 nsresult Init();
250 static void ComputeEffectiveTRRMode(nsHostRecord* aRec);
251 nsresult NativeLookup(nsHostRecord* aRec,
252 const mozilla::MutexAutoLock& aLock);
253 nsresult TrrLookup(nsHostRecord*, const mozilla::MutexAutoLock& aLock,
254 mozilla::net::TRR* pushedTRR = nullptr);
256 // Kick-off a name resolve operation, using native resolver and/or TRR
257 nsresult NameLookup(nsHostRecord* aRec, const mozilla::MutexAutoLock& aLock);
258 bool GetHostToLookup(nsHostRecord** result);
259 void MaybeRenewHostRecordLocked(nsHostRecord* aRec,
260 const mozilla::MutexAutoLock& aLock)
261 MOZ_REQUIRES(mLock);
263 // Cancels host records in the pending queue and also
264 // calls CompleteLookup with the NS_ERROR_ABORT result code.
265 void ClearPendingQueue(mozilla::LinkedList<RefPtr<nsHostRecord>>& aPendingQ);
266 nsresult ConditionallyCreateThread(nsHostRecord* rec) MOZ_REQUIRES(mLock);
269 * Starts a new lookup in the background for entries that are in the grace
270 * period with a failed connect or all cached entries are negative.
272 nsresult ConditionallyRefreshRecord(nsHostRecord* rec, const nsACString& host,
273 const mozilla::MutexAutoLock& aLock)
274 MOZ_REQUIRES(mLock);
276 void OnResolveComplete(nsHostRecord* aRec,
277 const mozilla::MutexAutoLock& aLock)
278 MOZ_REQUIRES(mLock);
280 void AddToEvictionQ(nsHostRecord* rec, const mozilla::MutexAutoLock& aLock)
281 MOZ_REQUIRES(mLock);
283 void ThreadFunc();
285 // Resolve the host from the DNS cache.
286 already_AddRefed<nsHostRecord> FromCache(nsHostRecord* aRec,
287 const nsACString& aHost,
288 uint16_t aType, nsresult& aStatus,
289 const mozilla::MutexAutoLock& aLock)
290 MOZ_REQUIRES(mLock);
291 // Called when the host name is an IP address and has been passed.
292 already_AddRefed<nsHostRecord> FromCachedIPLiteral(nsHostRecord* aRec);
293 // Like the above function, but the host name is not parsed to NetAddr yet.
294 already_AddRefed<nsHostRecord> FromIPLiteral(
295 AddrHostRecord* aAddrRec, const mozilla::net::NetAddr& aAddr);
296 // Called to check if we have an AF_UNSPEC entry in the cache.
297 already_AddRefed<nsHostRecord> FromUnspecEntry(
298 nsHostRecord* aRec, const nsACString& aHost, const nsACString& aTrrServer,
299 const nsACString& aOriginSuffix, uint16_t aType,
300 nsIDNSService::DNSFlags aFlags, uint16_t af, bool aPb, nsresult& aStatus)
301 MOZ_REQUIRES(mLock);
303 enum {
304 METHOD_HIT = 1,
305 METHOD_RENEWAL = 2,
306 METHOD_NEGATIVE_HIT = 3,
307 METHOD_LITERAL = 4,
308 METHOD_OVERFLOW = 5,
309 METHOD_NETWORK_FIRST = 6,
310 METHOD_NETWORK_SHARED = 7
313 uint32_t mMaxCacheEntries = 0;
314 uint32_t mDefaultCacheLifetime = 0; // granularity seconds
315 uint32_t mDefaultGracePeriod = 0; // granularity seconds
316 // mutable so SizeOfIncludingThis can be const
317 mutable Mutex mLock{"nsHostResolver.mLock"};
318 CondVar mIdleTaskCV;
319 nsRefPtrHashtable<nsGenericHashKey<nsHostKey>, nsHostRecord> mRecordDB
320 MOZ_GUARDED_BY(mLock);
321 PRTime mCreationTime;
322 mozilla::TimeDuration mLongIdleTimeout;
323 mozilla::TimeDuration mShortIdleTimeout;
325 RefPtr<nsIThreadPool> mResolverThreads;
326 RefPtr<mozilla::net::NetworkConnectivityService>
327 mNCS; // reference to a singleton
328 mozilla::net::HostRecordQueue mQueue MOZ_GUARDED_BY(mLock);
329 mozilla::Atomic<bool> mShutdown MOZ_GUARDED_BY(mLock){true};
330 mozilla::Atomic<uint32_t> mNumIdleTasks MOZ_GUARDED_BY(mLock){0};
331 mozilla::Atomic<uint32_t> mActiveTaskCount MOZ_GUARDED_BY(mLock){0};
332 mozilla::Atomic<uint32_t> mActiveAnyThreadCount MOZ_GUARDED_BY(mLock){0};
334 // Set the expiration time stamps appropriately.
335 void PrepareRecordExpirationAddrRecord(AddrHostRecord* rec) const;
337 public:
339 * Called by the networking dashboard via the DnsService2
341 void GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries>*);
344 #endif // nsHostResolver_h__