From d34212439068091bcec29a8fad4df82f0a82c638 Mon Sep 17 00:00:00 2001 From: Violeta Georgieva Date: Tue, 20 Apr 2021 09:18:32 +0300 Subject: [PATCH] Ensure DnsNameResolver resolves the host(computer) name on Windows (#11167) Motivation: On Windows DnsNameResolver is not able to resolve the host(computer) name as it is not in the hosts file and the DNS server is also not able to resolve it. The exception below is the result of the resolution: Caused by: java.net.UnknownHostException: failed to resolve 'host(computer)-name' after 2 queries at io.netty.resolver.dns.DnsResolveContext.finishResolve(DnsResolveContext.java:1013) at io.netty.resolver.dns.DnsResolveContext.tryToFinishResolve(DnsResolveContext.java:966) at io.netty.resolver.dns.DnsResolveContext.query(DnsResolveContext.java:414) at io.netty.resolver.dns.DnsResolveContext.tryToFinishResolve(DnsResolveContext.java:938) at io.netty.resolver.dns.DnsResolveContext.access$700(DnsResolveContext.java:63) at io.netty.resolver.dns.DnsResolveContext$2.operationComplete(DnsResolveContext.java:467) Modifications: On Windows DnsNameResolver maps host(computer) name to LOCALHOST Result: DnsNameResolver is able to resolve the host(computer) name on Windows Fixes #11142 --- .../netty/resolver/dns/DnsNameResolver.java | 15 +++- .../resolver/dns/DnsNameResolverTest.java | 70 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java index bf594db062..a3a514f203 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java @@ -91,6 +91,7 @@ public class DnsNameResolver extends InetNameResolver { private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsNameResolver.class); private static final String LOCALHOST = "localhost"; + private static final String WINDOWS_HOST_NAME; private static final InetAddress LOCALHOST_ADDRESS; private static final DnsRecord[] EMPTY_ADDITIONALS = new DnsRecord[0]; private static final DnsRecordType[] IPV4_ONLY_RESOLVED_RECORD_TYPES = @@ -127,6 +128,14 @@ public class DnsNameResolver extends InetNameResolver { LOCALHOST_ADDRESS = NetUtil.LOCALHOST4; } } + + String hostName; + try { + hostName = PlatformDependent.isWindows() ? InetAddress.getLocalHost().getHostName() : null; + } catch (Exception ignore) { + hostName = null; + } + WINDOWS_HOST_NAME = hostName; } static { @@ -686,10 +695,14 @@ public class DnsNameResolver extends InetNameResolver { return null; } else { InetAddress address = hostsFileEntriesResolver.address(hostname, resolvedAddressTypes); - if (address == null && PlatformDependent.isWindows() && LOCALHOST.equalsIgnoreCase(hostname)) { + if (address == null && PlatformDependent.isWindows() && + (LOCALHOST.equalsIgnoreCase(hostname) || + (WINDOWS_HOST_NAME != null && WINDOWS_HOST_NAME.equalsIgnoreCase(hostname)))) { // If we tried to resolve localhost we need workaround that windows removed localhost from its // hostfile in later versions. // See https://github.com/netty/netty/issues/5386 + // Need a workaround for resolving the host (computer) name in case it cannot be resolved from hostfile + // See https://github.com/netty/netty/issues/11142 return LOCALHOST_ADDRESS; } return address; diff --git a/resolver-dns/src/test/java/io/netty/resolver/dns/DnsNameResolverTest.java b/resolver-dns/src/test/java/io/netty/resolver/dns/DnsNameResolverTest.java index 3ba8f7aeca..bd16d47ba1 100644 --- a/resolver-dns/src/test/java/io/netty/resolver/dns/DnsNameResolverTest.java +++ b/resolver-dns/src/test/java/io/netty/resolver/dns/DnsNameResolverTest.java @@ -110,8 +110,10 @@ import static io.netty.handler.codec.dns.DnsRecordType.A; import static io.netty.handler.codec.dns.DnsRecordType.AAAA; import static io.netty.handler.codec.dns.DnsRecordType.CNAME; import static io.netty.handler.codec.dns.DnsRecordType.SRV; +import static io.netty.resolver.dns.DnsNameResolver.DEFAULT_RESOLVE_ADDRESS_TYPES; import static io.netty.resolver.dns.DnsServerAddresses.sequential; import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assumptions.assumeThat; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasSize; @@ -319,6 +321,18 @@ public class DnsNameResolverTest { StringUtil.EMPTY_STRING); } + private static final String HOST_NAME; + + static { + String hostName; + try { + hostName = PlatformDependent.isWindows() ? InetAddress.getLocalHost().getHostName() : null; + } catch (Exception ignore) { + hostName = null; + } + HOST_NAME = hostName; + } + private static final TestDnsServer dnsServer = new TestDnsServer(DOMAINS_ALL); private static final EventLoopGroup group = new NioEventLoopGroup(1); @@ -743,6 +757,34 @@ public class DnsNameResolverTest { testResolve0(ResolvedAddressTypes.IPV6_ONLY, NetUtil.LOCALHOST6, StringUtil.EMPTY_STRING); } + @Test + public void testResolveLocalhostIpv4() { + assumeThat(PlatformDependent.isWindows()).isTrue(); + assumeThat(DEFAULT_RESOLVE_ADDRESS_TYPES).isNotEqualTo(ResolvedAddressTypes.IPV6_PREFERRED); + testResolve0(ResolvedAddressTypes.IPV4_ONLY, NetUtil.LOCALHOST4, "localhost"); + } + + @Test + public void testResolveLocalhostIpv6() { + assumeThat(PlatformDependent.isWindows()).isTrue(); + assumeThat(DEFAULT_RESOLVE_ADDRESS_TYPES).isEqualTo(ResolvedAddressTypes.IPV6_PREFERRED); + testResolve0(ResolvedAddressTypes.IPV6_ONLY, NetUtil.LOCALHOST6, "localhost"); + } + + @Test + public void testResolveHostNameIpv4() { + assumeThat(PlatformDependent.isWindows()).isTrue(); + assumeThat(DEFAULT_RESOLVE_ADDRESS_TYPES).isNotEqualTo(ResolvedAddressTypes.IPV6_PREFERRED); + testResolve0(ResolvedAddressTypes.IPV4_ONLY, NetUtil.LOCALHOST4, HOST_NAME); + } + + @Test + public void testResolveHostNameIpv6() { + assumeThat(PlatformDependent.isWindows()).isTrue(); + assumeThat(DEFAULT_RESOLVE_ADDRESS_TYPES).isEqualTo(ResolvedAddressTypes.IPV6_PREFERRED); + testResolve0(ResolvedAddressTypes.IPV6_ONLY, NetUtil.LOCALHOST6, HOST_NAME); + } + @Test public void testResolveNullIpv4() { testResolve0(ResolvedAddressTypes.IPV4_ONLY, NetUtil.LOCALHOST4, null); @@ -776,6 +818,34 @@ public class DnsNameResolverTest { testResolveAll0(ResolvedAddressTypes.IPV6_ONLY, NetUtil.LOCALHOST6, StringUtil.EMPTY_STRING); } + @Test + public void testResolveAllLocalhostIpv4() { + assumeThat(PlatformDependent.isWindows()).isTrue(); + assumeThat(DEFAULT_RESOLVE_ADDRESS_TYPES).isNotEqualTo(ResolvedAddressTypes.IPV6_PREFERRED); + testResolveAll0(ResolvedAddressTypes.IPV4_ONLY, NetUtil.LOCALHOST4, "localhost"); + } + + @Test + public void testResolveAllLocalhostIpv6() { + assumeThat(PlatformDependent.isWindows()).isTrue(); + assumeThat(DEFAULT_RESOLVE_ADDRESS_TYPES).isEqualTo(ResolvedAddressTypes.IPV6_PREFERRED); + testResolveAll0(ResolvedAddressTypes.IPV6_ONLY, NetUtil.LOCALHOST6, "localhost"); + } + + @Test + public void testResolveAllHostNameIpv4() { + assumeThat(PlatformDependent.isWindows()).isTrue(); + assumeThat(DEFAULT_RESOLVE_ADDRESS_TYPES).isNotEqualTo(ResolvedAddressTypes.IPV6_PREFERRED); + testResolveAll0(ResolvedAddressTypes.IPV4_ONLY, NetUtil.LOCALHOST4, HOST_NAME); + } + + @Test + public void testResolveAllHostNameIpv6() { + assumeThat(PlatformDependent.isWindows()).isTrue(); + assumeThat(DEFAULT_RESOLVE_ADDRESS_TYPES).isEqualTo(ResolvedAddressTypes.IPV6_PREFERRED); + testResolveAll0(ResolvedAddressTypes.IPV6_ONLY, NetUtil.LOCALHOST6, HOST_NAME); + } + @Test public void testCNAMEResolveAllIpv4() throws IOException { testCNAMERecursiveResolve(true);