Respect resolvedAddressTypes when follow CNAME records.
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.
This commit is contained in:
parent
71efb0b39e
commit
ead87b7df8
@ -35,6 +35,7 @@ import io.netty.handler.codec.dns.DnsRawRecord;
|
||||
import io.netty.handler.codec.dns.DnsRecord;
|
||||
import io.netty.handler.codec.dns.DatagramDnsResponseDecoder;
|
||||
import io.netty.handler.codec.dns.DnsQuestion;
|
||||
import io.netty.handler.codec.dns.DnsRecordType;
|
||||
import io.netty.handler.codec.dns.DnsResponse;
|
||||
import io.netty.resolver.HostsFileEntriesResolver;
|
||||
import io.netty.resolver.InetNameResolver;
|
||||
@ -59,7 +60,9 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static io.netty.util.internal.ObjectUtil.*;
|
||||
|
||||
@ -148,6 +151,10 @@ public class DnsNameResolver extends InetNameResolver {
|
||||
private final HostsFileEntriesResolver hostsFileEntriesResolver;
|
||||
private final String[] searchDomains;
|
||||
private final int ndots;
|
||||
private final boolean cnameFollowARecords;
|
||||
private final boolean cnameFollowAAAARecords;
|
||||
private final InternetProtocolFamily preferredAddressType;
|
||||
private final DnsRecordType[] resolveRecordTypes;
|
||||
|
||||
/**
|
||||
* Creates a new DNS-based name resolver that communicates with the specified list of DNS servers.
|
||||
@ -200,6 +207,32 @@ public class DnsNameResolver extends InetNameResolver {
|
||||
this.searchDomains = checkNotNull(searchDomains, "searchDomains").clone();
|
||||
this.ndots = checkPositiveOrZero(ndots, "ndots");
|
||||
|
||||
boolean cnameFollowARecords = false;
|
||||
boolean cnameFollowAAAARecords = false;
|
||||
// Use LinkedHashSet to maintain correct ordering.
|
||||
Set<DnsRecordType> recordTypes = new LinkedHashSet<DnsRecordType>(resolvedAddressTypes.length);
|
||||
for (InternetProtocolFamily family: resolvedAddressTypes) {
|
||||
switch (family) {
|
||||
case IPv4:
|
||||
cnameFollowARecords = true;
|
||||
recordTypes.add(DnsRecordType.A);
|
||||
break;
|
||||
case IPv6:
|
||||
cnameFollowAAAARecords = true;
|
||||
recordTypes.add(DnsRecordType.AAAA);
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
// One of both must be always true.
|
||||
assert cnameFollowARecords || cnameFollowAAAARecords;
|
||||
this.cnameFollowAAAARecords = cnameFollowAAAARecords;
|
||||
this.cnameFollowARecords = cnameFollowARecords;
|
||||
resolveRecordTypes = recordTypes.toArray(new DnsRecordType[recordTypes.size()]);
|
||||
preferredAddressType = resolvedAddressTypes[0];
|
||||
|
||||
Bootstrap b = new Bootstrap();
|
||||
b.group(executor());
|
||||
b.channelFactory(channelFactory);
|
||||
@ -260,6 +293,22 @@ public class DnsNameResolver extends InetNameResolver {
|
||||
return ndots;
|
||||
}
|
||||
|
||||
final boolean isCnameFollowAAAARecords() {
|
||||
return cnameFollowAAAARecords;
|
||||
}
|
||||
|
||||
final boolean isCnameFollowARecords() {
|
||||
return cnameFollowARecords;
|
||||
}
|
||||
|
||||
final InternetProtocolFamily preferredAddressType() {
|
||||
return preferredAddressType;
|
||||
}
|
||||
|
||||
final DnsRecordType[] resolveRecordTypes() {
|
||||
return resolveRecordTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if and only if this resolver sends a DNS query with the RD (recursion desired) flag set.
|
||||
* The default value is {@code true}.
|
||||
|
@ -145,19 +145,7 @@ abstract class DnsNameResolverContext<T> {
|
||||
|
||||
private void internalResolve(Promise<T> promise) {
|
||||
InetSocketAddress nameServerAddrToTry = nameServerAddrs.next();
|
||||
for (InternetProtocolFamily f: resolveAddressTypes) {
|
||||
final DnsRecordType type;
|
||||
switch (f) {
|
||||
case IPv4:
|
||||
type = DnsRecordType.A;
|
||||
break;
|
||||
case IPv6:
|
||||
type = DnsRecordType.AAAA;
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
for (DnsRecordType type: parent.resolveRecordTypes()) {
|
||||
query(nameServerAddrToTry, new DefaultDnsQuestion(hostname, type), promise);
|
||||
}
|
||||
}
|
||||
@ -409,7 +397,7 @@ abstract class DnsNameResolverContext<T> {
|
||||
}
|
||||
|
||||
final int size = resolvedEntries.size();
|
||||
switch (resolveAddressTypes[0]) {
|
||||
switch (parent.preferredAddressType()) {
|
||||
case IPv4:
|
||||
for (int i = 0; i < size; i ++) {
|
||||
if (resolvedEntries.get(i).address() instanceof Inet4Address) {
|
||||
@ -424,6 +412,8 @@ abstract class DnsNameResolverContext<T> {
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -519,8 +509,12 @@ abstract class DnsNameResolverContext<T> {
|
||||
}
|
||||
|
||||
final InetSocketAddress nextAddr = nameServerAddrs.next();
|
||||
query(nextAddr, new DefaultDnsQuestion(cname, DnsRecordType.A), promise);
|
||||
query(nextAddr, new DefaultDnsQuestion(cname, DnsRecordType.AAAA), promise);
|
||||
if (parent.isCnameFollowARecords()) {
|
||||
query(nextAddr, new DefaultDnsQuestion(cname, DnsRecordType.A), promise);
|
||||
}
|
||||
if (parent.isCnameFollowAAAARecords()) {
|
||||
query(nextAddr, new DefaultDnsQuestion(cname, DnsRecordType.AAAA), promise);
|
||||
}
|
||||
}
|
||||
|
||||
private void addTrace(InetSocketAddress nameServerAddr, String msg) {
|
||||
|
Loading…
Reference in New Issue
Block a user