DnsResolver CNAME redirect bug
Motviation: DnsNameResolverContext#followCname attempts to build a query to follow a CNAME, but puts the original hostname in the DnsQuery instead of the CNAME hostname. This will result in not following CNAME redirects correctly. Result: - DnsNameResolverContext#followCname should use the CNAME instead of the original hostname when building the DnsQuery Result: More correct handling of redirect queries.
This commit is contained in:
parent
dc98eae5a5
commit
dcb828f02f
@ -735,7 +735,7 @@ abstract class DnsNameResolverContext<T> {
|
||||
DnsQuestion cnameQuestion = null;
|
||||
if (parent.supportsARecords()) {
|
||||
try {
|
||||
if ((cnameQuestion = newQuestion(hostname, DnsRecordType.A)) == null) {
|
||||
if ((cnameQuestion = newQuestion(cname, DnsRecordType.A)) == null) {
|
||||
return;
|
||||
}
|
||||
} catch (Throwable cause) {
|
||||
@ -746,7 +746,7 @@ abstract class DnsNameResolverContext<T> {
|
||||
}
|
||||
if (parent.supportsAAAARecords()) {
|
||||
try {
|
||||
if ((cnameQuestion = newQuestion(hostname, DnsRecordType.AAAA)) == null) {
|
||||
if ((cnameQuestion = newQuestion(cname, DnsRecordType.AAAA)) == null) {
|
||||
return;
|
||||
}
|
||||
} catch (Throwable cause) {
|
||||
|
@ -425,7 +425,7 @@ public class DnsNameResolverTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveA() throws Exception {
|
||||
public void testResolveA() throws Exception {
|
||||
DnsNameResolver resolver = newResolver(ResolvedAddressTypes.IPV4_ONLY)
|
||||
// Cache for eternity
|
||||
.ttl(Integer.MAX_VALUE, Integer.MAX_VALUE)
|
||||
@ -741,6 +741,81 @@ public class DnsNameResolverTest {
|
||||
testResolveAll0(ResolvedAddressTypes.IPV6_ONLY, NetUtil.LOCALHOST6, StringUtil.EMPTY_STRING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCNAMEResolveAllIpv4() throws IOException, InterruptedException {
|
||||
testCNAMERecursiveResolve(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCNAMEResolveAllIpv6() throws IOException, InterruptedException {
|
||||
testCNAMERecursiveResolve(false);
|
||||
}
|
||||
|
||||
private static void testCNAMERecursiveResolve(boolean ipv4Preferred) throws IOException, InterruptedException {
|
||||
final String firstName = "firstname.com";
|
||||
final String secondName = "secondname.com";
|
||||
final String lastName = "lastname.com";
|
||||
final String ipv4Addr = "1.2.3.4";
|
||||
final String ipv6Addr = "::1";
|
||||
TestDnsServer dnsServer2 = new TestDnsServer(new RecordStore() {
|
||||
@Override
|
||||
public Set<ResourceRecord> getRecords(QuestionRecord question) throws DnsException {
|
||||
ResourceRecordModifier rm = new ResourceRecordModifier();
|
||||
rm.setDnsClass(RecordClass.IN);
|
||||
rm.setDnsName(question.getDomainName());
|
||||
rm.setDnsTtl(100);
|
||||
rm.setDnsType(RecordType.CNAME);
|
||||
|
||||
if (question.getDomainName().equals(firstName)) {
|
||||
rm.put(DnsAttribute.DOMAIN_NAME, secondName);
|
||||
} else if (question.getDomainName().equals(secondName)) {
|
||||
rm.put(DnsAttribute.DOMAIN_NAME, lastName);
|
||||
} else if (question.getDomainName().equals(lastName)) {
|
||||
rm.setDnsType(question.getRecordType());
|
||||
switch (question.getRecordType()) {
|
||||
case A:
|
||||
rm.put(DnsAttribute.IP_ADDRESS, ipv4Addr);
|
||||
break;
|
||||
case AAAA:
|
||||
rm.put(DnsAttribute.IP_ADDRESS, ipv6Addr);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return Collections.singleton(rm.getEntry());
|
||||
}
|
||||
});
|
||||
dnsServer2.start();
|
||||
DnsNameResolver resolver = null;
|
||||
try {
|
||||
DnsNameResolverBuilder builder = newResolver()
|
||||
.recursionDesired(true)
|
||||
.maxQueriesPerResolve(16)
|
||||
.nameServerProvider(new SingletonDnsServerAddressStreamProvider(dnsServer2.localAddress()));
|
||||
if (ipv4Preferred) {
|
||||
builder.resolvedAddressTypes(ResolvedAddressTypes.IPV4_PREFERRED);
|
||||
} else {
|
||||
builder.resolvedAddressTypes(ResolvedAddressTypes.IPV6_PREFERRED);
|
||||
}
|
||||
resolver = builder.build();
|
||||
InetAddress resolvedAddress = resolver.resolve(firstName).syncUninterruptibly().getNow();
|
||||
if (ipv4Preferred) {
|
||||
assertEquals(ipv4Addr, resolvedAddress.getHostAddress());
|
||||
} else {
|
||||
assertEquals(ipv6Addr, NetUtil.toAddressString(resolvedAddress));
|
||||
}
|
||||
assertEquals(firstName, resolvedAddress.getHostName());
|
||||
} finally {
|
||||
dnsServer2.stop();
|
||||
if (resolver != null) {
|
||||
resolver.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveAllNullIpv4() {
|
||||
testResolveAll0(ResolvedAddressTypes.IPV4_ONLY, NetUtil.LOCALHOST4, null);
|
||||
|
Loading…
Reference in New Issue
Block a user