Only handle NXDOMAIN as failure when nameserver is authoritive or no other nameservers are left. (#8731)

Motivation:

When using multiple nameservers and a nameserver respond with NXDOMAIN we should only fail the query if the nameserver in question is authoritive or no nameservers are left to try.

Modifications:

- Try next nameserver if NXDOMAIN was returned but the nameserver is not authoritive
- Adjust testcase to respect correct behaviour.

Result:

Fixes https://github.com/netty/netty/issues/8261
This commit is contained in:
Norman Maurer 2019-01-18 21:06:44 +01:00 committed by GitHub
parent e4b9d5f9a1
commit df5eb060f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 8 deletions

View File

@ -497,6 +497,29 @@ abstract class DnsResolveContext<T> {
queryLifecycleObserver.queryNoAnswer(code), true, promise, null);
} else {
queryLifecycleObserver.queryFailed(NXDOMAIN_QUERY_FAILED_EXCEPTION);
// Try with the next server if is not authoritative for the domain.
//
// From https://tools.ietf.org/html/rfc1035 :
//
// RCODE Response code - this 4 bit field is set as part of
// responses. The values have the following
// interpretation:
//
// ....
// ....
//
// 3 Name Error - Meaningful only for
// responses from an authoritative name
// server, this code signifies that the
// domain name referenced in the query does
// not exist.
// ....
// ....
if (!res.isAuthoritativeAnswer()) {
query(nameServerAddrStream, nameServerAddrStreamIndex + 1, question,
newDnsQueryLifecycleObserver(question), true, promise, null);
}
}
} finally {
ReferenceCountUtil.safeRelease(envelope);

View File

@ -1143,7 +1143,7 @@ public class DnsNameResolverTest {
new TestRecursiveCacheDnsQueryLifecycleObserverFactory();
DnsNameResolverBuilder builder = new DnsNameResolverBuilder(group.next())
.resolvedAddressTypes(ResolvedAddressTypes.IPV6_PREFERRED)
.resolvedAddressTypes(ResolvedAddressTypes.IPV4_ONLY)
.dnsQueryLifecycleObserverFactory(lifecycleObserverFactory)
.channelType(NioDatagramChannel.class)
.optResourceEnabled(false)
@ -1156,18 +1156,12 @@ public class DnsNameResolverTest {
TestDnsQueryLifecycleObserver observer = lifecycleObserverFactory.observers.poll();
assertNotNull(observer);
assertEquals(2, lifecycleObserverFactory.observers.size());
assertEquals(1, lifecycleObserverFactory.observers.size());
assertEquals(2, observer.events.size());
QueryWrittenEvent writtenEvent = (QueryWrittenEvent) observer.events.poll();
assertEquals(dnsServer1.localAddress(), writtenEvent.dnsServerAddress);
QueryFailedEvent failedEvent = (QueryFailedEvent) observer.events.poll();
observer = lifecycleObserverFactory.observers.poll();
assertEquals(2, observer.events.size());
writtenEvent = (QueryWrittenEvent) observer.events.poll();
assertEquals(dnsServer1.localAddress(), writtenEvent.dnsServerAddress);
failedEvent = (QueryFailedEvent) observer.events.poll();
observer = lifecycleObserverFactory.observers.poll();
assertEquals(2, observer.events.size());
writtenEvent = (QueryWrittenEvent) observer.events.poll();