/src/mozilla-central/netwerk/dns/nsHostResolver.h
Line | Count | Source (jump to first uncovered line) |
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 "prnetdb.h" |
11 | | #include "PLDHashTable.h" |
12 | | #include "mozilla/CondVar.h" |
13 | | #include "mozilla/Mutex.h" |
14 | | #include "nsISupportsImpl.h" |
15 | | #include "nsIDNSListener.h" |
16 | | #include "nsIDNSService.h" |
17 | | #include "nsTArray.h" |
18 | | #include "GetAddrInfo.h" |
19 | | #include "mozilla/net/DNS.h" |
20 | | #include "mozilla/net/DashboardTypes.h" |
21 | | #include "mozilla/Atomics.h" |
22 | | #include "mozilla/LinkedList.h" |
23 | | #include "mozilla/TimeStamp.h" |
24 | | #include "mozilla/UniquePtr.h" |
25 | | #include "nsRefPtrHashtable.h" |
26 | | #include "nsIThreadPool.h" |
27 | | |
28 | | class nsHostResolver; |
29 | | class nsResolveHostCallback; |
30 | | namespace mozilla { namespace net { |
31 | | class TRR; |
32 | | enum ResolverMode { |
33 | | MODE_NATIVEONLY, // 0 - TRR OFF (by default) |
34 | | MODE_PARALLEL, // 1 - race and use the first response |
35 | | MODE_TRRFIRST, // 2 - fallback to native on TRR failure |
36 | | MODE_TRRONLY, // 3 - don't even fallback |
37 | | MODE_SHADOW, // 4 - race for stats, but always use native result |
38 | | MODE_TRROFF // 5 - identical to MODE_NATIVEONLY but explicitly selected |
39 | | }; |
40 | | } } |
41 | | |
42 | 0 | #define TRR_DISABLED(x) (((x) == MODE_NATIVEONLY) || ((x) == MODE_TRROFF)) |
43 | | |
44 | | extern mozilla::Atomic<bool, mozilla::Relaxed> gNativeIsLocalhost; |
45 | | |
46 | 0 | #define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY 3 |
47 | 0 | #define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 5 |
48 | 0 | #define MAX_NON_PRIORITY_REQUESTS 150 |
49 | | |
50 | 0 | #define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \ |
51 | 0 | MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY) |
52 | | |
53 | | struct nsHostKey |
54 | | { |
55 | | const nsCString host; |
56 | | uint16_t type; |
57 | | uint16_t flags; |
58 | | uint16_t af; |
59 | | bool pb; |
60 | | const nsCString originSuffix; |
61 | | explicit nsHostKey(const nsACString& host, uint16_t type, uint16_t flags, |
62 | | uint16_t af, bool pb, const nsACString& originSuffix); |
63 | | bool operator==(const nsHostKey& other) const; |
64 | | size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; |
65 | | PLDHashNumber Hash() const; |
66 | | }; |
67 | | |
68 | | /** |
69 | | * nsHostRecord - ref counted object type stored in host resolver cache. |
70 | | */ |
71 | | class nsHostRecord : |
72 | | public mozilla::LinkedListElement<RefPtr<nsHostRecord>>, |
73 | | public nsHostKey |
74 | | { |
75 | | typedef mozilla::Mutex Mutex; |
76 | | |
77 | | public: |
78 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHostRecord) |
79 | | |
80 | | /* a fully resolved host record has either a non-null |addr_info| or |addr| |
81 | | * field. if |addr_info| is null, it implies that the |host| is an IP |
82 | | * address literal. in which case, |addr| contains the parsed address. |
83 | | * otherwise, if |addr_info| is non-null, then it contains one or many |
84 | | * IP addresses corresponding to the given host name. if both |addr_info| |
85 | | * and |addr| are null, then the given host has not yet been fully resolved. |
86 | | * |af| is the address family of the record we are querying for. |
87 | | */ |
88 | | |
89 | | /* the lock protects |addr_info| and |addr_info_gencnt| because they |
90 | | * are mutable and accessed by the resolver worker thread and the |
91 | | * nsDNSService2 class. |addr| doesn't change after it has been |
92 | | * assigned a value. only the resolver worker thread modifies |
93 | | * nsHostRecord (and only in nsHostResolver::CompleteLookup); |
94 | | * the other threads just read it. therefore the resolver worker |
95 | | * thread doesn't need to lock when reading |addr_info|. |
96 | | */ |
97 | | Mutex addr_info_lock; |
98 | | int addr_info_gencnt; /* generation count of |addr_info| */ |
99 | | mozilla::net::AddrInfo *addr_info; |
100 | | mozilla::UniquePtr<mozilla::net::NetAddr> addr; |
101 | | bool negative; /* True if this record is a cache of a failed lookup. |
102 | | Negative cache entries are valid just like any other |
103 | | (though never for more than 60 seconds), but a use |
104 | | of that negative entry forces an asynchronous refresh. */ |
105 | | |
106 | | enum ExpirationStatus { |
107 | | EXP_VALID, |
108 | | EXP_GRACE, |
109 | | EXP_EXPIRED, |
110 | | }; |
111 | | |
112 | | ExpirationStatus CheckExpiration(const mozilla::TimeStamp& now) const; |
113 | | |
114 | | // When the record began being valid. Used mainly for bookkeeping. |
115 | | mozilla::TimeStamp mValidStart; |
116 | | |
117 | | // When the record is no longer valid (it's time of expiration) |
118 | | mozilla::TimeStamp mValidEnd; |
119 | | |
120 | | // When the record enters its grace period. This must be before mValidEnd. |
121 | | // If a record is in its grace period (and not expired), it will be used |
122 | | // but a request to refresh it will be made. |
123 | | mozilla::TimeStamp mGraceStart; |
124 | | |
125 | | // When the lookups of this record started and their durations |
126 | | mozilla::TimeStamp mTrrStart; |
127 | | mozilla::TimeStamp mNativeStart; |
128 | | mozilla::TimeDuration mTrrDuration; |
129 | | mozilla::TimeDuration mNativeDuration; |
130 | | |
131 | | // Convenience function for setting the timestamps above (mValidStart, |
132 | | // mValidEnd, and mGraceStart). valid and grace are durations in seconds. |
133 | | void SetExpiration(const mozilla::TimeStamp& now, unsigned int valid, |
134 | | unsigned int grace); |
135 | | void CopyExpirationTimesAndFlagsFrom(const nsHostRecord *aFromHostRecord); |
136 | | |
137 | | // Checks if the record is usable (not expired and has a value) |
138 | | bool HasUsableResult(const mozilla::TimeStamp& now, uint16_t queryFlags = 0) const; |
139 | | |
140 | | // Mark hostrecord as not usable |
141 | | void Invalidate(); |
142 | | |
143 | | // hold addr_info_lock when calling the blacklist functions |
144 | | bool Blacklisted(mozilla::net::NetAddr *query); |
145 | | void ResetBlacklist(); |
146 | | void ReportUnusable(mozilla::net::NetAddr *addr); |
147 | | |
148 | | size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; |
149 | | |
150 | | enum DnsPriority { |
151 | | DNS_PRIORITY_LOW, |
152 | | DNS_PRIORITY_MEDIUM, |
153 | | DNS_PRIORITY_HIGH, |
154 | | }; |
155 | | static DnsPriority GetPriority(uint16_t aFlags); |
156 | | |
157 | | bool RemoveOrRefresh(); // Mark records currently being resolved as needed |
158 | | // to resolve again. |
159 | 0 | bool IsTRR() { return mTRRUsed; } |
160 | | void ResolveComplete(); |
161 | | void Cancel(); |
162 | | |
163 | | mozilla::net::ResolverMode mResolverMode; |
164 | | |
165 | | nsTArray<nsCString> mRequestByTypeResult; |
166 | | Mutex mRequestByTypeResultLock; |
167 | | |
168 | | private: |
169 | | friend class nsHostResolver; |
170 | | |
171 | | explicit nsHostRecord(const nsHostKey& key); |
172 | | mozilla::LinkedList<RefPtr<nsResolveHostCallback>> mCallbacks; |
173 | | nsAutoPtr<mozilla::net::AddrInfo> mFirstTRR; // partial TRR storage |
174 | | nsresult mFirstTRRresult; |
175 | | |
176 | | uint16_t mResolving; // counter of outstanding resolving calls |
177 | | uint8_t mTRRSuccess; // number of successful TRR responses |
178 | | uint8_t mNativeSuccess; // number of native lookup responses |
179 | | |
180 | | uint16_t mNative : 1; // true if this record is being resolved "natively", |
181 | | // which means that it is either on the pending queue |
182 | | // or owned by one of the worker threads. */ |
183 | | uint16_t mTRRUsed : 1; // TRR was used on this record |
184 | | uint16_t mNativeUsed : 1; |
185 | | uint16_t onQueue : 1; // true if pending and on the queue (not yet given to getaddrinfo()) |
186 | | uint16_t usingAnyThread : 1; // true if off queue and contributing to mActiveAnyThreadCount |
187 | | uint16_t mDoomed : 1; // explicitly expired |
188 | | uint16_t mDidCallbacks : 1; |
189 | | uint16_t mGetTtl : 1; |
190 | | |
191 | | // when the results from this resolve is returned, it is not to be |
192 | | // trusted, but instead a new resolve must be made! |
193 | | uint16_t mResolveAgain : 1; |
194 | | |
195 | | enum { |
196 | | INIT, STARTED, OK, FAILED |
197 | | } mTrrAUsed, mTrrAAAAUsed; |
198 | | |
199 | | Mutex mTrrLock; // lock when accessing the mTrrA[AAA] pointers |
200 | | RefPtr<mozilla::net::TRR> mTrrA; |
201 | | RefPtr<mozilla::net::TRR> mTrrAAAA; |
202 | | RefPtr<mozilla::net::TRR> mTrrTxt; |
203 | | |
204 | | // The number of times ReportUnusable() has been called in the record's |
205 | | // lifetime. |
206 | | uint32_t mBlacklistedCount; |
207 | | |
208 | | // a list of addresses associated with this record that have been reported |
209 | | // as unusable. the list is kept as a set of strings to make it independent |
210 | | // of gencnt. |
211 | | nsTArray<nsCString> mBlacklistedItems; |
212 | | |
213 | | ~nsHostRecord(); |
214 | | }; |
215 | | |
216 | | /** |
217 | | * This class is used to notify listeners when a ResolveHost operation is |
218 | | * complete. Classes that derive it must implement threadsafe nsISupports |
219 | | * to be able to use RefPtr with this class. |
220 | | */ |
221 | | class nsResolveHostCallback |
222 | | : public mozilla::LinkedListElement<RefPtr<nsResolveHostCallback>> |
223 | | , public nsISupports |
224 | | { |
225 | | public: |
226 | | /** |
227 | | * OnResolveHostComplete |
228 | | * |
229 | | * this function is called to complete a host lookup initiated by |
230 | | * nsHostResolver::ResolveHost. it may be invoked recursively from |
231 | | * ResolveHost or on an unspecified background thread. |
232 | | * |
233 | | * NOTE: it is the responsibility of the implementor of this method |
234 | | * to handle the callback in a thread safe manner. |
235 | | * |
236 | | * @param resolver |
237 | | * nsHostResolver object associated with this result |
238 | | * @param record |
239 | | * the host record containing the results of the lookup |
240 | | * @param status |
241 | | * if successful, |record| contains non-null results |
242 | | */ |
243 | | virtual void OnResolveHostComplete(nsHostResolver *resolver, |
244 | | nsHostRecord *record, |
245 | | nsresult status) = 0; |
246 | | /** |
247 | | * EqualsAsyncListener |
248 | | * |
249 | | * Determines if the listener argument matches the listener member var. |
250 | | * For subclasses not implementing a member listener, should return false. |
251 | | * For subclasses having a member listener, the function should check if |
252 | | * they are the same. Used for cases where a pointer to an object |
253 | | * implementing nsResolveHostCallback is unknown, but a pointer to |
254 | | * the original listener is known. |
255 | | * |
256 | | * @param aListener |
257 | | * nsIDNSListener object associated with the original request |
258 | | */ |
259 | | virtual bool EqualsAsyncListener(nsIDNSListener *aListener) = 0; |
260 | | |
261 | | virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const = 0; |
262 | | protected: |
263 | 0 | virtual ~nsResolveHostCallback() = default; |
264 | | }; |
265 | | |
266 | | class AHostResolver |
267 | | { |
268 | | public: |
269 | 6 | AHostResolver() = default; |
270 | 0 | virtual ~AHostResolver() = default; |
271 | | NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING |
272 | | |
273 | | enum LookupStatus { |
274 | | LOOKUP_OK, |
275 | | LOOKUP_RESOLVEAGAIN, |
276 | | }; |
277 | | |
278 | | virtual LookupStatus CompleteLookup(nsHostRecord *, nsresult, mozilla::net::AddrInfo *, bool pb) = 0; |
279 | | virtual LookupStatus CompleteLookupByType(nsHostRecord *, nsresult, |
280 | | const nsTArray<nsCString> *aResult, |
281 | | uint32_t aTtl, bool pb) = 0; |
282 | | virtual nsresult GetHostRecord(const nsACString &host, |
283 | | uint16_t flags, uint16_t af, bool pb, |
284 | | const nsCString &originSuffix, |
285 | | nsHostRecord **result) |
286 | 0 | { |
287 | 0 | return NS_ERROR_FAILURE; |
288 | 0 | } |
289 | | virtual nsresult TrrLookup_unlocked(nsHostRecord *, mozilla::net::TRR *pushedTRR = nullptr) |
290 | 0 | { |
291 | 0 | return NS_ERROR_FAILURE; |
292 | 0 | } |
293 | | }; |
294 | | |
295 | | /** |
296 | | * nsHostResolver - an asynchronous host name resolver. |
297 | | */ |
298 | | class nsHostResolver : public nsISupports, public AHostResolver |
299 | | { |
300 | | typedef mozilla::CondVar CondVar; |
301 | | typedef mozilla::Mutex Mutex; |
302 | | |
303 | | public: |
304 | | NS_DECL_THREADSAFE_ISUPPORTS |
305 | | |
306 | | /** |
307 | | * creates an addref'd instance of a nsHostResolver object. |
308 | | */ |
309 | | static nsresult Create(uint32_t maxCacheEntries, // zero disables cache |
310 | | uint32_t defaultCacheEntryLifetime, // seconds |
311 | | uint32_t defaultGracePeriod, // seconds |
312 | | nsHostResolver **resolver); |
313 | | |
314 | | /** |
315 | | * Set (new) cache limits. |
316 | | */ |
317 | | void SetCacheLimits(uint32_t maxCacheEntries, // zero disables cache |
318 | | uint32_t defaultCacheEntryLifetime, // seconds |
319 | | uint32_t defaultGracePeriod); // seconds |
320 | | |
321 | | /** |
322 | | * puts the resolver in the shutdown state, which will cause any pending |
323 | | * callbacks to be detached. any future calls to ResolveHost will fail. |
324 | | */ |
325 | | void Shutdown(); |
326 | | |
327 | | /** |
328 | | * resolve the given hostname and originAttributes asynchronously. the caller |
329 | | * can synthesize a synchronous host lookup using a lock and a cvar. as noted |
330 | | * above the callback will occur re-entrantly from an unspecified thread. the |
331 | | * host lookup cannot be canceled (cancelation can be layered above this by |
332 | | * having the callback implementation return without doing anything). |
333 | | */ |
334 | | nsresult ResolveHost(const nsACString &hostname, |
335 | | uint16_t type, |
336 | | const mozilla::OriginAttributes &aOriginAttributes, |
337 | | uint16_t flags, |
338 | | uint16_t af, |
339 | | nsResolveHostCallback *callback); |
340 | | |
341 | | /** |
342 | | * removes the specified callback from the nsHostRecord for the given |
343 | | * hostname, originAttributes, flags, and address family. these parameters |
344 | | * should correspond to the parameters passed to ResolveHost. this function |
345 | | * executes the callback if the callback is still pending with the given status. |
346 | | */ |
347 | | void DetachCallback(const nsACString &hostname, |
348 | | uint16_t type, |
349 | | const mozilla::OriginAttributes &aOriginAttributes, |
350 | | uint16_t flags, |
351 | | uint16_t af, |
352 | | nsResolveHostCallback *callback, |
353 | | nsresult status); |
354 | | |
355 | | /** |
356 | | * Cancels an async request associated with the hostname, originAttributes, flags, |
357 | | * address family and listener. Cancels first callback found which matches |
358 | | * these criteria. These parameters should correspond to the parameters |
359 | | * passed to ResolveHost. If this is the last callback associated with the |
360 | | * host record, it is removed from any request queues it might be on. |
361 | | */ |
362 | | void CancelAsyncRequest(const nsACString &host, |
363 | | uint16_t type, |
364 | | const mozilla::OriginAttributes &aOriginAttributes, |
365 | | uint16_t flags, |
366 | | uint16_t af, |
367 | | nsIDNSListener *aListener, |
368 | | nsresult status); |
369 | | /** |
370 | | * values for the flags parameter passed to ResolveHost and DetachCallback |
371 | | * that may be bitwise OR'd together. |
372 | | * |
373 | | * NOTE: in this implementation, these flags correspond exactly in value |
374 | | * to the flags defined on nsIDNSService. |
375 | | */ |
376 | | enum { |
377 | | RES_BYPASS_CACHE = nsIDNSService::RESOLVE_BYPASS_CACHE, |
378 | | RES_CANON_NAME = nsIDNSService::RESOLVE_CANONICAL_NAME, |
379 | | RES_PRIORITY_MEDIUM = nsIDNSService::RESOLVE_PRIORITY_MEDIUM, |
380 | | RES_PRIORITY_LOW = nsIDNSService::RESOLVE_PRIORITY_LOW, |
381 | | RES_SPECULATE = nsIDNSService::RESOLVE_SPECULATE, |
382 | | //RES_DISABLE_IPV6 = nsIDNSService::RESOLVE_DISABLE_IPV6, // Not used |
383 | | RES_OFFLINE = nsIDNSService::RESOLVE_OFFLINE, |
384 | | //RES_DISABLE_IPv4 = nsIDNSService::RESOLVE_DISABLE_IPV4, // Not Used |
385 | | RES_ALLOW_NAME_COLLISION = nsIDNSService::RESOLVE_ALLOW_NAME_COLLISION, |
386 | | RES_DISABLE_TRR = nsIDNSService::RESOLVE_DISABLE_TRR, |
387 | | RES_REFRESH_CACHE = nsIDNSService::RESOLVE_REFRESH_CACHE |
388 | | }; |
389 | | |
390 | | size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; |
391 | | |
392 | | /** |
393 | | * Flush the DNS cache. |
394 | | */ |
395 | | void FlushCache(); |
396 | | |
397 | | LookupStatus CompleteLookup(nsHostRecord *, nsresult, mozilla::net::AddrInfo *, bool pb) override; |
398 | | LookupStatus CompleteLookupByType(nsHostRecord *, nsresult, |
399 | | const nsTArray<nsCString> *aResult, |
400 | | uint32_t aTtl, bool pb) override; |
401 | | nsresult GetHostRecord(const nsACString &host, |
402 | | uint16_t flags, uint16_t af, bool pb, |
403 | | const nsCString &originSuffix, |
404 | | nsHostRecord **result) override; |
405 | | nsresult TrrLookup_unlocked(nsHostRecord *, mozilla::net::TRR *pushedTRR = nullptr) override; |
406 | | |
407 | | private: |
408 | | explicit nsHostResolver(uint32_t maxCacheEntries, |
409 | | uint32_t defaultCacheEntryLifetime, |
410 | | uint32_t defaultGracePeriod); |
411 | | virtual ~nsHostResolver(); |
412 | | |
413 | | nsresult Init(); |
414 | | // In debug builds it asserts that the element is in the list. |
415 | | void AssertOnQ(nsHostRecord *, mozilla::LinkedList<RefPtr<nsHostRecord>>&); |
416 | | mozilla::net::ResolverMode Mode(); |
417 | | nsresult NativeLookup(nsHostRecord *); |
418 | | nsresult TrrLookup(nsHostRecord *, mozilla::net::TRR *pushedTRR = nullptr); |
419 | | |
420 | | // Kick-off a name resolve operation, using native resolver and/or TRR |
421 | | nsresult NameLookup(nsHostRecord *); |
422 | | bool GetHostToLookup(nsHostRecord **m); |
423 | | |
424 | | // Removes the first element from the list and returns it AddRef-ed in aResult |
425 | | // Should not be called for an empty linked list. |
426 | | void DeQueue(mozilla::LinkedList<RefPtr<nsHostRecord>>& aQ, nsHostRecord **aResult); |
427 | | // Cancels host records in the pending queue and also |
428 | | // calls CompleteLookup with the NS_ERROR_ABORT result code. |
429 | | void ClearPendingQueue(mozilla::LinkedList<RefPtr<nsHostRecord>>& aPendingQ); |
430 | | nsresult ConditionallyCreateThread(nsHostRecord *rec); |
431 | | |
432 | | /** |
433 | | * Starts a new lookup in the background for entries that are in the grace |
434 | | * period with a failed connect or all cached entries are negative. |
435 | | */ |
436 | | nsresult ConditionallyRefreshRecord(nsHostRecord *rec, const nsACString &host); |
437 | | |
438 | | void AddToEvictionQ(nsHostRecord* rec); |
439 | | |
440 | | void ThreadFunc(); |
441 | | |
442 | | enum { |
443 | | METHOD_HIT = 1, |
444 | | METHOD_RENEWAL = 2, |
445 | | METHOD_NEGATIVE_HIT = 3, |
446 | | METHOD_LITERAL = 4, |
447 | | METHOD_OVERFLOW = 5, |
448 | | METHOD_NETWORK_FIRST = 6, |
449 | | METHOD_NETWORK_SHARED = 7 |
450 | | }; |
451 | | |
452 | | uint32_t mMaxCacheEntries; |
453 | | uint32_t mDefaultCacheLifetime; // granularity seconds |
454 | | uint32_t mDefaultGracePeriod; // granularity seconds |
455 | | mutable Mutex mLock; // mutable so SizeOfIncludingThis can be const |
456 | | CondVar mIdleTaskCV; |
457 | | nsRefPtrHashtable<nsGenericHashKey<nsHostKey>, nsHostRecord> mRecordDB; |
458 | | mozilla::LinkedList<RefPtr<nsHostRecord>> mHighQ; |
459 | | mozilla::LinkedList<RefPtr<nsHostRecord>> mMediumQ; |
460 | | mozilla::LinkedList<RefPtr<nsHostRecord>> mLowQ; |
461 | | mozilla::LinkedList<RefPtr<nsHostRecord>> mEvictionQ; |
462 | | uint32_t mEvictionQSize; |
463 | | PRTime mCreationTime; |
464 | | mozilla::TimeDuration mLongIdleTimeout; |
465 | | mozilla::TimeDuration mShortIdleTimeout; |
466 | | |
467 | | RefPtr<nsIThreadPool> mResolverThreads; |
468 | | |
469 | | mozilla::Atomic<bool> mShutdown; |
470 | | mozilla::Atomic<uint32_t> mNumIdleTasks; |
471 | | mozilla::Atomic<uint32_t> mActiveTaskCount; |
472 | | mozilla::Atomic<uint32_t> mActiveAnyThreadCount; |
473 | | mozilla::Atomic<uint32_t> mPendingCount; |
474 | | |
475 | | // Set the expiration time stamps appropriately. |
476 | | void PrepareRecordExpiration(nsHostRecord* rec) const; |
477 | | |
478 | | public: |
479 | | /* |
480 | | * Called by the networking dashboard via the DnsService2 |
481 | | */ |
482 | | void GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries> *); |
483 | | }; |
484 | | |
485 | | #endif // nsHostResolver_h__ |