Use all configured nameservers when using DnsNameResolver in all cases (#10503)

Motivation:

Due a change introduced in 68105b257d we incorrectly skipped the usage of nameservers in some cases.

Modifications:

Only fetch a new stream of nameserver if the hostname not matches the original hostname in the query.

Result:

Use all configured nameservers. Fixes https://github.com/netty/netty/issues/10499
This commit is contained in:
Norman Maurer 2020-08-31 09:12:12 +02:00 committed by GitHub
parent bc344617b4
commit 6c1840749d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 5 deletions

View File

@ -1025,11 +1025,18 @@ abstract class DnsResolveContext<T> {
}
}
private DnsServerAddressStream getNameServers(String hostname) {
DnsServerAddressStream stream = getNameServersFromCache(hostname);
// We need to obtain a new stream from the parent DnsNameResolver as the hostname may not be the same as the
// one used for the original query (for example we may follow CNAMEs).
return stream == null ? parent.newNameServerAddressStream(hostname) : stream;
private DnsServerAddressStream getNameServers(String name) {
DnsServerAddressStream stream = getNameServersFromCache(name);
if (stream == null) {
// We need to obtain a new stream from the parent DnsNameResolver if the hostname is not the same as
// for the original query (for example we may follow CNAMEs). Otherwise let's just duplicate the
// original nameservers so we correctly update the internal index
if (name.equals(hostname)) {
return nameServerAddrs.duplicate();
}
return parent.newNameServerAddressStream(name);
}
return stream;
}
private void followCname(DnsQuestion question, String cname, DnsQueryLifecycleObserver queryLifecycleObserver,

View File

@ -3102,4 +3102,79 @@ public class DnsNameResolverTest {
assertEquals(ipAddr, resolvedAddress.getHostAddress());
assertEquals(hostname, resolvedAddress.getHostName());
}
@Test
public void testAllNameServers() throws IOException {
final String domain = "netty.io";
final String ipv4Addr = "1.2.3.4";
final AtomicInteger server2Counter = new AtomicInteger();
final TestDnsServer dnsServer2 = new TestDnsServer(new RecordStore() {
@Override
public Set<ResourceRecord> getRecords(QuestionRecord question) {
server2Counter.incrementAndGet();
ResourceRecordModifier rm = new ResourceRecordModifier();
rm.setDnsClass(RecordClass.IN);
rm.setDnsName(question.getDomainName());
rm.setDnsTtl(100);
rm.setDnsType(question.getRecordType());
rm.put(DnsAttribute.IP_ADDRESS, ipv4Addr);
return Collections.singleton(rm.getEntry());
}
});
dnsServer2.start();
final AtomicInteger server3Counter = new AtomicInteger();
final TestDnsServer dnsServer3 = new TestDnsServer(new RecordStore() {
@Override
public Set<ResourceRecord> getRecords(QuestionRecord question) {
server3Counter.incrementAndGet();
ResourceRecordModifier rm = new ResourceRecordModifier();
rm.setDnsClass(RecordClass.IN);
rm.setDnsName(question.getDomainName());
rm.setDnsTtl(100);
rm.setDnsType(question.getRecordType());
rm.put(DnsAttribute.IP_ADDRESS, ipv4Addr);
return Collections.singleton(rm.getEntry());
}
});
dnsServer3.start();
DnsNameResolver resolver = null;
try {
resolver = newResolver()
.resolveCache(NoopDnsCache.INSTANCE)
.cnameCache(NoopDnsCnameCache.INSTANCE)
.recursionDesired(true)
.maxQueriesPerResolve(16)
.nameServerProvider(new DnsServerAddressStreamProvider() {
private final DnsServerAddresses addresses =
DnsServerAddresses.rotational(dnsServer2.localAddress(), dnsServer3.localAddress());
@Override
public DnsServerAddressStream nameServerAddressStream(String hostname) {
return addresses.stream();
}
})
.resolvedAddressTypes(ResolvedAddressTypes.IPV4_ONLY).build();
assertResolvedAddress(resolver.resolve(domain).syncUninterruptibly().getNow(), ipv4Addr, domain);
assertEquals(1, server2Counter.get());
assertEquals(0, server3Counter.get());
assertResolvedAddress(resolver.resolve(domain).syncUninterruptibly().getNow(), ipv4Addr, domain);
assertEquals(1, server2Counter.get());
assertEquals(1, server3Counter.get());
assertResolvedAddress(resolver.resolve(domain).syncUninterruptibly().getNow(), ipv4Addr, domain);
assertEquals(2, server2Counter.get());
assertEquals(1, server3Counter.get());
assertResolvedAddress(resolver.resolve(domain).syncUninterruptibly().getNow(), ipv4Addr, domain);
assertEquals(2, server2Counter.get());
assertEquals(2, server3Counter.get());
} finally {
dnsServer2.stop();
dnsServer3.stop();
if (resolver != null) {
resolver.close();
}
}
}
}