Skip to content

Commit 6b4f75d

Browse files
committed
Respect resolvedAddressTypes when follow CNAME records, close AsyncHttpClient#1327
Motivation: When we follow CNAME records we should respect resolvedAddressTypes and only query A / AAAA depending on which address types are expected. Modifications: Check if we should query A / AAAA when follow CNAMEs depending on resolvedAddressTypes. Result: Correct behaviour when follow CNAMEs.
1 parent a0cbc31 commit 6b4f75d

File tree

2 files changed

+59
-16
lines changed

2 files changed

+59
-16
lines changed

netty-bp/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import io.netty.handler.codec.dns.DnsRecord;
3636
import io.netty.handler.codec.dns.DatagramDnsResponseDecoder;
3737
import io.netty.handler.codec.dns.DnsQuestion;
38+
import io.netty.handler.codec.dns.DnsRecordType;
3839
import io.netty.handler.codec.dns.DnsResponse;
3940
import io.netty.resolver.HostsFileEntriesResolver;
4041
import io.netty.resolver.InetNameResolver;
@@ -59,7 +60,9 @@
5960
import java.util.Collection;
6061
import java.util.Collections;
6162
import java.util.Iterator;
63+
import java.util.LinkedHashSet;
6264
import java.util.List;
65+
import java.util.Set;
6366

6467
import static io.netty.util.internal.ObjectUtil2.*;
6568

@@ -148,6 +151,10 @@ protected DnsServerAddressStream initialValue() throws Exception {
148151
private final HostsFileEntriesResolver hostsFileEntriesResolver;
149152
private final String[] searchDomains;
150153
private final int ndots;
154+
private final boolean cnameFollowARecords;
155+
private final boolean cnameFollowAAAARecords;
156+
private final InternetProtocolFamily2 preferredAddressType;
157+
private final DnsRecordType[] resolveRecordTypes;
151158

152159
/**
153160
* Creates a new DNS-based name resolver that communicates with the specified list of DNS servers.
@@ -200,6 +207,32 @@ public DnsNameResolver(
200207
this.searchDomains = checkNotNull(searchDomains, "searchDomains").clone();
201208
this.ndots = checkPositiveOrZero(ndots, "ndots");
202209

210+
boolean cnameFollowARecords = false;
211+
boolean cnameFollowAAAARecords = false;
212+
// Use LinkedHashSet to maintain correct ordering.
213+
Set<DnsRecordType> recordTypes = new LinkedHashSet<DnsRecordType>(resolvedAddressTypes.length);
214+
for (InternetProtocolFamily2 family: resolvedAddressTypes) {
215+
switch (family) {
216+
case IPv4:
217+
cnameFollowARecords = true;
218+
recordTypes.add(DnsRecordType.A);
219+
break;
220+
case IPv6:
221+
cnameFollowAAAARecords = true;
222+
recordTypes.add(DnsRecordType.AAAA);
223+
break;
224+
default:
225+
throw new Error();
226+
}
227+
}
228+
229+
// One of both must be always true.
230+
assert cnameFollowARecords || cnameFollowAAAARecords;
231+
this.cnameFollowAAAARecords = cnameFollowAAAARecords;
232+
this.cnameFollowARecords = cnameFollowARecords;
233+
resolveRecordTypes = recordTypes.toArray(new DnsRecordType[recordTypes.size()]);
234+
preferredAddressType = resolvedAddressTypes[0];
235+
203236
Bootstrap b = new Bootstrap();
204237
b.group(executor());
205238
b.channelFactory(channelFactory);
@@ -260,6 +293,22 @@ final int ndots() {
260293
return ndots;
261294
}
262295

296+
final boolean isCnameFollowAAAARecords() {
297+
return cnameFollowAAAARecords;
298+
}
299+
300+
final boolean isCnameFollowARecords() {
301+
return cnameFollowARecords;
302+
}
303+
304+
final InternetProtocolFamily2 preferredAddressType() {
305+
return preferredAddressType;
306+
}
307+
308+
final DnsRecordType[] resolveRecordTypes() {
309+
return resolveRecordTypes;
310+
}
311+
263312
/**
264313
* Returns {@code true} if and only if this resolver sends a DNS query with the RD (recursion desired) flag set.
265314
* The default value is {@code true}.

netty-bp/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolverContext.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -146,19 +146,7 @@ public void operationComplete(Future<T> future) throws Exception {
146146

147147
private void internalResolve(Promise<T> promise) {
148148
InetSocketAddress nameServerAddrToTry = nameServerAddrs.next();
149-
for (InternetProtocolFamily2 f: resolveAddressTypes) {
150-
final DnsRecordType type;
151-
switch (f) {
152-
case IPv4:
153-
type = DnsRecordType.A;
154-
break;
155-
case IPv6:
156-
type = DnsRecordType.AAAA;
157-
break;
158-
default:
159-
throw new Error();
160-
}
161-
149+
for (DnsRecordType type: parent.resolveRecordTypes()) {
162150
query(nameServerAddrToTry, new DefaultDnsQuestion(hostname, type), promise);
163151
}
164152
}
@@ -410,7 +398,7 @@ private boolean gotPreferredAddress() {
410398
}
411399

412400
final int size = resolvedEntries.size();
413-
switch (resolveAddressTypes[0]) {
401+
switch (parent.preferredAddressType()) {
414402
case IPv4:
415403
for (int i = 0; i < size; i ++) {
416404
if (resolvedEntries.get(i).address() instanceof Inet4Address) {
@@ -425,6 +413,8 @@ private boolean gotPreferredAddress() {
425413
}
426414
}
427415
break;
416+
default:
417+
throw new Error();
428418
}
429419

430420
return false;
@@ -520,8 +510,12 @@ private void followCname(InetSocketAddress nameServerAddr, String name, String c
520510
}
521511

522512
final InetSocketAddress nextAddr = nameServerAddrs.next();
523-
query(nextAddr, new DefaultDnsQuestion(cname, DnsRecordType.A), promise);
524-
query(nextAddr, new DefaultDnsQuestion(cname, DnsRecordType.AAAA), promise);
513+
if (parent.isCnameFollowARecords()) {
514+
query(nextAddr, new DefaultDnsQuestion(cname, DnsRecordType.A), promise);
515+
}
516+
if (parent.isCnameFollowAAAARecords()) {
517+
query(nextAddr, new DefaultDnsQuestion(cname, DnsRecordType.AAAA), promise);
518+
}
525519
}
526520

527521
private void addTrace(InetSocketAddress nameServerAddr, String msg) {

0 commit comments

Comments
 (0)