@@ -134,6 +134,7 @@ public class DnsNameResolver extends InetNameResolver {
134134 * Cache for {@link #doResolve(String, Promise)} and {@link #doResolveAll(String, Promise)}.
135135 */
136136private final DnsCache resolveCache ;
137+ private final DnsCache authoritativeDnsServerCache ;
137138
138139private final FastThreadLocal <DnsServerAddressStream >nameServerAddrStream =
139140new FastThreadLocal <DnsServerAddressStream >() {
@@ -153,8 +154,8 @@ protected DnsServerAddressStream initialValue() throws Exception {
153154private final HostsFileEntriesResolver hostsFileEntriesResolver ;
154155private final String []searchDomains ;
155156private final int ndots ;
156- private final boolean cnameFollowARecords ;
157- private final boolean cnameFollowAAAARecords ;
157+ private final boolean supportsAAAARecords ;
158+ private final boolean supportsARecords ;
158159private final InternetProtocolFamily2 preferredAddressType ;
159160private final DnsRecordType []resolveRecordTypes ;
160161private final boolean decodeIdn ;
@@ -178,9 +179,9 @@ protected DnsServerAddressStream initialValue() throws Exception {
178179 * @param hostsFileEntriesResolver the {@link HostsFileEntriesResolver} used to check for local aliases
179180 * @param searchDomains the list of search domain
180181 * @param ndots the ndots value
181- * @deprecated use {@link #DnsNameResolver(EventLoop, ChannelFactory, DnsServerAddresses, DnsCache, long ,
182- * InternetProtocolFamily2[], boolean, int, boolean, int,
183- *boolean, HostsFileEntriesResolver, String[], int, boolean)}
182+ * @deprecated use {@linkDnsNameResolver #DnsNameResolver(EventLoop, ChannelFactory, DnsServerAddresses, DnsCache,
183+ * DnsCache, long, InternetProtocolFamily2[], boolean, int, boolean, int, boolean ,
184+ * HostsFileEntriesResolver, String[], int, boolean)}
184185 */
185186@ Deprecated
186187public DnsNameResolver (
@@ -198,11 +199,10 @@ public DnsNameResolver(
198199HostsFileEntriesResolver hostsFileEntriesResolver ,
199200String []searchDomains ,
200201int ndots ) {
201- this (eventLoop ,channelFactory ,nameServerAddresses ,resolveCache ,queryTimeoutMillis , resolvedAddressTypes ,
202- recursionDesired ,maxQueriesPerResolve ,traceEnabled ,maxPayloadSize , optResourceEnabled ,
203- hostsFileEntriesResolver ,searchDomains ,ndots ,true );
202+ this (eventLoop ,channelFactory ,nameServerAddresses ,resolveCache ,NoopDnsCache . INSTANCE , queryTimeoutMillis ,
203+ resolvedAddressTypes , recursionDesired ,maxQueriesPerResolve ,traceEnabled ,maxPayloadSize ,
204+ optResourceEnabled , hostsFileEntriesResolver ,searchDomains ,ndots ,true );
204205 }
205-
206206/**
207207 * Creates a new DNS-based name resolver that communicates with the specified list of DNS servers.
208208 *
@@ -212,6 +212,7 @@ public DnsNameResolver(
212212 * this to determine which DNS server should be contacted for the next retry in case
213213 * of failure.
214214 * @param resolveCache the DNS resolved entries cache
215+ * @param authoritativeDnsServerCache the cache used to find the authoritative DNS server for a domain
215216 * @param queryTimeoutMillis timeout of each DNS query in millis
216217 * @param resolvedAddressTypes list of the protocol families
217218 * @param recursionDesired if recursion desired flag must be set
@@ -230,6 +231,7 @@ public DnsNameResolver(
230231ChannelFactory <?extends DatagramChannel >channelFactory ,
231232DnsServerAddresses nameServerAddresses ,
232233final DnsCache resolveCache ,
234+ DnsCache authoritativeDnsServerCache ,
233235long queryTimeoutMillis ,
234236InternetProtocolFamily2 []resolvedAddressTypes ,
235237boolean recursionDesired ,
@@ -241,7 +243,6 @@ public DnsNameResolver(
241243String []searchDomains ,
242244int ndots ,
243245boolean decodeIdn ) {
244-
245246super (eventLoop );
246247checkNotNull (channelFactory ,"channelFactory" );
247248this .nameServerAddresses =checkNotNull (nameServerAddresses ,"nameServerAddresses" );
@@ -254,22 +255,23 @@ public DnsNameResolver(
254255this .optResourceEnabled =optResourceEnabled ;
255256this .hostsFileEntriesResolver =checkNotNull (hostsFileEntriesResolver ,"hostsFileEntriesResolver" );
256257this .resolveCache =checkNotNull (resolveCache ,"resolveCache" );
258+ this .authoritativeDnsServerCache =checkNotNull (authoritativeDnsServerCache ,"authoritativeDnsServerCache" );
257259this .searchDomains =checkNotNull (searchDomains ,"searchDomains" ).clone ();
258260this .ndots =checkPositiveOrZero (ndots ,"ndots" );
259261this .decodeIdn =decodeIdn ;
260262
261- boolean cnameFollowARecords =false ;
262- boolean cnameFollowAAAARecords =false ;
263+ boolean supportsARecords =false ;
264+ boolean supportsAAAARecords =false ;
263265// Use LinkedHashSet to maintain correct ordering.
264266Set <DnsRecordType >recordTypes =new LinkedHashSet <DnsRecordType >(resolvedAddressTypes .length );
265267for (InternetProtocolFamily2 family :resolvedAddressTypes ) {
266268switch (family ) {
267269case IPv4 :
268- cnameFollowARecords =true ;
270+ supportsARecords =true ;
269271recordTypes .add (DnsRecordType .A );
270272break ;
271273case IPv6 :
272- cnameFollowAAAARecords =true ;
274+ supportsAAAARecords =true ;
273275recordTypes .add (DnsRecordType .AAAA );
274276break ;
275277default :
@@ -278,9 +280,9 @@ public DnsNameResolver(
278280 }
279281
280282// One of both must be always true.
281- assert cnameFollowARecords ||cnameFollowAAAARecords ;
282- this .cnameFollowAAAARecords =cnameFollowAAAARecords ;
283- this .cnameFollowARecords =cnameFollowARecords ;
283+ assert supportsARecords ||supportsAAAARecords ;
284+ this .supportsAAAARecords =supportsAAAARecords ;
285+ this .supportsARecords =supportsARecords ;
284286resolveRecordTypes =recordTypes .toArray (new DnsRecordType [recordTypes .size ()]);
285287preferredAddressType =resolvedAddressTypes [0 ];
286288
@@ -308,13 +310,25 @@ public void operationComplete(ChannelFuture future) throws Exception {
308310 });
309311 }
310312
313+ // Only here to override in unit tests.
314+ int dnsRedirectPort (@ SuppressWarnings ("unused" )InetAddress server ) {
315+ return DnsServerAddresses .DNS_PORT ;
316+ }
317+
311318/**
312319 * Returns the resolution cache.
313320 */
314321public DnsCache resolveCache () {
315322return resolveCache ;
316323 }
317324
325+ /**
326+ * Returns the cache used for authoritative DNS servers for a domain.
327+ */
328+ public DnsCache authoritativeDnsServerCache () {
329+ return authoritativeDnsServerCache ;
330+ }
331+
318332/**
319333 * Returns the timeout of each DNS query performed by this resolver (in milliseconds).
320334 * The default value is 5 seconds.
@@ -344,12 +358,12 @@ final int ndots() {
344358return ndots ;
345359 }
346360
347- final boolean isCnameFollowAAAARecords () {
348- return cnameFollowAAAARecords ;
361+ final boolean supportsAAAARecords () {
362+ return supportsAAAARecords ;
349363 }
350364
351- final boolean isCnameFollowARecords () {
352- return cnameFollowARecords ;
365+ final boolean supportsARecords () {
366+ return supportsARecords ;
353367 }
354368
355369final InternetProtocolFamily2 preferredAddressType () {