8244958: preferIPv4Stack and preferIPv6Addresses do not affect addresses returned by HostsFileNameService

Reviewed-by: dfuchs, alanb, vtewari
This commit is contained in:
Aleksei Efimov 2020-05-29 13:39:16 +01:00
parent b43f356288
commit 02fbf44cc7
2 changed files with 226 additions and 33 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,11 +25,11 @@
package java.net;
import java.util.List;
import java.util.NavigableSet;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Scanner;
import java.security.AccessController;
import java.io.File;
import java.io.ObjectStreamException;
import java.io.ObjectStreamField;
@ -954,29 +954,18 @@ public class InetAddress implements java.io.Serializable {
*/
private static final class HostsFileNameService implements NameService {
private static final InetAddress[] EMPTY_ARRAY = new InetAddress[0];
// Specify if only IPv4 addresses should be returned by HostsFileService implementation
private static final boolean preferIPv4Stack = Boolean.parseBoolean(
GetPropertyAction.privilegedGetProperty("java.net.preferIPv4Stack"));
private final String hostsFile;
public HostsFileNameService (String hostsFileName) {
public HostsFileNameService(String hostsFileName) {
this.hostsFile = hostsFileName;
}
private String addrToString(byte addr[]) {
String stringifiedAddress = null;
if (addr.length == Inet4Address.INADDRSZ) {
stringifiedAddress = Inet4Address.numericToTextFormat(addr);
} else { // treat as an IPV6 jobby
byte[] newAddr
= IPAddressUtil.convertFromIPv4MappedAddress(addr);
if (newAddr != null) {
stringifiedAddress = Inet4Address.numericToTextFormat(addr);
} else {
stringifiedAddress = Inet6Address.numericToTextFormat(addr);
}
}
return stringifiedAddress;
}
/**
* Lookup the host name corresponding to the IP address provided.
* Search the configured host file a host name corresponding to
@ -1037,15 +1026,15 @@ public class InetAddress implements java.io.Serializable {
public InetAddress[] lookupAllHostAddr(String host)
throws UnknownHostException {
String hostEntry;
String addrStr = null;
InetAddress[] res = null;
byte addr[] = new byte[4];
ArrayList<InetAddress> inetAddresses = null;
String addrStr;
byte addr[];
List<InetAddress> inetAddresses = new ArrayList<>();
List<InetAddress> inet4Addresses = new ArrayList<>();
List<InetAddress> inet6Addresses = new ArrayList<>();
// lookup the file and create a list InetAddress for the specified host
try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
UTF_8.INSTANCE))
{
UTF_8.INSTANCE)) {
while (hostsFileScanner.hasNextLine()) {
hostEntry = hostsFileScanner.nextLine();
if (!hostEntry.startsWith("#")) {
@ -1054,11 +1043,15 @@ public class InetAddress implements java.io.Serializable {
addrStr = extractHostAddr(hostEntry, host);
if ((addrStr != null) && (!addrStr.isEmpty())) {
addr = createAddressByteArray(addrStr);
if (inetAddresses == null) {
inetAddresses = new ArrayList<>(1);
}
if (addr != null) {
inetAddresses.add(InetAddress.getByAddress(host, addr));
InetAddress address = InetAddress.getByAddress(host, addr);
inetAddresses.add(address);
if (address instanceof Inet4Address) {
inet4Addresses.add(address);
}
if (address instanceof Inet6Address) {
inet6Addresses.add(address);
}
}
}
}
@ -1069,13 +1062,32 @@ public class InetAddress implements java.io.Serializable {
+ " as hosts file " + hostsFile + " not found ");
}
if (inetAddresses != null) {
res = inetAddresses.toArray(new InetAddress[inetAddresses.size()]);
List<InetAddress> res;
// If "preferIPv4Stack" system property is set to "true" then return
// only IPv4 addresses
if (preferIPv4Stack) {
res = inet4Addresses;
} else {
// Otherwise, analyse "preferIPv6Addresses" value
res = switch (preferIPv6Address) {
case PREFER_IPV4_VALUE -> concatAddresses(inet4Addresses, inet6Addresses);
case PREFER_IPV6_VALUE -> concatAddresses(inet6Addresses, inet4Addresses);
default -> inetAddresses;
};
}
if (res.isEmpty()) {
throw new UnknownHostException("Unable to resolve host " + host
+ " in hosts file " + hostsFile);
}
return res;
return res.toArray(EMPTY_ARRAY);
}
private static List<InetAddress> concatAddresses(List<InetAddress> firstPart,
List<InetAddress> secondPart) {
List<InetAddress> result = new ArrayList<>(firstPart);
result.addAll(secondPart);
return result;
}
private String removeComments(String hostsEntry) {