Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DnsNameResolver hangs if search domain results in invalid hostname #8180

Merged
merged 1 commit into from Aug 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -749,7 +749,7 @@ private void followCname(DnsQuestion question, String cname, DnsQueryLifecycleOb

final DnsQuestion cnameQuestion;
try {
cnameQuestion = newQuestion(cname, question.type());
cnameQuestion = new DefaultDnsQuestion(cname, question.type(), dnsClass);
} catch (Throwable cause) {
queryLifecycleObserver.queryFailed(cause);
PlatformDependent.throwException(cause);
Expand All @@ -760,23 +760,20 @@ private void followCname(DnsQuestion question, String cname, DnsQueryLifecycleOb

private boolean query(String hostname, DnsRecordType type, DnsServerAddressStream dnsServerAddressStream,
Promise<List<T>> promise) {
final DnsQuestion question = newQuestion(hostname, type);
if (question == null) {
final DnsQuestion question;
try {
question = new DefaultDnsQuestion(hostname, type, dnsClass);
} catch (Throwable cause) {
// Assume a single failure means that queries will succeed. If the hostname is invalid for one type
// there is no case where it is known to be valid for another type.
promise.tryFailure(new IllegalArgumentException("Unable to create DNS Question for: [" + hostname + ", " +
type + "]", cause));
return false;
}
query(dnsServerAddressStream, 0, question, promise, null);
return true;
}

private DnsQuestion newQuestion(String hostname, DnsRecordType type) {
try {
return new DefaultDnsQuestion(hostname, type, dnsClass);
} catch (IllegalArgumentException e) {
// java.net.IDN.toASCII(...) may throw an IllegalArgumentException if it fails to parse the hostname
return null;
}
}

/**
* Holds the closed DNS Servers for a domain.
*/
Expand Down
Expand Up @@ -58,7 +58,9 @@
import org.hamcrest.Matchers;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.io.IOException;
import java.net.InetAddress;
Expand Down Expand Up @@ -88,6 +90,7 @@
import static io.netty.handler.codec.dns.DnsRecordType.CNAME;
import static io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.DNS_PORT;
import static io.netty.resolver.dns.DnsServerAddresses.sequential;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
Expand Down Expand Up @@ -298,6 +301,9 @@ public class DnsNameResolverTest {
private static final TestDnsServer dnsServer = new TestDnsServer(DOMAINS_ALL);
private static final EventLoopGroup group = new NioEventLoopGroup(1);

@Rule
public ExpectedException expectedException = ExpectedException.none();

private static DnsNameResolverBuilder newResolver(boolean decodeToUnicode) {
return newResolver(decodeToUnicode, null);
}
Expand Down Expand Up @@ -1682,4 +1688,28 @@ public Set<ResourceRecord> getRecords(QuestionRecord question) {
}
}
}

@Test
public void testSearchDomainQueryFailureForSingleAddressTypeCompletes() {
expectedException.expect(UnknownHostException.class);
testSearchDomainQueryFailureCompletes(ResolvedAddressTypes.IPV4_ONLY);
}

@Test
public void testSearchDomainQueryFailureForMultipleAddressTypeCompletes() {
expectedException.expect(UnknownHostException.class);
testSearchDomainQueryFailureCompletes(ResolvedAddressTypes.IPV4_PREFERRED);
}

private void testSearchDomainQueryFailureCompletes(ResolvedAddressTypes types) {
DnsNameResolver resolver = newResolver()
.resolvedAddressTypes(types)
.ndots(1)
.searchDomains(singletonList(".")).build();
try {
resolver.resolve("invalid.com").syncUninterruptibly();
} finally {
resolver.close();
}
}
}