Use ResolvedAddressTypes.IPV4_ONLY in DnsNameResolver by default if n… (#9048)

Motivation:

To closely mimic what the JDK does we should not try to resolve AAAA records if the system itself does not support IPv6 at all as it is impossible to connect to this addresses later on. In this case we need to use ResolvedAddressTypes.IPV4_ONLY.

Modifications:

Add static method to detect if IPv6 is supported and if not use ResolvedAddressTypes.IPV4_ONLY.

Result:

More consistent behaviour between JDK and our resolver implementation.
This commit is contained in:
Norman Maurer 2019-04-15 13:07:05 +02:00 committed by GitHub
parent 26cd59c328
commit dde3f561bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -65,10 +65,13 @@ import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -109,7 +112,7 @@ public class DnsNameResolver extends InetNameResolver {
private static final int DEFAULT_NDOTS; private static final int DEFAULT_NDOTS;
static { static {
if (NetUtil.isIpV4StackPreferred()) { if (NetUtil.isIpV4StackPreferred() || !anyInterfaceSupportsIpV6()) {
DEFAULT_RESOLVE_ADDRESS_TYPES = ResolvedAddressTypes.IPV4_ONLY; DEFAULT_RESOLVE_ADDRESS_TYPES = ResolvedAddressTypes.IPV4_ONLY;
LOCALHOST_ADDRESS = NetUtil.LOCALHOST4; LOCALHOST_ADDRESS = NetUtil.LOCALHOST4;
} else { } else {
@ -145,6 +148,28 @@ public class DnsNameResolver extends InetNameResolver {
DEFAULT_NDOTS = ndots; DEFAULT_NDOTS = ndots;
} }
/**
* Returns {@code true} if any {@link NetworkInterface} supports {@code IPv6}, {@code false} otherwise.
*/
private static boolean anyInterfaceSupportsIpV6() {
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
Enumeration<InetAddress> addresses = iface.getInetAddresses();
while (addresses.hasMoreElements()) {
if (addresses.nextElement() instanceof Inet6Address) {
return true;
}
}
}
} catch (SocketException e) {
logger.debug("Unable to detect if any interface supports IPv6, assuming IPv4-only", e);
// ignore
}
return false;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static List<String> getSearchDomainsHack() throws Exception { private static List<String> getSearchDomainsHack() throws Exception {
// This code on Java 9+ yields a warning about illegal reflective access that will be denied in // This code on Java 9+ yields a warning about illegal reflective access that will be denied in