264
265 /**
266 * Specifies the address family type, for instance, '1' for IPv4
267 * addresses, and '2' for IPv6 addresses.
268 */
269 int family;
270
271 int getFamily() {
272 return family;
273 }
274 }
275
276 /* Used to store the serializable fields of InetAddress */
277 final transient InetAddressHolder holder;
278
279 InetAddressHolder holder() {
280 return holder;
281 }
282
283 /* Used to store the name service provider */
284 private static transient NameService nameService = null;
285
286 /* Used to store the best available hostname */
287 private transient String canonicalHostName = null;
288
289 /** use serialVersionUID from JDK 1.0.2 for interoperability */
290 private static final long serialVersionUID = 3286316764910316507L;
291
292 /*
293 * Load net library into runtime, and perform initializations.
294 */
295 static {
296 preferIPv6Address = java.security.AccessController.doPrivileged(
297 new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue();
298 AccessController.doPrivileged(
299 new java.security.PrivilegedAction<>() {
300 public Void run() {
301 System.loadLibrary("net");
302 return null;
303 }
304 });
841 // schedule expiry
842 expirySet.add(cachedAddresses);
843 }
844 }
845 if (inetAddresses == null) {
846 throw ex == null ? new UnknownHostException(host) : ex;
847 }
848 return inetAddresses;
849 }
850 // else addresses != this
851 }
852 // delegate to different addresses when we are already replaced
853 // but outside of synchronized block to avoid any chance of dead-locking
854 return addresses.get();
855 }
856 }
857
858 /**
859 * NameService provides host and address lookup service
860 *
861 */
862 private interface NameService {
863
864 /**
865 * Lookup a host mapping by name. Retrieve the IP addresses
866 * associated with a host
867 *
868 * @param host the specified hostname
869 * @return array of IP addresses for the requested host
870 * @throws UnknownHostException
871 * if no IP address for the {@code host} could be found
872 */
873 InetAddress[] lookupAllHostAddr(String host)
874 throws UnknownHostException;
875
876 /**
877 * Lookup the host corresponding to the IP address provided
878 *
879 * @param addr byte array representing an IP address
880 * @return {@code String} representing the host name mapping
881 * @throws UnknownHostException
882 * if no host found for the specified IP address
883 */
884 String getHostByAddr(byte[] addr) throws UnknownHostException;
885
886 }
887
888 /**
889 * The default NameService implementation, which delegates to the underlying
890 * OS network libraries to resolve host address mappings.
891 *
892 */
893 private static final class PlatformNameService implements NameService {
894
895 public InetAddress[] lookupAllHostAddr(String host)
896 throws UnknownHostException {
897
898 return impl.lookupAllHostAddr(host);
899
900 }
901
902 public String getHostByAddr(byte[] addr) throws UnknownHostException {
903
904 return impl.getHostByAddr(addr);
905
906 }
907
908 }
909
910 /**
911 * <p>The HostsFileNameService provides host address mapping
912 * by reading the entries in a hosts file, which is specified in the
913 * property jdk.net.hosts.file
914 *
915 * <p>The file format is that which corresponds with the /etc/hosts file
916 * ipaddress host alias list
917 *
918 * <p>When the file lookup is enabled it replaces the call flows to the native
919 * OS ip nameservice lookup calls
920 *
921 * <p>This functionalty doesn't currently support IPV6 mappings
922 * This can be provided whenever it is required
923 */
924 private static final class HostsFileNameService implements NameService {
925
926 private final String hostsFile;
927
928 public HostsFileNameService (String hostsFileName) {
929 this.hostsFile = hostsFileName;
930 }
931
932 private String addrToString(byte addr[]) {
933 return Byte.toString(addr[0]) + "." + Byte.toString(addr[1]) + "."
934 + Byte.toString(addr[2]) + "." + Byte.toString(addr[3]);
935 }
936
937 /**
938 * Lookup the host name corresponding to the IP address provided.
939 * Search the configured host file a host name corresponding to
940 * the specified IP address.
941 *
942 * @param addr byte array representing an IP address
943 * @return {@code String} representing the host name mapping
944 * @throws UnknownHostException
945 * if no host found for the specified IP address
946 */
947 public String getHostByAddr(byte[] addr) throws UnknownHostException {
948 String hostEntry;
949 String host = null;
950
951 String addrString = addrToString(addr);
952 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) {
953 while (hostsFileScanner.hasNextLine()) {
954 hostEntry = hostsFileScanner.nextLine();
955 if (!hostEntry.startsWith("#")) {
956 hostEntry = removeComments(hostEntry);
957 if (hostEntry.contains(addrString)) {
958 host = extractHost(hostEntry, addrString);
959 if (host != null) {
960 break;
961 }
962 }
963 }
964 }
965 } catch (FileNotFoundException e) {
966 throw new UnknownHostException("Unable to resolve address "
967 + addrString + " as hosts file " + hostsFile
968 + " not found ");
969 }
970
971 if ((host == null) || (host.equals("")) || (host.equals(" "))) {
972 throw new UnknownHostException("Requested address "
973 + addrString
974 + " resolves to an invalid entry in hosts file "
975 + hostsFile);
976 }
977 return host;
978 }
979
980
981 /**
982 * <p>Lookup a host mapping by name. Retrieve the IP addresses
983 * associated with a host.
984 *
985 * <p>Search the configured hosts file for the addresses assocaited with
986 * with the specified host name.
987 *
988 * @param host the specified hostname
989 * @return array of IP addresses for the requested host
990 * @throws UnknownHostException
991 * if no IP address for the {@code host} could be found
992 */
993
994 public InetAddress[] lookupAllHostAddr(String host)
995 throws UnknownHostException {
996 String hostEntry;
997 String addrStr = null;
998 InetAddress[] res = null;
999 byte addr[] = new byte[4];
1000 ArrayList<InetAddress> inetAddresses = null;
1001
1002 // lookup the file and create a list InetAddress for the specfied host
1003 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) {
1004 while (hostsFileScanner.hasNextLine()) {
1005 hostEntry = hostsFileScanner.nextLine();
1006 if (!hostEntry.startsWith("#")) {
1007 hostEntry = removeComments(hostEntry);
1008 if (hostEntry.contains(host)) {
1009 addrStr = extractHostAddr(hostEntry, host);
1010 if ((addrStr != null) && (!addrStr.equals(""))) {
1011 createAddressByteArray(addrStr, addr);
1012 if (inetAddresses == null) {
1013 inetAddresses = new ArrayList<>(1);
1014 }
1015 inetAddresses.add(InetAddress.getByAddress(host, addr));
1016 }
1017 }
1018 }
1025 if (inetAddresses != null) {
1026 res = inetAddresses.toArray(new InetAddress[inetAddresses.size()]);
1027 } else {
1028 throw new UnknownHostException("Unable to resolve host " + host
1029 + " in hosts file " + hostsFile);
1030 }
1031 return res;
1032 }
1033
1034 private String removeComments(String hostsEntry) {
1035 String filteredEntry = hostsEntry;
1036 int hashIndex;
1037
1038 if ((hashIndex = hostsEntry.indexOf("#")) != -1) {
1039 filteredEntry = hostsEntry.substring(0, hashIndex);
1040 }
1041 return filteredEntry;
1042 }
1043
1044 private void createAddressByteArray(String addrStr, byte[] addr) {
1045
1046 String[] ipAddr = addrStr.split("\\.");
1047 for (int i = 0; i < 4; i++) {
1048 addr[i] = (byte) Integer.parseInt(ipAddr[i]);
1049 }
1050 }
1051
1052 // host to ip address mapping
1053 private String extractHostAddr(String hostEntry, String host) {
1054 String[] mapping = hostEntry.split("\\s+");
1055 String hostAddr = null;
1056
1057 if (mapping.length >= 2) {
1058 // look at the host aliases
1059 for (int i = 1; i < mapping.length; i++) {
1060 if (mapping[i].equalsIgnoreCase(host)) {
1061 hostAddr = mapping[0];
1062 }
1063 }
1064 }
1065 return hostAddr;
1066 }
1067
1068 // ipaddress to host mapping
1069 // use first host alias in list
1070 private String extractHost(String hostEntry, String addrString) {
1071 String[] mapping = hostEntry.split("\\s+");
1072 String host = null;
1073
1074 if (mapping.length >= 2) {
1075 if (mapping[0].equalsIgnoreCase(addrString)) {
1076 host = mapping[1];
1077 }
1078 }
1079 return host;
1080 }
1081 }
1082
1083 static final InetAddressImpl impl;
1084
1085 static {
1086 // create the impl
1087 impl = InetAddressImplFactory.create();
1088
1089 // create name service
1090 nameService = createNameService();
1091 }
1092
1093 /**
1094 * Create an instance of the NameService interface based on
1095 * the setting of the system property jdk.net.hosts.file.
1096 *
1097 * <p>The default NameService is the PlatformNameService, which typically
1098 * delegates name and address resolution calls to the underlying
1099 * OS network libraries.
1100 *
1101 * <p>If jdk.net.hosts.file is set, and the file exists then
1102 * instantiate a HostsFileNameService
1103 * else
1104 * instantiate a PlatformNameService.
1105 *
1106 * @return the instantiated {@code NameService}
1107 */
1108 private static NameService createNameService() {
1109
1110 String hostsFileName = AccessController
1111 .doPrivileged(new GetPropertyAction("jdk.net.hosts.file"));
1112 NameService theNameService;
1113 if (hostsFileName != null) {
1114 theNameService = new HostsFileNameService(hostsFileName);
1115 } else {
1116 theNameService = new PlatformNameService();
1117 }
1118 return theNameService;
1119 }
1120
1121 /**
1122 * Creates an InetAddress based on the provided host name and IP address.
1123 * No name service is checked for the validity of the address.
1124 *
1125 * <p> The host name can either be a machine name, such as
1126 * "{@code java.sun.com}", or a textual representation of its IP
1127 * address.
1128 * <p> No validity checking is done on the host name either.
1129 *
1130 * <p> If addr specifies an IPv4 address an instance of Inet4Address
1131 * will be returned; otherwise, an instance of Inet6Address
1132 * will be returned.
1133 *
1134 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1135 * must be 16 bytes long
1136 *
1137 * @param host the specified host
1138 * @param addr the raw IP address in network byte order
|
264
265 /**
266 * Specifies the address family type, for instance, '1' for IPv4
267 * addresses, and '2' for IPv6 addresses.
268 */
269 int family;
270
271 int getFamily() {
272 return family;
273 }
274 }
275
276 /* Used to store the serializable fields of InetAddress */
277 final transient InetAddressHolder holder;
278
279 InetAddressHolder holder() {
280 return holder;
281 }
282
283 /* Used to store the name service provider */
284 private static NameService nameService = null;
285
286 /* Used to store the best available hostname */
287 private transient String canonicalHostName = null;
288
289 /** use serialVersionUID from JDK 1.0.2 for interoperability */
290 private static final long serialVersionUID = 3286316764910316507L;
291
292 /*
293 * Load net library into runtime, and perform initializations.
294 */
295 static {
296 preferIPv6Address = java.security.AccessController.doPrivileged(
297 new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue();
298 AccessController.doPrivileged(
299 new java.security.PrivilegedAction<>() {
300 public Void run() {
301 System.loadLibrary("net");
302 return null;
303 }
304 });
841 // schedule expiry
842 expirySet.add(cachedAddresses);
843 }
844 }
845 if (inetAddresses == null) {
846 throw ex == null ? new UnknownHostException(host) : ex;
847 }
848 return inetAddresses;
849 }
850 // else addresses != this
851 }
852 // delegate to different addresses when we are already replaced
853 // but outside of synchronized block to avoid any chance of dead-locking
854 return addresses.get();
855 }
856 }
857
858 /**
859 * NameService provides host and address lookup service
860 *
861 * @since 9
862 */
863 private interface NameService {
864
865 /**
866 * Looks up a host mapping by name. Retrieves the IP addresses
867 * associated with a host.
868 *
869 * @param host the specified hostname
870 * @return an array of IP addresses for the given host name
871 * @throws UnknownHostException
872 * if no IP address for the {@code host} could be found
873 */
874 InetAddress[] lookupAllHostAddr(String host)
875 throws UnknownHostException;
876
877 /**
878 * Looks up the host corresponding to the given IP address.
879 *
880 * @param addr byte array representing an IP address
881 * @return {@code String} representing the host name mapping
882 * @throws UnknownHostException
883 * if no host found for the specified IP address
884 */
885 String getHostByAddr(byte[] addr) throws UnknownHostException;
886 }
887
888 /**
889 * The default NameService implementation, which delegates to the underlying
890 * OS network libraries to resolve host address mappings.
891 *
892 * @since 9
893 */
894 private static final class PlatformNameService implements NameService {
895
896 public InetAddress[] lookupAllHostAddr(String host)
897 throws UnknownHostException
898 {
899 return impl.lookupAllHostAddr(host);
900 }
901
902 public String getHostByAddr(byte[] addr) throws UnknownHostException {
903 return impl.getHostByAddr(addr);
904 }
905 }
906
907 /**
908 * A HostsFileNameService provides host address mappings by reading the
909 * entries in a hosts file, which is specified by the {@code
910 * jdk.net.hosts.file} system property.
911 *
912 * <p> The file format is that which corresponds to the /etc/hosts file
913 * IP Address host alias list.
914 *
915 * <p> When the file lookup is enabled it replaces the default NameService
916 * implementation.
917 *
918 * @since 9
919 */
920 private static final class HostsFileNameService implements NameService {
921
922 private final String hostsFile;
923
924 public HostsFileNameService (String hostsFileName) {
925 this.hostsFile = hostsFileName;
926 }
927
928 private String addrToString(byte addr[]) {
929 return Byte.toString(addr[0]) + "." + Byte.toString(addr[1]) + "."
930 + Byte.toString(addr[2]) + "." + Byte.toString(addr[3]);
931 }
932
933 /**
934 * Looks up the host name corresponding to the IP address provided.
935 * Searches the configured host file for a host name corresponding to
936 * the specified IP address.
937 *
938 * @param addr byte array representing an IP address
939 * @return {@code String} representing the host name mapping
940 * @throws UnknownHostException
941 * if no host found for the specified IP address
942 */
943 @Override
944 public String getHostByAddr(byte[] addr) throws UnknownHostException {
945 String hostEntry;
946 String host = null;
947
948 String addrString = addrToString(addr);
949 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) {
950 while (hostsFileScanner.hasNextLine()) {
951 hostEntry = hostsFileScanner.nextLine();
952 if (!hostEntry.startsWith("#")) {
953 hostEntry = removeComments(hostEntry);
954 if (hostEntry.contains(addrString)) {
955 host = extractHost(hostEntry, addrString);
956 if (host != null) {
957 break;
958 }
959 }
960 }
961 }
962 } catch (FileNotFoundException e) {
963 throw new UnknownHostException("Unable to resolve address "
964 + addrString + " as hosts file " + hostsFile
965 + " not found ");
966 }
967
968 if ((host == null) || (host.equals("")) || (host.equals(" "))) {
969 throw new UnknownHostException("Requested address "
970 + addrString
971 + " resolves to an invalid entry in hosts file "
972 + hostsFile);
973 }
974 return host;
975 }
976
977
978 /**
979 * Looks up a host mapping by name. Retrieves the IP addresses
980 * associated with a host.
981 *
982 * <p> Searches the configured hosts file for the addresses associated
983 * with with the specified host name.
984 *
985 * @param host the specified hostname
986 * @return array of IP addresses for the requested host
987 * @throws UnknownHostException
988 * if no IP address for the {@code host} could be found
989 */
990 @Override
991 public InetAddress[] lookupAllHostAddr(String host)
992 throws UnknownHostException
993 {
994 String hostEntry;
995 String addrStr;
996 InetAddress[] res;
997 byte addr[] = new byte[4];
998 ArrayList<InetAddress> inetAddresses = null;
999
1000 // lookup the file and create a list InetAddress for the specfied host
1001 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) {
1002 while (hostsFileScanner.hasNextLine()) {
1003 hostEntry = hostsFileScanner.nextLine();
1004 if (!hostEntry.startsWith("#")) {
1005 hostEntry = removeComments(hostEntry);
1006 if (hostEntry.contains(host)) {
1007 addrStr = extractHostAddr(hostEntry, host);
1008 if ((addrStr != null) && (!addrStr.equals(""))) {
1009 createAddressByteArray(addrStr, addr);
1010 if (inetAddresses == null) {
1011 inetAddresses = new ArrayList<>(1);
1012 }
1013 inetAddresses.add(InetAddress.getByAddress(host, addr));
1014 }
1015 }
1016 }
1023 if (inetAddresses != null) {
1024 res = inetAddresses.toArray(new InetAddress[inetAddresses.size()]);
1025 } else {
1026 throw new UnknownHostException("Unable to resolve host " + host
1027 + " in hosts file " + hostsFile);
1028 }
1029 return res;
1030 }
1031
1032 private String removeComments(String hostsEntry) {
1033 String filteredEntry = hostsEntry;
1034 int hashIndex;
1035
1036 if ((hashIndex = hostsEntry.indexOf("#")) != -1) {
1037 filteredEntry = hostsEntry.substring(0, hashIndex);
1038 }
1039 return filteredEntry;
1040 }
1041
1042 private void createAddressByteArray(String addrStr, byte[] addr) {
1043 String[] ipAddr = addrStr.split("\\.");
1044 for (int i = 0; i < 4; i++) {
1045 addr[i] = (byte) Integer.parseInt(ipAddr[i]);
1046 }
1047 }
1048
1049 /** Host to IP address mapping. */
1050 private String extractHostAddr(String hostEntry, String host) {
1051 String[] mapping = hostEntry.split("\\s+");
1052 String hostAddr = null;
1053
1054 if (mapping.length >= 2) {
1055 // look at the host aliases
1056 for (int i = 1; i < mapping.length; i++) {
1057 if (mapping[i].equalsIgnoreCase(host)) {
1058 hostAddr = mapping[0];
1059 }
1060 }
1061 }
1062 return hostAddr;
1063 }
1064
1065 /** IP Address to host mapping. Uses first host alias in list. */
1066 private String extractHost(String hostEntry, String addrString) {
1067 String[] mapping = hostEntry.split("\\s+");
1068 String host = null;
1069
1070 if (mapping.length >= 2) {
1071 if (mapping[0].equalsIgnoreCase(addrString)) {
1072 host = mapping[1];
1073 }
1074 }
1075 return host;
1076 }
1077 }
1078
1079 static final InetAddressImpl impl;
1080
1081 static {
1082 // create the impl
1083 impl = InetAddressImplFactory.create();
1084
1085 // create name service
1086 nameService = createNameService();
1087 }
1088
1089 /**
1090 * Creates an instance of the NameService interface based on the value of
1091 * the {@code jdk.net.hosts.file} system property.
1092 *
1093 * <p> The default NameService is the PlatformNameService, which typically
1094 * delegates name and address resolution calls to the underlying OS network
1095 * libraries.
1096 *
1097 * <p> A HostsFileNameService is created if the {@code jdk.net.hosts.file}
1098 * system property is set. If the specified file doesn't exist, the name or
1099 * address lookup will result in an UnknownHostException. Thus, non existent
1100 * hosts file is handled as if the file is empty.
1101 *
1102 * @return a NameService
1103 */
1104 private static NameService createNameService() {
1105 String hostsFileName = AccessController
1106 .doPrivileged(new GetPropertyAction("jdk.net.hosts.file"));
1107
1108 if (hostsFileName != null) {
1109 return new HostsFileNameService(hostsFileName);
1110 } else {
1111 return new PlatformNameService();
1112 }
1113 }
1114
1115 /**
1116 * Creates an InetAddress based on the provided host name and IP address.
1117 * No name service is checked for the validity of the address.
1118 *
1119 * <p> The host name can either be a machine name, such as
1120 * "{@code java.sun.com}", or a textual representation of its IP
1121 * address.
1122 * <p> No validity checking is done on the host name either.
1123 *
1124 * <p> If addr specifies an IPv4 address an instance of Inet4Address
1125 * will be returned; otherwise, an instance of Inet6Address
1126 * will be returned.
1127 *
1128 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1129 * must be 16 bytes long
1130 *
1131 * @param host the specified host
1132 * @param addr the raw IP address in network byte order
|