8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.net;
27
28 import java.util.List;
29 import java.util.NavigableSet;
30 import java.util.ArrayList;
31 import java.util.Objects;
32 import java.util.Scanner;
33 import java.io.File;
34 import java.io.ObjectStreamException;
35 import java.io.ObjectStreamField;
36 import java.io.IOException;
37 import java.io.InvalidObjectException;
38 import java.io.ObjectInputStream;
39 import java.io.ObjectInputStream.GetField;
40 import java.io.ObjectOutputStream;
41 import java.io.ObjectOutputStream.PutField;
42 import java.lang.annotation.Native;
43 import java.util.concurrent.ConcurrentHashMap;
44 import java.util.concurrent.ConcurrentMap;
45 import java.util.concurrent.ConcurrentSkipListSet;
46 import java.util.concurrent.atomic.AtomicLong;
47 import java.util.Arrays;
48
49 import jdk.internal.access.JavaNetInetAddressAccess;
50 import jdk.internal.access.SharedSecrets;
51 import sun.security.action.*;
52 import sun.net.InetAddressCachePolicy;
53 import sun.net.util.IPAddressUtil;
54 import sun.nio.cs.UTF_8;
55
56 /**
57 * This class represents an Internet Protocol (IP) address.
58 *
59 * <p> An IP address is either a 32-bit or 128-bit unsigned number
60 * used by IP, a lower-level protocol on which protocols like UDP and
61 * TCP are built. The IP address architecture is defined by <a
62 * href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC 790:
63 * Assigned Numbers</i></a>, <a
64 * href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC 1918:
65 * Address Allocation for Private Internets</i></a>, <a
66 * href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:
67 * Administratively Scoped IP Multicast</i></a>, and <a
68 * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP
69 * Version 6 Addressing Architecture</i></a>. An instance of an
70 * InetAddress consists of an IP address and possibly its
71 * corresponding host name (depending on whether it is constructed
72 * with a host name or whether it has already done reverse host name
73 * resolution).
74 *
75 * <h2> Address types </h2>
171 * <dl style="margin-left:2em">
172 * <dt><b>networkaddress.cache.ttl</b></dt>
173 * <dd>Indicates the caching policy for successful name lookups from
174 * the name service. The value is specified as an integer to indicate
175 * the number of seconds to cache the successful lookup. The default
176 * setting is to cache for an implementation specific period of time.
177 * <p>
178 * A value of -1 indicates "cache forever".
179 * </dd>
180 * <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>
181 * <dd>Indicates the caching policy for un-successful name lookups
182 * from the name service. The value is specified as an integer to
183 * indicate the number of seconds to cache the failure for
184 * un-successful lookups.
185 * <p>
186 * A value of 0 indicates "never cache".
187 * A value of -1 indicates "cache forever".
188 * </dd>
189 * </dl>
190 *
191 * @author Chris Warth
192 * @see java.net.InetAddress#getByAddress(byte[])
193 * @see java.net.InetAddress#getByAddress(java.lang.String, byte[])
194 * @see java.net.InetAddress#getAllByName(java.lang.String)
195 * @see java.net.InetAddress#getByName(java.lang.String)
196 * @see java.net.InetAddress#getLocalHost()
197 * @since 1.0
198 */
199 public class InetAddress implements java.io.Serializable {
200
201 @Native static final int PREFER_IPV4_VALUE = 0;
202 @Native static final int PREFER_IPV6_VALUE = 1;
203 @Native static final int PREFER_SYSTEM_VALUE = 2;
204
205 /**
206 * Specify the address family: Internet Protocol, Version 4
207 * @since 1.4
208 */
209 @Native static final int IPv4 = 1;
210
211 /**
212 * Specify the address family: Internet Protocol, Version 6
213 * @since 1.4
214 */
215 @Native static final int IPv6 = 2;
216
217 /* Specify address family preference */
218 static transient final int preferIPv6Address;
219
220 static class InetAddressHolder {
221 /**
222 * Reserve the original application specified hostname.
223 *
224 * The original hostname is useful for domain-based endpoint
225 * identification (see RFC 2818 and RFC 6125). If an address
226 * was created with a raw IP address, a reverse name lookup
227 * may introduce endpoint identification security issue via
228 * DNS forging.
229 *
230 * Oracle JSSE provider is using this original hostname, via
231 * jdk.internal.misc.JavaNetAccess, for SSL/TLS endpoint identification.
232 *
233 * Note: May define a new public method in the future if necessary.
234 */
235 String originalHostName;
236
237 InetAddressHolder() {}
238
239 InetAddressHolder(String hostName, int address, int family) {
271 }
272
273 /**
274 * Specifies the address family type, for instance, '1' for IPv4
275 * addresses, and '2' for IPv6 addresses.
276 */
277 int family;
278
279 int getFamily() {
280 return family;
281 }
282 }
283
284 /* Used to store the serializable fields of InetAddress */
285 final transient InetAddressHolder holder;
286
287 InetAddressHolder holder() {
288 return holder;
289 }
290
291 /* Used to store the name service provider */
292 private static transient NameService nameService;
293
294 /**
295 * Used to store the best available hostname.
296 * Lazily initialized via a data race; safe because Strings are immutable.
297 */
298 private transient String canonicalHostName = null;
299
300 /** use serialVersionUID from JDK 1.0.2 for interoperability */
301 @java.io.Serial
302 private static final long serialVersionUID = 3286316764910316507L;
303
304 /*
305 * Load net library into runtime, and perform initializations.
306 */
307 static {
308 String str = GetPropertyAction.privilegedGetProperty("java.net.preferIPv6Addresses");
309 if (str == null) {
310 preferIPv6Address = PREFER_IPV4_VALUE;
311 } else if (str.equalsIgnoreCase("true")) {
312 preferIPv6Address = PREFER_IPV6_VALUE;
313 } else if (str.equalsIgnoreCase("false")) {
314 preferIPv6Address = PREFER_IPV4_VALUE;
315 } else if (str.equalsIgnoreCase("system")) {
316 preferIPv6Address = PREFER_SYSTEM_VALUE;
317 } else {
318 preferIPv6Address = PREFER_IPV4_VALUE;
319 }
320 jdk.internal.loader.BootLoader.loadLibrary("net");
321 SharedSecrets.setJavaNetInetAddressAccess(
322 new JavaNetInetAddressAccess() {
323 public String getOriginalHostName(InetAddress ia) {
324 return ia.holder.getOriginalHostName();
325 }
326
327 public InetAddress getByName(String hostName,
328 InetAddress hostAddress)
329 throws UnknownHostException
330 {
331 return InetAddress.getByName(hostName, hostAddress);
332 }
333
334 public int addressValue(Inet4Address inet4Address) {
335 return inet4Address.addressValue();
336 }
337
338 public byte[] addressBytes(Inet6Address inet6Address) {
339 return inet6Address.addressBytes();
340 }
341 }
342 );
343 init();
344 }
345
346 /**
347 * Constructor for the Socket.accept() method.
348 * This creates an empty InetAddress, which is filled in by
349 * the accept() method. This InetAddress, however, is not
350 * put in the address cache, since it is not created by name.
351 */
352 InetAddress() {
353 holder = new InetAddressHolder();
354 }
355
356 /**
357 * Replaces the de-serialized object with an Inet4Address object.
358 *
359 * @return the alternate object to the de-serialized object.
360 *
361 * @throws ObjectStreamException if a new object replacing this
362 * object could not be created
363 */
364 @java.io.Serial
365 private Object readResolve() throws ObjectStreamException {
538 * @throws IOException if a network error occurs
539 * @since 1.5
540 */
541 public boolean isReachable(NetworkInterface netif, int ttl,
542 int timeout) throws IOException {
543 if (ttl < 0)
544 throw new IllegalArgumentException("ttl can't be negative");
545 if (timeout < 0)
546 throw new IllegalArgumentException("timeout can't be negative");
547
548 return impl.isReachable(this, timeout, netif, ttl);
549 }
550
551 /**
552 * Gets the host name for this IP address.
553 *
554 * <p>If this InetAddress was created with a host name,
555 * this host name will be remembered and returned;
556 * otherwise, a reverse name lookup will be performed
557 * and the result will be returned based on the system
558 * configured name lookup service. If a lookup of the name service
559 * is required, call
560 * {@link #getCanonicalHostName() getCanonicalHostName}.
561 *
562 * <p>If there is a security manager, its
563 * {@code checkConnect} method is first called
564 * with the hostname and {@code -1}
565 * as its arguments to see if the operation is allowed.
566 * If the operation is not allowed, it will return
567 * the textual representation of the IP address.
568 *
569 * @return the host name for this IP address, or if the operation
570 * is not allowed by the security check, the textual
571 * representation of the IP address.
572 *
573 * @see InetAddress#getCanonicalHostName
574 * @see SecurityManager#checkConnect
575 */
576 public String getHostName() {
577 return getHostName(true);
578 }
639 /**
640 * Returns the hostname for this address.
641 *
642 * <p>If there is a security manager, this method first
643 * calls its {@code checkConnect} method
644 * with the hostname and {@code -1}
645 * as its arguments to see if the calling code is allowed to know
646 * the hostname for this IP address, i.e., to connect to the host.
647 * If the operation is not allowed, it will return
648 * the textual representation of the IP address.
649 *
650 * @return the host name for this IP address, or if the operation
651 * is not allowed by the security check, the textual
652 * representation of the IP address.
653 *
654 * @param check make security check if true
655 *
656 * @see SecurityManager#checkConnect
657 */
658 private static String getHostFromNameService(InetAddress addr, boolean check) {
659 String host = null;
660 try {
661 // first lookup the hostname
662 host = nameService.getHostByAddr(addr.getAddress());
663
664 /* check to see if calling code is allowed to know
665 * the hostname for this IP address, ie, connect to the host
666 */
667 if (check) {
668 @SuppressWarnings("removal")
669 SecurityManager sec = System.getSecurityManager();
670 if (sec != null) {
671 sec.checkConnect(host, -1);
672 }
673 }
674
675 /* now get all the IP addresses for this hostname,
676 * and make sure one of them matches the original IP
677 * address. We do this to try and prevent spoofing.
678 */
679
680 InetAddress[] arr = InetAddress.getAllByName0(host, check);
681 boolean ok = false;
682
683 if (arr != null) {
684 for (int i = 0; !ok && i < arr.length; i++) {
685 ok = addr.equals(arr[i]);
686 }
687 }
688
689 //XXX: if it looks like a spoof just return the address?
690 if (!ok) {
691 host = addr.getHostAddress();
692 return host;
693 }
694 } catch (SecurityException e) {
695 host = addr.getHostAddress();
696 } catch (UnknownHostException e) {
697 host = addr.getHostAddress();
698 // let next provider resolve the hostname
699 }
700 return host;
701 }
702
703 /**
704 * Returns the raw IP address of this {@code InetAddress}
705 * object. The result is in network byte order: the highest order
706 * byte of the address is in {@code getAddress()[0]}.
707 *
708 * @return the raw IP address of this object.
709 */
710 public byte[] getAddress() {
711 return null;
712 }
713
714 /**
715 * Returns the IP address string in textual presentation.
716 *
717 * @return the raw IP address in a string format.
718 * @since 1.0.2
738 * <p>
739 * Two instances of {@code InetAddress} represent the same IP
740 * address if the length of the byte arrays returned by
741 * {@code getAddress} is the same for both, and each of the
742 * array components is the same for the byte arrays.
743 *
744 * @param obj the object to compare against.
745 * @return {@code true} if the objects are the same;
746 * {@code false} otherwise.
747 * @see java.net.InetAddress#getAddress()
748 */
749 public boolean equals(Object obj) {
750 return false;
751 }
752
753 /**
754 * Converts this IP address to a {@code String}. The
755 * string returned is of the form: hostname / literal IP
756 * address.
757 *
758 * If the host name is unresolved, no reverse name service lookup
759 * is performed. The hostname part will be represented by an empty string.
760 *
761 * @return a string representation of this IP address.
762 */
763 public String toString() {
764 String hostName = holder().getHostName();
765 return Objects.toString(hostName, "")
766 + "/" + getHostAddress();
767 }
768
769 // mapping from host name to Addresses - either NameServiceAddresses (while
770 // still being looked-up by NameService(s)) or CachedAddresses when cached
771 private static final ConcurrentMap<String, Addresses> cache =
772 new ConcurrentHashMap<>();
773
774 // CachedAddresses that have to expire are kept ordered in this NavigableSet
775 // which is scanned on each access
776 private static final NavigableSet<CachedAddresses> expirySet =
777 new ConcurrentSkipListSet<>();
778
779 // common interface
804 }
805
806 @Override
807 public int compareTo(CachedAddresses other) {
808 // natural order is expiry time -
809 // compare difference of expiry times rather than
810 // expiry times directly, to avoid possible overflow.
811 // (see System.nanoTime() recommendations...)
812 long diff = this.expiryTime - other.expiryTime;
813 if (diff < 0L) return -1;
814 if (diff > 0L) return 1;
815 // ties are broken using unique id
816 return Long.compare(this.id, other.id);
817 }
818 }
819
820 // a name service lookup based Addresses implementation which replaces itself
821 // in cache when the result is obtained
822 private static final class NameServiceAddresses implements Addresses {
823 private final String host;
824 private final InetAddress reqAddr;
825
826 NameServiceAddresses(String host, InetAddress reqAddr) {
827 this.host = host;
828 this.reqAddr = reqAddr;
829 }
830
831 @Override
832 public InetAddress[] get() throws UnknownHostException {
833 Addresses addresses;
834 // only one thread is doing lookup to name service
835 // for particular host at any time.
836 synchronized (this) {
837 // re-check that we are still us + re-install us if slot empty
838 addresses = cache.putIfAbsent(host, this);
839 if (addresses == null) {
840 // this can happen when we were replaced by CachedAddresses in
841 // some other thread, then CachedAddresses expired and were
842 // removed from cache while we were waiting for lock...
843 addresses = this;
844 }
845 // still us ?
846 if (addresses == this) {
847 // lookup name services
848 InetAddress[] inetAddresses;
849 UnknownHostException ex;
850 int cachePolicy;
851 try {
852 inetAddresses = getAddressesFromNameService(host, reqAddr);
853 ex = null;
854 cachePolicy = InetAddressCachePolicy.get();
855 } catch (UnknownHostException uhe) {
856 inetAddresses = null;
857 ex = uhe;
858 cachePolicy = InetAddressCachePolicy.getNegative();
859 }
860 // remove or replace us with cached addresses according to cachePolicy
861 if (cachePolicy == InetAddressCachePolicy.NEVER) {
862 cache.remove(host, this);
863 } else {
864 CachedAddresses cachedAddresses = new CachedAddresses(
865 host,
866 inetAddresses,
867 cachePolicy == InetAddressCachePolicy.FOREVER
868 ? 0L
869 // cachePolicy is in [s] - we need [ns]
870 : System.nanoTime() + 1000_000_000L * cachePolicy
871 );
872 if (cache.replace(host, this, cachedAddresses) &&
873 cachePolicy != InetAddressCachePolicy.FOREVER) {
874 // schedule expiry
875 expirySet.add(cachedAddresses);
876 }
877 }
878 if (inetAddresses == null) {
879 throw ex == null ? new UnknownHostException(host) : ex;
880 }
881 return inetAddresses;
882 }
883 // else addresses != this
884 }
885 // delegate to different addresses when we are already replaced
886 // but outside of synchronized block to avoid any chance of dead-locking
887 return addresses.get();
888 }
889 }
890
891 /**
892 * NameService provides host and address lookup service
893 *
894 * @since 9
895 */
896 private interface NameService {
897
898 /**
899 * Lookup a host mapping by name. Retrieve the IP addresses
900 * associated with a host
901 *
902 * @param host the specified hostname
903 * @return array of IP addresses for the requested host
904 * @throws UnknownHostException
905 * if no IP address for the {@code host} could be found
906 */
907 InetAddress[] lookupAllHostAddr(String host)
908 throws UnknownHostException;
909
910 /**
911 * Lookup the host corresponding to the IP address provided
912 *
913 * @param addr byte array representing an IP address
914 * @return {@code String} representing the host name mapping
915 * @throws UnknownHostException
916 * if no host found for the specified IP address
917 */
918 String getHostByAddr(byte[] addr) throws UnknownHostException;
919
920 }
921
922 /**
923 * The default NameService implementation, which delegates to the underlying
924 * OS network libraries to resolve host address mappings.
925 *
926 * @since 9
927 */
928 private static final class PlatformNameService implements NameService {
929
930 public InetAddress[] lookupAllHostAddr(String host)
931 throws UnknownHostException
932 {
933 return impl.lookupAllHostAddr(host);
934 }
935
936 public String getHostByAddr(byte[] addr)
937 throws UnknownHostException
938 {
939 return impl.getHostByAddr(addr);
940 }
941 }
942
943 /**
944 * The HostsFileNameService provides host address mapping
945 * by reading the entries in a hosts file, which is specified by
946 * {@code jdk.net.hosts.file} system property
947 *
948 * <p>The file format is that which corresponds with the /etc/hosts file
949 * IP Address host alias list.
950 *
951 * <p>When the file lookup is enabled it replaces the default NameService
952 * implementation
953 *
954 * @since 9
955 */
956 private static final class HostsFileNameService implements NameService {
957
958 private static final InetAddress[] EMPTY_ARRAY = new InetAddress[0];
959
960 // Specify if only IPv4 addresses should be returned by HostsFileService implementation
961 private static final boolean preferIPv4Stack = Boolean.parseBoolean(
962 GetPropertyAction.privilegedGetProperty("java.net.preferIPv4Stack"));
963
964 private final String hostsFile;
965
966 public HostsFileNameService(String hostsFileName) {
967 this.hostsFile = hostsFileName;
968 }
969
970 /**
971 * Lookup the host name corresponding to the IP address provided.
972 * Search the configured host file a host name corresponding to
973 * the specified IP address.
974 *
975 * @param addr byte array representing an IP address
976 * @return {@code String} representing the host name mapping
977 * @throws UnknownHostException
978 * if no host found for the specified IP address
979 */
980 @Override
981 public String getHostByAddr(byte[] addr) throws UnknownHostException {
982 String hostEntry;
983 String host = null;
984
985 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
986 UTF_8.INSTANCE))
987 {
988 while (hostsFileScanner.hasNextLine()) {
989 hostEntry = hostsFileScanner.nextLine();
990 if (!hostEntry.startsWith("#")) {
991 hostEntry = removeComments(hostEntry);
992 String[] mapping = hostEntry.split("\\s+");
993 if (mapping.length >= 2 &&
994 Arrays.equals(addr, createAddressByteArray(mapping[0]))) {
995 host = mapping[1];
996 break;
997 }
998 }
999 }
1000 } catch (IOException e) {
1001 throw new UnknownHostException("Unable to resolve address "
1002 + Arrays.toString(addr) + " as hosts file " + hostsFile
1003 + " not found ");
1004 }
1005
1006 if ((host == null) || (host.isEmpty()) || (host.equals(" "))) {
1007 throw new UnknownHostException("Requested address "
1008 + Arrays.toString(addr)
1009 + " resolves to an invalid entry in hosts file "
1010 + hostsFile);
1011 }
1012 return host;
1013 }
1014
1015 /**
1016 * <p>Lookup a host mapping by name. Retrieve the IP addresses
1017 * associated with a host.
1018 *
1019 * <p>Search the configured hosts file for the addresses associated
1020 * with the specified host name.
1021 *
1022 * @param host the specified hostname
1023 * @return array of IP addresses for the requested host
1024 * @throws UnknownHostException
1025 * if no IP address for the {@code host} could be found
1026 */
1027 public InetAddress[] lookupAllHostAddr(String host)
1028 throws UnknownHostException {
1029 String hostEntry;
1030 String addrStr;
1031 byte addr[];
1032 List<InetAddress> inetAddresses = new ArrayList<>();
1033 List<InetAddress> inet4Addresses = new ArrayList<>();
1034 List<InetAddress> inet6Addresses = new ArrayList<>();
1035
1036 // lookup the file and create a list InetAddress for the specified host
1037 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
1038 UTF_8.INSTANCE)) {
1039 while (hostsFileScanner.hasNextLine()) {
1040 hostEntry = hostsFileScanner.nextLine();
1041 if (!hostEntry.startsWith("#")) {
1042 hostEntry = removeComments(hostEntry);
1043 if (hostEntry.contains(host)) {
1044 addrStr = extractHostAddr(hostEntry, host);
1045 if ((addrStr != null) && (!addrStr.isEmpty())) {
1046 addr = createAddressByteArray(addrStr);
1047 if (addr != null) {
1048 InetAddress address = InetAddress.getByAddress(host, addr);
1049 inetAddresses.add(address);
1050 if (address instanceof Inet4Address) {
1051 inet4Addresses.add(address);
1052 }
1053 if (address instanceof Inet6Address) {
1054 inet6Addresses.add(address);
1055 }
1056 }
1057 }
1058 }
1059 }
1060 }
1061 } catch (IOException e) {
1062 throw new UnknownHostException("Unable to resolve host " + host
1063 + " as hosts file " + hostsFile + " not found ");
1064 }
1065
1066 List<InetAddress> res;
1067 // If "preferIPv4Stack" system property is set to "true" then return
1068 // only IPv4 addresses
1069 if (preferIPv4Stack) {
1070 res = inet4Addresses;
1071 } else {
1072 // Otherwise, analyse "preferIPv6Addresses" value
1073 res = switch (preferIPv6Address) {
1074 case PREFER_IPV4_VALUE -> concatAddresses(inet4Addresses, inet6Addresses);
1075 case PREFER_IPV6_VALUE -> concatAddresses(inet6Addresses, inet4Addresses);
1076 default -> inetAddresses;
1077 };
1078 }
1079
1080 if (res.isEmpty()) {
1081 throw new UnknownHostException("Unable to resolve host " + host
1082 + " in hosts file " + hostsFile);
1083 }
1084 return res.toArray(EMPTY_ARRAY);
1085 }
1086
1087 private static List<InetAddress> concatAddresses(List<InetAddress> firstPart,
1088 List<InetAddress> secondPart) {
1089 List<InetAddress> result = new ArrayList<>(firstPart);
1090 result.addAll(secondPart);
1091 return result;
1092 }
1093
1094 private String removeComments(String hostsEntry) {
1095 String filteredEntry = hostsEntry;
1096 int hashIndex;
1097
1098 if ((hashIndex = hostsEntry.indexOf("#")) != -1) {
1099 filteredEntry = hostsEntry.substring(0, hashIndex);
1100 }
1101 return filteredEntry;
1102 }
1103
1104 private byte [] createAddressByteArray(String addrStr) {
1105 byte[] addrArray;
1106 // check if IPV4 address - most likely
1107 addrArray = IPAddressUtil.textToNumericFormatV4(addrStr);
1108 if (addrArray == null) {
1109 addrArray = IPAddressUtil.textToNumericFormatV6(addrStr);
1110 }
1111 return addrArray;
1113
1114 /** host to ip address mapping */
1115 private String extractHostAddr(String hostEntry, String host) {
1116 String[] mapping = hostEntry.split("\\s+");
1117 String hostAddr = null;
1118
1119 if (mapping.length >= 2) {
1120 // look at the host aliases
1121 for (int i = 1; i < mapping.length; i++) {
1122 if (mapping[i].equalsIgnoreCase(host)) {
1123 hostAddr = mapping[0];
1124 }
1125 }
1126 }
1127 return hostAddr;
1128 }
1129 }
1130
1131 static final InetAddressImpl impl;
1132
1133 static {
1134 // create the impl
1135 impl = InetAddressImplFactory.create();
1136
1137 // create name service
1138 nameService = createNameService();
1139 }
1140
1141 /**
1142 * Create an instance of the NameService interface based on
1143 * the setting of the {@code jdk.net.hosts.file} system property.
1144 *
1145 * <p>The default NameService is the PlatformNameService, which typically
1146 * delegates name and address resolution calls to the underlying
1147 * OS network libraries.
1148 *
1149 * <p> A HostsFileNameService is created if the {@code jdk.net.hosts.file}
1150 * system property is set. If the specified file doesn't exist, the name or
1151 * address lookup will result in an UnknownHostException. Thus, non existent
1152 * hosts file is handled as if the file is empty.
1153 *
1154 * @return a NameService
1155 */
1156 private static NameService createNameService() {
1157
1158 String hostsFileName =
1159 GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file");
1160 NameService theNameService;
1161 if (hostsFileName != null) {
1162 theNameService = new HostsFileNameService(hostsFileName);
1163 } else {
1164 theNameService = new PlatformNameService();
1165 }
1166 return theNameService;
1167 }
1168
1169 /**
1170 * Creates an InetAddress based on the provided host name and IP address.
1171 * No name service is checked for the validity of the address.
1172 *
1173 * <p> The host name can either be a machine name, such as
1174 * "{@code www.example.com}", or a textual representation of its IP
1175 * address.
1176 * <p> No validity checking is done on the host name either.
1177 *
1178 * <p> If addr specifies an IPv4 address an instance of Inet4Address
1179 * will be returned; otherwise, an instance of Inet6Address
1180 * will be returned.
1181 *
1182 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1183 * must be 16 bytes long
1184 *
1185 * @param host the specified host
1186 * @param addr the raw IP address in network byte order
1187 * @return an InetAddress object created from the raw IP address.
1188 * @throws UnknownHostException if IP address is of illegal length
1189 * @since 1.4
1190 */
1191 public static InetAddress getByAddress(String host, byte[] addr)
1234 * section 2.5.3.
1235 *
1236 * <p> If there is a security manager, and {@code host} is not {@code null}
1237 * or {@code host.length() } is not equal to zero, the security manager's
1238 * {@code checkConnect} method is called with the hostname and {@code -1}
1239 * as its arguments to determine if the operation is allowed.
1240 *
1241 * @param host the specified host, or {@code null}.
1242 * @return an IP address for the given host name.
1243 * @throws UnknownHostException if no IP address for the
1244 * {@code host} could be found, or if a scope_id was specified
1245 * for a global IPv6 address.
1246 * @throws SecurityException if a security manager exists
1247 * and its checkConnect method doesn't allow the operation
1248 */
1249 public static InetAddress getByName(String host)
1250 throws UnknownHostException {
1251 return InetAddress.getAllByName(host)[0];
1252 }
1253
1254 // called from deployment cache manager
1255 private static InetAddress getByName(String host, InetAddress reqAddr)
1256 throws UnknownHostException {
1257 return InetAddress.getAllByName(host, reqAddr)[0];
1258 }
1259
1260 /**
1261 * Given the name of a host, returns an array of its IP addresses,
1262 * based on the configured name service on the system.
1263 *
1264 * <p> The host name can either be a machine name, such as
1265 * "{@code www.example.com}", or a textual representation of its IP
1266 * address. If a literal IP address is supplied, only the
1267 * validity of the address format is checked.
1268 *
1269 * <p> For {@code host} specified in <i>literal IPv6 address</i>,
1270 * either the form defined in RFC 2732 or the literal IPv6 address
1271 * format defined in RFC 2373 is accepted. A literal IPv6 address may
1272 * also be qualified by appending a scoped zone identifier or scope_id.
1273 * The syntax and usage of scope_ids is described
1274 * <a href="Inet6Address.html#scoped">here</a>.
1275 *
1276 * <p> If the host is {@code null} or {@code host.length()} is equal
1277 * to zero, then an {@code InetAddress} representing an address of the
1278 * loopback interface is returned.
1279 * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
1280 * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
1281 * section 2.5.3. </p>
1282 *
1283 * <p> If there is a security manager, and {@code host} is not {@code null}
1284 * or {@code host.length() } is not equal to zero, the security manager's
1285 * {@code checkConnect} method is called with the hostname and {@code -1}
1286 * as its arguments to determine if the operation is allowed.
1287 *
1288 * @param host the name of the host, or {@code null}.
1289 * @return an array of all the IP addresses for a given host name.
1290 *
1291 * @throws UnknownHostException if no IP address for the
1292 * {@code host} could be found, or if a scope_id was specified
1293 * for a global IPv6 address.
1294 * @throws SecurityException if a security manager exists and its
1295 * {@code checkConnect} method doesn't allow the operation.
1296 *
1297 * @see SecurityManager#checkConnect
1298 */
1299 public static InetAddress[] getAllByName(String host)
1300 throws UnknownHostException {
1301 return getAllByName(host, null);
1302 }
1303
1304 private static InetAddress[] getAllByName(String host, InetAddress reqAddr)
1305 throws UnknownHostException {
1306
1307 if (host == null || host.isEmpty()) {
1308 InetAddress[] ret = new InetAddress[1];
1309 ret[0] = impl.loopbackAddress();
1310 return ret;
1311 }
1312
1313 boolean ipv6Expected = false;
1314 if (host.charAt(0) == '[') {
1315 // This is supposed to be an IPv6 literal
1316 if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
1317 host = host.substring(1, host.length() -1);
1318 ipv6Expected = true;
1319 } else {
1320 // This was supposed to be a IPv6 address, but it's not!
1321 throw new UnknownHostException(host + ": invalid IPv6 address");
1322 }
1323 }
1324
1325 // if host is an IP address, we won't do further lookup
1347 // Means an IPv4 literal between brackets!
1348 throw new UnknownHostException("["+host+"]");
1349 }
1350 InetAddress[] ret = new InetAddress[1];
1351 if(addr != null) {
1352 if (addr.length == Inet4Address.INADDRSZ) {
1353 ret[0] = new Inet4Address(null, addr);
1354 } else {
1355 if (ifname != null) {
1356 ret[0] = new Inet6Address(null, addr, ifname);
1357 } else {
1358 ret[0] = new Inet6Address(null, addr, numericZone);
1359 }
1360 }
1361 return ret;
1362 }
1363 } else if (ipv6Expected) {
1364 // We were expecting an IPv6 Literal, but got something else
1365 throw new UnknownHostException("["+host+"]");
1366 }
1367 return getAllByName0(host, reqAddr, true, true);
1368 }
1369
1370 /**
1371 * Returns the loopback address.
1372 * <p>
1373 * The InetAddress returned will represent the IPv4
1374 * loopback address, 127.0.0.1, or the IPv6 loopback
1375 * address, ::1. The IPv4 loopback address returned
1376 * is only one of many in the form 127.*.*.*
1377 *
1378 * @return the InetAddress loopback instance.
1379 * @since 1.7
1380 */
1381 public static InetAddress getLoopbackAddress() {
1382 return impl.loopbackAddress();
1383 }
1384
1385
1386 /**
1387 * check if the literal address string has %nn appended
1397 if (percent == -1) {
1398 return -1;
1399 }
1400 for (int i=percent+1; i<slen; i++) {
1401 char c = s.charAt(i);
1402 if (c == ']') {
1403 if (i == percent+1) {
1404 /* empty per-cent field */
1405 return -1;
1406 }
1407 break;
1408 }
1409 if ((digit = Character.digit (c, 10)) < 0) {
1410 return -1;
1411 }
1412 zone = (zone * 10) + digit;
1413 }
1414 return zone;
1415 }
1416
1417 private static InetAddress[] getAllByName0 (String host)
1418 throws UnknownHostException
1419 {
1420 return getAllByName0(host, true);
1421 }
1422
1423 /**
1424 * package private so SocketPermission can call it
1425 */
1426 static InetAddress[] getAllByName0 (String host, boolean check)
1427 throws UnknownHostException {
1428 return getAllByName0 (host, null, check, true);
1429 }
1430
1431 /**
1432 * Designated lookup method.
1433 *
1434 * @param host host name to look up
1435 * @param reqAddr requested address to be the 1st in returned array
1436 * @param check perform security check
1437 * @param useCache use cached value if not expired else always
1438 * perform name service lookup (and cache the result)
1439 * @return array of InetAddress(es)
1440 * @throws UnknownHostException if host name is not found
1441 */
1442 private static InetAddress[] getAllByName0(String host,
1443 InetAddress reqAddr,
1444 boolean check,
1445 boolean useCache)
1446 throws UnknownHostException {
1447
1448 /* If it gets here it is presumed to be a hostname */
1449
1450 /* make sure the connection to the host is allowed, before we
1451 * give out a hostname
1452 */
1453 if (check) {
1454 @SuppressWarnings("removal")
1455 SecurityManager security = System.getSecurityManager();
1456 if (security != null) {
1457 security.checkConnect(host, -1);
1458 }
1459 }
1460
1461 // remove expired addresses from cache - expirySet keeps them ordered
1462 // by expiry time so we only need to iterate the prefix of the NavigableSet...
1463 long now = System.nanoTime();
1481 // look-up or remove from cache
1482 Addresses addrs;
1483 if (useCache) {
1484 addrs = cache.get(host);
1485 } else {
1486 addrs = cache.remove(host);
1487 if (addrs != null) {
1488 if (addrs instanceof CachedAddresses) {
1489 // try removing from expirySet too if CachedAddresses
1490 expirySet.remove(addrs);
1491 }
1492 addrs = null;
1493 }
1494 }
1495
1496 if (addrs == null) {
1497 // create a NameServiceAddresses instance which will look up
1498 // the name service and install it within cache...
1499 Addresses oldAddrs = cache.putIfAbsent(
1500 host,
1501 addrs = new NameServiceAddresses(host, reqAddr)
1502 );
1503 if (oldAddrs != null) { // lost putIfAbsent race
1504 addrs = oldAddrs;
1505 }
1506 }
1507
1508 // ask Addresses to get an array of InetAddress(es) and clone it
1509 return addrs.get().clone();
1510 }
1511
1512 static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)
1513 throws UnknownHostException {
1514 InetAddress[] addresses = null;
1515 UnknownHostException ex = null;
1516
1517 try {
1518 addresses = nameService.lookupAllHostAddr(host);
1519 } catch (UnknownHostException uhe) {
1520 if (host.equalsIgnoreCase("localhost")) {
1521 addresses = new InetAddress[]{impl.loopbackAddress()};
1522 } else {
1523 ex = uhe;
1524 }
1525 }
1526
1527 if (addresses == null) {
1528 throw ex == null ? new UnknownHostException(host) : ex;
1529 }
1530
1531 // More to do?
1532 if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {
1533 // Find it?
1534 int i = 1;
1535 for (; i < addresses.length; i++) {
1536 if (addresses[i].equals(reqAddr)) {
1537 break;
1538 }
1539 }
1540 // Rotate
1541 if (i < addresses.length) {
1542 InetAddress tmp, tmp2 = reqAddr;
1543 for (int j = 0; j < i; j++) {
1544 tmp = addresses[j];
1545 addresses[j] = tmp2;
1546 tmp2 = tmp;
1547 }
1548 addresses[i] = tmp2;
1549 }
1550 }
1551
1552 return addresses;
1553 }
1554
1555 /**
1556 * Returns an {@code InetAddress} object given the raw IP address .
1557 * The argument is in network byte order: the highest order
1558 * byte of the address is in {@code getAddress()[0]}.
1559 *
1560 * <p> This method doesn't block, i.e. no reverse name service lookup
1561 * is performed.
1562 *
1563 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1564 * must be 16 bytes long
1565 *
1566 * @param addr the raw IP address in network byte order
1567 * @return an InetAddress object created from the raw IP address.
1568 * @throws UnknownHostException if IP address is of illegal length
1569 * @since 1.4
1570 */
1571 public static InetAddress getByAddress(byte[] addr)
1572 throws UnknownHostException {
1573 return getByAddress(null, addr);
1574 }
1575
1576 private static final class CachedLocalHost {
1577 final String host;
1578 final InetAddress addr;
1579 final long expiryTime = System.nanoTime() + 5000_000_000L; // now + 5s;
1580
1581 CachedLocalHost(String host, InetAddress addr) {
1620 if (security != null) {
1621 security.checkConnect(clh.host, -1);
1622 }
1623 return clh.addr;
1624 }
1625
1626 String local = impl.getLocalHostName();
1627
1628 if (security != null) {
1629 security.checkConnect(local, -1);
1630 }
1631
1632 InetAddress localAddr;
1633 if (local.equals("localhost")) {
1634 // shortcut for "localhost" host name
1635 localAddr = impl.loopbackAddress();
1636 } else {
1637 // call getAllByName0 without security checks and
1638 // without using cached data
1639 try {
1640 localAddr = getAllByName0(local, null, false, false)[0];
1641 } catch (UnknownHostException uhe) {
1642 // Rethrow with a more informative error message.
1643 UnknownHostException uhe2 =
1644 new UnknownHostException(local + ": " +
1645 uhe.getMessage());
1646 uhe2.initCause(uhe);
1647 throw uhe2;
1648 }
1649 }
1650 cachedLocalHost = new CachedLocalHost(local, localAddr);
1651 return localAddr;
1652 } catch (java.lang.SecurityException e) {
1653 return impl.loopbackAddress();
1654 }
1655 }
1656
1657 /**
1658 * Perform class load-time initializations.
1659 */
1660 private static native void init();
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.net;
27
28 import java.net.spi.InetAddressResolver;
29 import java.net.spi.InetAddressResolverProvider;
30 import java.net.spi.InetAddressResolver.LookupPolicy;
31 import java.security.AccessController;
32 import java.security.PrivilegedAction;
33 import java.util.List;
34 import java.util.NavigableSet;
35 import java.util.ArrayList;
36 import java.util.Objects;
37 import java.util.Scanner;
38 import java.io.File;
39 import java.io.ObjectStreamException;
40 import java.io.ObjectStreamField;
41 import java.io.IOException;
42 import java.io.InvalidObjectException;
43 import java.io.ObjectInputStream;
44 import java.io.ObjectInputStream.GetField;
45 import java.io.ObjectOutputStream;
46 import java.io.ObjectOutputStream.PutField;
47 import java.lang.annotation.Native;
48 import java.util.ServiceLoader;
49 import java.util.concurrent.ConcurrentHashMap;
50 import java.util.concurrent.ConcurrentMap;
51 import java.util.concurrent.ConcurrentSkipListSet;
52 import java.util.concurrent.atomic.AtomicLong;
53 import java.util.Arrays;
54 import java.util.concurrent.locks.ReentrantLock;
55 import java.util.stream.Stream;
56
57 import jdk.internal.misc.VM;
58
59 import jdk.internal.access.JavaNetInetAddressAccess;
60 import jdk.internal.access.SharedSecrets;
61 import sun.net.ResolverProviderConfiguration;
62 import sun.security.action.*;
63 import sun.net.InetAddressCachePolicy;
64 import sun.net.util.IPAddressUtil;
65 import sun.nio.cs.UTF_8;
66
67 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4;
68 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST;
69 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6;
70 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST;
71
72 /**
73 * This class represents an Internet Protocol (IP) address.
74 *
75 * <p> An IP address is either a 32-bit or 128-bit unsigned number
76 * used by IP, a lower-level protocol on which protocols like UDP and
77 * TCP are built. The IP address architecture is defined by <a
78 * href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC 790:
79 * Assigned Numbers</i></a>, <a
80 * href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC 1918:
81 * Address Allocation for Private Internets</i></a>, <a
82 * href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:
83 * Administratively Scoped IP Multicast</i></a>, and <a
84 * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP
85 * Version 6 Addressing Architecture</i></a>. An instance of an
86 * InetAddress consists of an IP address and possibly its
87 * corresponding host name (depending on whether it is constructed
88 * with a host name or whether it has already done reverse host name
89 * resolution).
90 *
91 * <h2> Address types </h2>
187 * <dl style="margin-left:2em">
188 * <dt><b>networkaddress.cache.ttl</b></dt>
189 * <dd>Indicates the caching policy for successful name lookups from
190 * the name service. The value is specified as an integer to indicate
191 * the number of seconds to cache the successful lookup. The default
192 * setting is to cache for an implementation specific period of time.
193 * <p>
194 * A value of -1 indicates "cache forever".
195 * </dd>
196 * <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>
197 * <dd>Indicates the caching policy for un-successful name lookups
198 * from the name service. The value is specified as an integer to
199 * indicate the number of seconds to cache the failure for
200 * un-successful lookups.
201 * <p>
202 * A value of 0 indicates "never cache".
203 * A value of -1 indicates "cache forever".
204 * </dd>
205 * </dl>
206 *
207 * <h3 id="resolverProviders"> InetAddress Resolver Providers </h3>
208 *
209 * <p> Host name resolution and reverse name resolution operations are delegated to a
210 * {@linkplain InetAddressResolver resolver}. Lookup operations performed by
211 * this class use the <i>system-wide resolver</i>. The system-wide resolver
212 * is set once, lazily, after the VM is fully initialized and when
213 * an invocation of a method in this class triggers the first lookup operation.
214 *
215 * <p> A <i>custom resolver</i> can be installed as the system-wide resolver
216 * by deploying a {@linkplain InetAddressResolverProvider resolver provider}.
217 * A resolver provider is essentially a factory for resolvers, and is used
218 * to instantiate a custom resolver. If no resolver provider
219 * is found, then the <i>built-in resolver</i> will be set as the
220 * system-wide resolver.
221 *
222 * <p> A custom resolver is found and installed as the system-wide resolver
223 * as follows:
224 * <ol>
225 * <li>The {@link ServiceLoader} mechanism is used to locate an
226 * {@link InetAddressResolverProvider InetAddressResolverProvider} using the
227 * system class loader. The order in which providers are located is
228 * {@linkplain ServiceLoader#load(java.lang.Class, java.lang.ClassLoader) implementation specific}.
229 * The first provider found will be used to instantiate the {@link InetAddressResolver InetAddressResolver}
230 * by invoking the {@link InetAddressResolverProvider#get(InetAddressResolverProvider.Configuration)}
231 * method. The instantiated {@code InetAddressResolver} will be installed as the system-wide
232 * resolver.
233 * <li>If the previous step fails to find any resolver provider the
234 * built-in resolver will be set as the system-wide resolver.
235 * </ol>
236 *
237 * <p> If instantiating a custom resolver from a provider discovered in
238 * step 1 throws an error or exception, the system-wide resolver will not be
239 * installed and the error or exception will be propagated to the calling thread.
240 * Otherwise, any lookup operation will be performed through the installed
241 * <i>system-wide resolver</i>.
242 * @implNote
243 * For any lookup operation that might occur before the VM is fully booted the <i>built-in
244 * resolver</i> will be used.
245 *
246 * @author Chris Warth
247 * @see java.net.InetAddress#getByAddress(byte[])
248 * @see java.net.InetAddress#getByAddress(java.lang.String, byte[])
249 * @see java.net.InetAddress#getAllByName(java.lang.String)
250 * @see java.net.InetAddress#getByName(java.lang.String)
251 * @see java.net.InetAddress#getLocalHost()
252 * @since 1.0
253 */
254 public class InetAddress implements java.io.Serializable {
255
256 /**
257 * Specify the address family: Internet Protocol, Version 4
258 * @since 1.4
259 */
260 @Native static final int IPv4 = 1;
261
262 /**
263 * Specify the address family: Internet Protocol, Version 6
264 * @since 1.4
265 */
266 @Native static final int IPv6 = 2;
267
268 static class InetAddressHolder {
269 /**
270 * Reserve the original application specified hostname.
271 *
272 * The original hostname is useful for domain-based endpoint
273 * identification (see RFC 2818 and RFC 6125). If an address
274 * was created with a raw IP address, a reverse name lookup
275 * may introduce endpoint identification security issue via
276 * DNS forging.
277 *
278 * Oracle JSSE provider is using this original hostname, via
279 * jdk.internal.misc.JavaNetAccess, for SSL/TLS endpoint identification.
280 *
281 * Note: May define a new public method in the future if necessary.
282 */
283 String originalHostName;
284
285 InetAddressHolder() {}
286
287 InetAddressHolder(String hostName, int address, int family) {
319 }
320
321 /**
322 * Specifies the address family type, for instance, '1' for IPv4
323 * addresses, and '2' for IPv6 addresses.
324 */
325 int family;
326
327 int getFamily() {
328 return family;
329 }
330 }
331
332 /* Used to store the serializable fields of InetAddress */
333 final transient InetAddressHolder holder;
334
335 InetAddressHolder holder() {
336 return holder;
337 }
338
339 /* Used to store the system-wide resolver */
340 private static volatile InetAddressResolver resolver;
341
342 private static final InetAddressResolver BUILTIN_RESOLVER;
343
344 /**
345 * Used to store the best available hostname.
346 * Lazily initialized via a data race; safe because Strings are immutable.
347 */
348 private transient String canonicalHostName = null;
349
350 /** use serialVersionUID from JDK 1.0.2 for interoperability */
351 @java.io.Serial
352 private static final long serialVersionUID = 3286316764910316507L;
353
354 // "java.net.preferIPv4Stack" system property value
355 private static final String PREFER_IPV4_STACK_VALUE;
356
357 // "java.net.preferIPv6Addresses" system property value
358 private static final String PREFER_IPV6_ADDRESSES_VALUE;
359
360 // "jdk.net.hosts.file" system property value
361 private static final String HOSTS_FILE_NAME;
362
363 /*
364 * Load net library into runtime, and perform initializations.
365 */
366 static {
367 PREFER_IPV4_STACK_VALUE =
368 GetPropertyAction.privilegedGetProperty("java.net.preferIPv4Stack");
369 PREFER_IPV6_ADDRESSES_VALUE =
370 GetPropertyAction.privilegedGetProperty("java.net.preferIPv6Addresses");
371 HOSTS_FILE_NAME =
372 GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file");
373 jdk.internal.loader.BootLoader.loadLibrary("net");
374 SharedSecrets.setJavaNetInetAddressAccess(
375 new JavaNetInetAddressAccess() {
376 public String getOriginalHostName(InetAddress ia) {
377 return ia.holder.getOriginalHostName();
378 }
379
380 public int addressValue(Inet4Address inet4Address) {
381 return inet4Address.addressValue();
382 }
383
384 public byte[] addressBytes(Inet6Address inet6Address) {
385 return inet6Address.addressBytes();
386 }
387 }
388 );
389 init();
390 }
391
392 /**
393 * Creates an address lookup policy from {@code "java.net.preferIPv4Stack"},
394 * {@code "java.net.preferIPv6Addresses"} system property values, and O/S configuration.
395 */
396 private static final LookupPolicy initializePlatformLookupPolicy() {
397 // Calculate AddressFamily value first
398 boolean ipv4Available = isIPv4Available();
399 if ("true".equals(PREFER_IPV4_STACK_VALUE) && ipv4Available) {
400 return LookupPolicy.of(IPV4);
401 }
402 // Check if IPv6 is not supported
403 if (InetAddress.impl instanceof Inet4AddressImpl) {
404 return LookupPolicy.of(IPV4);
405 }
406 // Check if system supports IPv4, if not use IPv6
407 if (!ipv4Available) {
408 return LookupPolicy.of(IPV6);
409 }
410 // If both address families are needed - check preferIPv6Addresses value
411 if (PREFER_IPV6_ADDRESSES_VALUE != null) {
412 if (PREFER_IPV6_ADDRESSES_VALUE.equalsIgnoreCase("true")) {
413 return LookupPolicy.of(IPV4 | IPV6 | IPV6_FIRST);
414 }
415 if (PREFER_IPV6_ADDRESSES_VALUE.equalsIgnoreCase("false")) {
416 return LookupPolicy.of(IPV4 | IPV6 | IPV4_FIRST);
417 }
418 if (PREFER_IPV6_ADDRESSES_VALUE.equalsIgnoreCase("system")) {
419 return LookupPolicy.of(IPV4 | IPV6);
420 }
421 }
422 // Default value with both address families needed - IPv4 addresses come first
423 return LookupPolicy.of(IPV4 | IPV6 | IPV4_FIRST);
424 }
425
426 static boolean systemAddressesOrder(int lookupCharacteristics) {
427 return (lookupCharacteristics & (IPV4_FIRST | IPV6_FIRST)) == 0;
428 }
429
430 static boolean ipv4AddressesFirst(int lookupCharacteristics) {
431 return (lookupCharacteristics & IPV4_FIRST) != 0;
432 }
433
434 static boolean ipv6AddressesFirst(int lookupCharacteristics) {
435 return (lookupCharacteristics & IPV6_FIRST) != 0;
436 }
437
438 // Native method to check if IPv4 is available
439 private static native boolean isIPv4Available();
440
441 /**
442 * The {@code RuntimePermission("inetAddressResolverProvider")} is
443 * necessary to subclass and instantiate the {@code InetAddressResolverProvider}
444 * class, as well as to obtain resolver from an instance of that class,
445 * and it is also required to obtain the operating system name resolution configurations.
446 */
447 private static final RuntimePermission INET_ADDRESS_RESOLVER_PERMISSION =
448 new RuntimePermission("inetAddressResolverProvider");
449
450 private static final ReentrantLock RESOLVER_LOCK = new ReentrantLock();
451 private static volatile InetAddressResolver bootstrapResolver;
452
453 @SuppressWarnings("removal")
454 private static InetAddressResolver resolver() {
455 InetAddressResolver cns = resolver;
456 if (cns != null) {
457 return cns;
458 }
459 if (VM.isBooted()) {
460 RESOLVER_LOCK.lock();
461 try {
462 cns = resolver;
463 if (cns != null) {
464 return cns;
465 }
466 // Protection against provider calling InetAddress APIs during initialization
467 if (bootstrapResolver != null) {
468 return bootstrapResolver;
469 } else {
470 bootstrapResolver = BUILTIN_RESOLVER;
471 }
472 if (HOSTS_FILE_NAME != null) {
473 // The default resolver service is already host file resolver
474 cns = BUILTIN_RESOLVER;
475 } else if (System.getSecurityManager() != null) {
476 PrivilegedAction<InetAddressResolver> pa = InetAddress::loadResolver;
477 cns = AccessController.doPrivileged(
478 pa, null, INET_ADDRESS_RESOLVER_PERMISSION);
479 } else {
480 cns = loadResolver();
481 }
482
483 InetAddress.resolver = cns;
484 return cns;
485 } finally {
486 bootstrapResolver = null;
487 RESOLVER_LOCK.unlock();
488 }
489 } else {
490 return BUILTIN_RESOLVER;
491 }
492 }
493
494 private static InetAddressResolver loadResolver() {
495 return ServiceLoader.load(InetAddressResolverProvider.class)
496 .findFirst()
497 .map(nsp -> nsp.get(builtinConfiguration()))
498 .orElse(BUILTIN_RESOLVER);
499 }
500
501 private static InetAddressResolverProvider.Configuration builtinConfiguration() {
502 return new ResolverProviderConfiguration(BUILTIN_RESOLVER, () -> {
503 try {
504 return impl.getLocalHostName();
505 } catch (UnknownHostException unknownHostException) {
506 return "localhost";
507 }
508 });
509 }
510
511 /**
512 * Constructor for the Socket.accept() method.
513 * This creates an empty InetAddress, which is filled in by
514 * the accept() method. This InetAddress, however, is not
515 * put in the address cache, since it is not created by name.
516 */
517 InetAddress() {
518 holder = new InetAddressHolder();
519 }
520
521 /**
522 * Replaces the de-serialized object with an Inet4Address object.
523 *
524 * @return the alternate object to the de-serialized object.
525 *
526 * @throws ObjectStreamException if a new object replacing this
527 * object could not be created
528 */
529 @java.io.Serial
530 private Object readResolve() throws ObjectStreamException {
703 * @throws IOException if a network error occurs
704 * @since 1.5
705 */
706 public boolean isReachable(NetworkInterface netif, int ttl,
707 int timeout) throws IOException {
708 if (ttl < 0)
709 throw new IllegalArgumentException("ttl can't be negative");
710 if (timeout < 0)
711 throw new IllegalArgumentException("timeout can't be negative");
712
713 return impl.isReachable(this, timeout, netif, ttl);
714 }
715
716 /**
717 * Gets the host name for this IP address.
718 *
719 * <p>If this InetAddress was created with a host name,
720 * this host name will be remembered and returned;
721 * otherwise, a reverse name lookup will be performed
722 * and the result will be returned based on the system
723 * configured resolver. If a lookup of the name service
724 * is required, call
725 * {@link #getCanonicalHostName() getCanonicalHostName}.
726 *
727 * <p>If there is a security manager, its
728 * {@code checkConnect} method is first called
729 * with the hostname and {@code -1}
730 * as its arguments to see if the operation is allowed.
731 * If the operation is not allowed, it will return
732 * the textual representation of the IP address.
733 *
734 * @return the host name for this IP address, or if the operation
735 * is not allowed by the security check, the textual
736 * representation of the IP address.
737 *
738 * @see InetAddress#getCanonicalHostName
739 * @see SecurityManager#checkConnect
740 */
741 public String getHostName() {
742 return getHostName(true);
743 }
804 /**
805 * Returns the hostname for this address.
806 *
807 * <p>If there is a security manager, this method first
808 * calls its {@code checkConnect} method
809 * with the hostname and {@code -1}
810 * as its arguments to see if the calling code is allowed to know
811 * the hostname for this IP address, i.e., to connect to the host.
812 * If the operation is not allowed, it will return
813 * the textual representation of the IP address.
814 *
815 * @return the host name for this IP address, or if the operation
816 * is not allowed by the security check, the textual
817 * representation of the IP address.
818 *
819 * @param check make security check if true
820 *
821 * @see SecurityManager#checkConnect
822 */
823 private static String getHostFromNameService(InetAddress addr, boolean check) {
824 String host;
825 var resolver = resolver();
826 try {
827 // first lookup the hostname
828 host = resolver.lookupHostName(addr.getAddress());
829
830 /* check to see if calling code is allowed to know
831 * the hostname for this IP address, ie, connect to the host
832 */
833 if (check) {
834 @SuppressWarnings("removal")
835 SecurityManager sec = System.getSecurityManager();
836 if (sec != null) {
837 sec.checkConnect(host, -1);
838 }
839 }
840
841 /* now get all the IP addresses for this hostname,
842 * and make sure one of them matches the original IP
843 * address. We do this to try and prevent spoofing.
844 */
845
846 InetAddress[] arr = InetAddress.getAllByName0(host, check);
847 boolean ok = false;
848
849 if (arr != null) {
850 for (int i = 0; !ok && i < arr.length; i++) {
851 ok = addr.equals(arr[i]);
852 }
853 }
854
855 //XXX: if it looks like a spoof just return the address?
856 if (!ok) {
857 host = addr.getHostAddress();
858 return host;
859 }
860 } catch (RuntimeException | UnknownHostException e) {
861 host = addr.getHostAddress();
862 }
863 return host;
864 }
865
866 /**
867 * Returns the raw IP address of this {@code InetAddress}
868 * object. The result is in network byte order: the highest order
869 * byte of the address is in {@code getAddress()[0]}.
870 *
871 * @return the raw IP address of this object.
872 */
873 public byte[] getAddress() {
874 return null;
875 }
876
877 /**
878 * Returns the IP address string in textual presentation.
879 *
880 * @return the raw IP address in a string format.
881 * @since 1.0.2
901 * <p>
902 * Two instances of {@code InetAddress} represent the same IP
903 * address if the length of the byte arrays returned by
904 * {@code getAddress} is the same for both, and each of the
905 * array components is the same for the byte arrays.
906 *
907 * @param obj the object to compare against.
908 * @return {@code true} if the objects are the same;
909 * {@code false} otherwise.
910 * @see java.net.InetAddress#getAddress()
911 */
912 public boolean equals(Object obj) {
913 return false;
914 }
915
916 /**
917 * Converts this IP address to a {@code String}. The
918 * string returned is of the form: hostname / literal IP
919 * address.
920 *
921 * If the host name is unresolved, no reverse lookup
922 * is performed. The hostname part will be represented
923 * by an empty string.
924 *
925 * @return a string representation of this IP address.
926 */
927 public String toString() {
928 String hostName = holder().getHostName();
929 return Objects.toString(hostName, "")
930 + "/" + getHostAddress();
931 }
932
933 // mapping from host name to Addresses - either NameServiceAddresses (while
934 // still being looked-up by NameService(s)) or CachedAddresses when cached
935 private static final ConcurrentMap<String, Addresses> cache =
936 new ConcurrentHashMap<>();
937
938 // CachedAddresses that have to expire are kept ordered in this NavigableSet
939 // which is scanned on each access
940 private static final NavigableSet<CachedAddresses> expirySet =
941 new ConcurrentSkipListSet<>();
942
943 // common interface
968 }
969
970 @Override
971 public int compareTo(CachedAddresses other) {
972 // natural order is expiry time -
973 // compare difference of expiry times rather than
974 // expiry times directly, to avoid possible overflow.
975 // (see System.nanoTime() recommendations...)
976 long diff = this.expiryTime - other.expiryTime;
977 if (diff < 0L) return -1;
978 if (diff > 0L) return 1;
979 // ties are broken using unique id
980 return Long.compare(this.id, other.id);
981 }
982 }
983
984 // a name service lookup based Addresses implementation which replaces itself
985 // in cache when the result is obtained
986 private static final class NameServiceAddresses implements Addresses {
987 private final String host;
988
989 NameServiceAddresses(String host) {
990 this.host = host;
991 }
992
993 @Override
994 public InetAddress[] get() throws UnknownHostException {
995 Addresses addresses;
996 // only one thread is doing lookup to name service
997 // for particular host at any time.
998 synchronized (this) {
999 // re-check that we are still us + re-install us if slot empty
1000 addresses = cache.putIfAbsent(host, this);
1001 if (addresses == null) {
1002 // this can happen when we were replaced by CachedAddresses in
1003 // some other thread, then CachedAddresses expired and were
1004 // removed from cache while we were waiting for lock...
1005 addresses = this;
1006 }
1007 // still us ?
1008 if (addresses == this) {
1009 // lookup name services
1010 InetAddress[] inetAddresses;
1011 UnknownHostException ex;
1012 int cachePolicy;
1013 try {
1014 inetAddresses = getAddressesFromNameService(host);
1015 ex = null;
1016 cachePolicy = InetAddressCachePolicy.get();
1017 } catch (UnknownHostException uhe) {
1018 inetAddresses = null;
1019 ex = uhe;
1020 cachePolicy = InetAddressCachePolicy.getNegative();
1021 }
1022 // remove or replace us with cached addresses according to cachePolicy
1023 if (cachePolicy == InetAddressCachePolicy.NEVER) {
1024 cache.remove(host, this);
1025 } else {
1026 CachedAddresses cachedAddresses = new CachedAddresses(
1027 host,
1028 inetAddresses,
1029 cachePolicy == InetAddressCachePolicy.FOREVER
1030 ? 0L
1031 // cachePolicy is in [s] - we need [ns]
1032 : System.nanoTime() + 1000_000_000L * cachePolicy
1033 );
1034 if (cache.replace(host, this, cachedAddresses) &&
1035 cachePolicy != InetAddressCachePolicy.FOREVER) {
1036 // schedule expiry
1037 expirySet.add(cachedAddresses);
1038 }
1039 }
1040 if (inetAddresses == null) {
1041 throw ex == null ? new UnknownHostException(host) : ex;
1042 }
1043 return inetAddresses;
1044 }
1045 // else addresses != this
1046 }
1047 // delegate to different addresses when we are already replaced
1048 // but outside of synchronized block to avoid any chance of dead-locking
1049 return addresses.get();
1050 }
1051 }
1052
1053 /**
1054 * The default InetAddressResolver implementation, which delegates to the underlying
1055 * OS network libraries to resolve host address mappings.
1056 *
1057 * @since 9
1058 */
1059 private static final class PlatformResolver implements InetAddressResolver {
1060
1061 public Stream<InetAddress> lookupAddresses(String host, LookupPolicy policy)
1062 throws UnknownHostException {
1063 Objects.requireNonNull(host);
1064 return Arrays.stream(impl.lookupAllHostAddr(host, policy));
1065 }
1066
1067 public String lookupHostName(byte[] addr)
1068 throws UnknownHostException {
1069 if (addr.length != Inet4Address.INADDRSZ && addr.length != Inet6Address.INADDRSZ) {
1070 throw new IllegalArgumentException("Invalid address length");
1071 }
1072 return impl.getHostByAddr(addr);
1073 }
1074 }
1075
1076 /**
1077 * The HostsFileResolver provides host address mapping
1078 * by reading the entries in a hosts file, which is specified by
1079 * {@code jdk.net.hosts.file} system property
1080 *
1081 * <p>The file format is that which corresponds with the /etc/hosts file
1082 * IP Address host alias list.
1083 *
1084 * <p>When the file lookup is enabled it replaces the default InetAddressResolver
1085 * implementation
1086 *
1087 * @since 9
1088 */
1089 private static final class HostsFileResolver implements InetAddressResolver {
1090
1091 private final String hostsFile;
1092
1093 public HostsFileResolver(String hostsFileName) {
1094 this.hostsFile = hostsFileName;
1095 }
1096
1097 /**
1098 * Lookup the host name corresponding to the IP address provided.
1099 * Search the configured host file a host name corresponding to
1100 * the specified IP address.
1101 *
1102 * @param addr byte array representing an IP address
1103 * @return {@code String} representing the host name mapping
1104 * @throws UnknownHostException if no host found for the specified IP address
1105 * @throws IllegalArgumentException if IP address is of illegal length
1106 */
1107 @Override
1108 public String lookupHostName(byte[] addr) throws UnknownHostException {
1109 String hostEntry;
1110 String host = null;
1111
1112 // Check the length of the address array
1113 if (addr.length != Inet4Address.INADDRSZ && addr.length != Inet6Address.INADDRSZ) {
1114 throw new IllegalArgumentException("Invalid address length");
1115 }
1116
1117 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
1118 UTF_8.INSTANCE)) {
1119 while (hostsFileScanner.hasNextLine()) {
1120 hostEntry = hostsFileScanner.nextLine();
1121 if (!hostEntry.startsWith("#")) {
1122 hostEntry = removeComments(hostEntry);
1123 String[] mapping = hostEntry.split("\\s+");
1124 if (mapping.length >= 2 &&
1125 Arrays.equals(addr, createAddressByteArray(mapping[0]))) {
1126 host = mapping[1];
1127 break;
1128 }
1129 }
1130 }
1131 } catch (IOException e) {
1132 throw new UnknownHostException("Unable to resolve address "
1133 + Arrays.toString(addr) + " as hosts file " + hostsFile
1134 + " not found ");
1135 }
1136
1137 if ((host == null) || (host.isEmpty()) || (host.equals(" "))) {
1138 throw new UnknownHostException("Requested address "
1139 + Arrays.toString(addr)
1140 + " resolves to an invalid entry in hosts file "
1141 + hostsFile);
1142 }
1143 return host;
1144 }
1145
1146 /**
1147 * <p>Lookup a host mapping by name. Retrieve the IP addresses
1148 * associated with a host.
1149 *
1150 * <p>Search the configured hosts file for the addresses associated
1151 * with the specified host name.
1152 *
1153 * @param host the specified hostname
1154 * @param lookupPolicy IP addresses lookup policy which specifies addresses
1155 * family and their order
1156 * @return stream of IP addresses for the requested host
1157 * @throws UnknownHostException
1158 * if no IP address for the {@code host} could be found
1159 */
1160 public Stream<InetAddress> lookupAddresses(String host, LookupPolicy lookupPolicy)
1161 throws UnknownHostException {
1162 String hostEntry;
1163 String addrStr;
1164 byte addr[];
1165 List<InetAddress> inetAddresses = new ArrayList<>();
1166 List<InetAddress> inet4Addresses = new ArrayList<>();
1167 List<InetAddress> inet6Addresses = new ArrayList<>();
1168 int flags = lookupPolicy.characteristics();
1169 boolean needIPv4 = (flags & IPv4) != 0;
1170 boolean needIPv6 = (flags & IPv6) != 0;
1171
1172 Objects.requireNonNull(host);
1173
1174 // lookup the file and create a list InetAddress for the specified host
1175 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
1176 UTF_8.INSTANCE)) {
1177 while (hostsFileScanner.hasNextLine()) {
1178 hostEntry = hostsFileScanner.nextLine();
1179 if (!hostEntry.startsWith("#")) {
1180 hostEntry = removeComments(hostEntry);
1181 if (hostEntry.contains(host)) {
1182 addrStr = extractHostAddr(hostEntry, host);
1183 if ((addrStr != null) && (!addrStr.isEmpty())) {
1184 addr = createAddressByteArray(addrStr);
1185 if (addr != null) {
1186 InetAddress address = InetAddress.getByAddress(host, addr);
1187 inetAddresses.add(address);
1188 if (address instanceof Inet4Address && needIPv4) {
1189 inet4Addresses.add(address);
1190 }
1191 if (address instanceof Inet6Address && needIPv6) {
1192 inet6Addresses.add(address);
1193 }
1194 }
1195 }
1196 }
1197 }
1198 }
1199 } catch (IOException e) {
1200 throw new UnknownHostException("Unable to resolve host " + host
1201 + " as hosts file " + hostsFile + " not found ");
1202 }
1203 // Check number of found addresses:
1204 // If none found - throw an exception
1205 boolean noAddressFound = inetAddresses.isEmpty();
1206 // needIPv4 == false and needIPv6 is not a valid combination. See LookupPolicy.of.
1207 if (needIPv4 != needIPv6) {
1208 if (needIPv4) {
1209 noAddressFound = inet4Addresses.isEmpty();
1210 } else {
1211 noAddressFound = inet6Addresses.isEmpty();
1212 }
1213 }
1214 if (noAddressFound) {
1215 throw new UnknownHostException("Unable to resolve host " + host
1216 + " in hosts file " + hostsFile);
1217 }
1218
1219 // If both address types are requested
1220 if (needIPv4 == needIPv6) {
1221 if (systemAddressesOrder(flags)) {
1222 return inetAddresses.stream();
1223 } else if (ipv6AddressesFirst(flags)) {
1224 return Stream.concat(inet6Addresses.stream(), inet4Addresses.stream());
1225 } else if (ipv4AddressesFirst(flags)) {
1226 return Stream.concat(inet4Addresses.stream(), inet6Addresses.stream());
1227 }
1228 }
1229 // Only IPv4 addresses are requested
1230 if (needIPv4) {
1231 return inet4Addresses.stream();
1232 }
1233 // Only IPv6 addresses are requested
1234 return inet6Addresses.stream();
1235 }
1236
1237 private String removeComments(String hostsEntry) {
1238 String filteredEntry = hostsEntry;
1239 int hashIndex;
1240
1241 if ((hashIndex = hostsEntry.indexOf("#")) != -1) {
1242 filteredEntry = hostsEntry.substring(0, hashIndex);
1243 }
1244 return filteredEntry;
1245 }
1246
1247 private byte [] createAddressByteArray(String addrStr) {
1248 byte[] addrArray;
1249 // check if IPV4 address - most likely
1250 addrArray = IPAddressUtil.textToNumericFormatV4(addrStr);
1251 if (addrArray == null) {
1252 addrArray = IPAddressUtil.textToNumericFormatV6(addrStr);
1253 }
1254 return addrArray;
1256
1257 /** host to ip address mapping */
1258 private String extractHostAddr(String hostEntry, String host) {
1259 String[] mapping = hostEntry.split("\\s+");
1260 String hostAddr = null;
1261
1262 if (mapping.length >= 2) {
1263 // look at the host aliases
1264 for (int i = 1; i < mapping.length; i++) {
1265 if (mapping[i].equalsIgnoreCase(host)) {
1266 hostAddr = mapping[0];
1267 }
1268 }
1269 }
1270 return hostAddr;
1271 }
1272 }
1273
1274 static final InetAddressImpl impl;
1275
1276 /**
1277 * Platform-wide {@code LookupPolicy} initialized from {@code "java.net.preferIPv4Stack"},
1278 * {@code "java.net.preferIPv6Addresses"} system properties.
1279 */
1280 static final LookupPolicy PLATFORM_LOOKUP_POLICY;
1281
1282 static {
1283 // create the impl
1284 impl = InetAddressImplFactory.create();
1285
1286 // impl must be initialized before calling this method
1287 PLATFORM_LOOKUP_POLICY = initializePlatformLookupPolicy();
1288
1289 // create built-in resolver
1290 BUILTIN_RESOLVER = createBuiltinInetAddressResolver();
1291 }
1292
1293 /**
1294 * Create an instance of the InetAddressResolver interface based on
1295 * the setting of the {@code jdk.net.hosts.file} system property.
1296 *
1297 * <p>The default InetAddressResolver is the PlatformResolver, which typically
1298 * delegates name and address resolution calls to the underlying
1299 * OS network libraries.
1300 *
1301 * <p> A HostsFileResolver is created if the {@code jdk.net.hosts.file}
1302 * system property is set. If the specified file doesn't exist, the name or
1303 * address lookup will result in an UnknownHostException. Thus, non existent
1304 * hosts file is handled as if the file is empty.
1305 *
1306 * @return an InetAddressResolver
1307 */
1308 private static InetAddressResolver createBuiltinInetAddressResolver() {
1309 InetAddressResolver theResolver;
1310 if (HOSTS_FILE_NAME != null) {
1311 theResolver = new HostsFileResolver(HOSTS_FILE_NAME);
1312 } else {
1313 theResolver = new PlatformResolver();
1314 }
1315 return theResolver;
1316 }
1317
1318 /**
1319 * Creates an InetAddress based on the provided host name and IP address.
1320 * System {@linkplain InetAddressResolver resolver} is not used to check
1321 * the validity of the address.
1322 *
1323 * <p> The host name can either be a machine name, such as
1324 * "{@code www.example.com}", or a textual representation of its IP
1325 * address.
1326 * <p> No validity checking is done on the host name either.
1327 *
1328 * <p> If addr specifies an IPv4 address an instance of Inet4Address
1329 * will be returned; otherwise, an instance of Inet6Address
1330 * will be returned.
1331 *
1332 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1333 * must be 16 bytes long
1334 *
1335 * @param host the specified host
1336 * @param addr the raw IP address in network byte order
1337 * @return an InetAddress object created from the raw IP address.
1338 * @throws UnknownHostException if IP address is of illegal length
1339 * @since 1.4
1340 */
1341 public static InetAddress getByAddress(String host, byte[] addr)
1384 * section 2.5.3.
1385 *
1386 * <p> If there is a security manager, and {@code host} is not {@code null}
1387 * or {@code host.length() } is not equal to zero, the security manager's
1388 * {@code checkConnect} method is called with the hostname and {@code -1}
1389 * as its arguments to determine if the operation is allowed.
1390 *
1391 * @param host the specified host, or {@code null}.
1392 * @return an IP address for the given host name.
1393 * @throws UnknownHostException if no IP address for the
1394 * {@code host} could be found, or if a scope_id was specified
1395 * for a global IPv6 address.
1396 * @throws SecurityException if a security manager exists
1397 * and its checkConnect method doesn't allow the operation
1398 */
1399 public static InetAddress getByName(String host)
1400 throws UnknownHostException {
1401 return InetAddress.getAllByName(host)[0];
1402 }
1403
1404 /**
1405 * Given the name of a host, returns an array of its IP addresses,
1406 * based on the configured system {@linkplain InetAddressResolver resolver}.
1407 *
1408 * <p> The host name can either be a machine name, such as
1409 * "{@code www.example.com}", or a textual representation of its IP
1410 * address. If a literal IP address is supplied, only the
1411 * validity of the address format is checked.
1412 *
1413 * <p> For {@code host} specified in <i>literal IPv6 address</i>,
1414 * either the form defined in RFC 2732 or the literal IPv6 address
1415 * format defined in RFC 2373 is accepted. A literal IPv6 address may
1416 * also be qualified by appending a scoped zone identifier or scope_id.
1417 * The syntax and usage of scope_ids is described
1418 * <a href="Inet6Address.html#scoped">here</a>.
1419 *
1420 * <p> If the host is {@code null} or {@code host.length()} is equal
1421 * to zero, then an {@code InetAddress} representing an address of the
1422 * loopback interface is returned.
1423 * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
1424 * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
1425 * section 2.5.3. </p>
1426 *
1427 * <p> If there is a security manager, and {@code host} is not {@code null}
1428 * or {@code host.length() } is not equal to zero, the security manager's
1429 * {@code checkConnect} method is called with the hostname and {@code -1}
1430 * as its arguments to determine if the operation is allowed.
1431 *
1432 * @param host the name of the host, or {@code null}.
1433 * @return an array of all the IP addresses for a given host name.
1434 *
1435 * @throws UnknownHostException if no IP address for the
1436 * {@code host} could be found, or if a scope_id was specified
1437 * for a global IPv6 address.
1438 * @throws SecurityException if a security manager exists and its
1439 * {@code checkConnect} method doesn't allow the operation.
1440 *
1441 * @see SecurityManager#checkConnect
1442 */
1443 public static InetAddress[] getAllByName(String host)
1444 throws UnknownHostException {
1445
1446 if (host == null || host.isEmpty()) {
1447 InetAddress[] ret = new InetAddress[1];
1448 ret[0] = impl.loopbackAddress();
1449 return ret;
1450 }
1451
1452 boolean ipv6Expected = false;
1453 if (host.charAt(0) == '[') {
1454 // This is supposed to be an IPv6 literal
1455 if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
1456 host = host.substring(1, host.length() -1);
1457 ipv6Expected = true;
1458 } else {
1459 // This was supposed to be a IPv6 address, but it's not!
1460 throw new UnknownHostException(host + ": invalid IPv6 address");
1461 }
1462 }
1463
1464 // if host is an IP address, we won't do further lookup
1486 // Means an IPv4 literal between brackets!
1487 throw new UnknownHostException("["+host+"]");
1488 }
1489 InetAddress[] ret = new InetAddress[1];
1490 if(addr != null) {
1491 if (addr.length == Inet4Address.INADDRSZ) {
1492 ret[0] = new Inet4Address(null, addr);
1493 } else {
1494 if (ifname != null) {
1495 ret[0] = new Inet6Address(null, addr, ifname);
1496 } else {
1497 ret[0] = new Inet6Address(null, addr, numericZone);
1498 }
1499 }
1500 return ret;
1501 }
1502 } else if (ipv6Expected) {
1503 // We were expecting an IPv6 Literal, but got something else
1504 throw new UnknownHostException("["+host+"]");
1505 }
1506 return getAllByName0(host, true, true);
1507 }
1508
1509 /**
1510 * Returns the loopback address.
1511 * <p>
1512 * The InetAddress returned will represent the IPv4
1513 * loopback address, 127.0.0.1, or the IPv6 loopback
1514 * address, ::1. The IPv4 loopback address returned
1515 * is only one of many in the form 127.*.*.*
1516 *
1517 * @return the InetAddress loopback instance.
1518 * @since 1.7
1519 */
1520 public static InetAddress getLoopbackAddress() {
1521 return impl.loopbackAddress();
1522 }
1523
1524
1525 /**
1526 * check if the literal address string has %nn appended
1536 if (percent == -1) {
1537 return -1;
1538 }
1539 for (int i=percent+1; i<slen; i++) {
1540 char c = s.charAt(i);
1541 if (c == ']') {
1542 if (i == percent+1) {
1543 /* empty per-cent field */
1544 return -1;
1545 }
1546 break;
1547 }
1548 if ((digit = Character.digit (c, 10)) < 0) {
1549 return -1;
1550 }
1551 zone = (zone * 10) + digit;
1552 }
1553 return zone;
1554 }
1555
1556 /**
1557 * package private so SocketPermission can call it
1558 */
1559 static InetAddress[] getAllByName0 (String host, boolean check)
1560 throws UnknownHostException {
1561 return getAllByName0(host, check, true);
1562 }
1563
1564 /**
1565 * Designated lookup method.
1566 *
1567 * @param host host name to look up
1568 * @param check perform security check
1569 * @param useCache use cached value if not expired else always
1570 * perform name service lookup (and cache the result)
1571 * @return array of InetAddress(es)
1572 * @throws UnknownHostException if host name is not found
1573 */
1574 private static InetAddress[] getAllByName0(String host,
1575 boolean check,
1576 boolean useCache)
1577 throws UnknownHostException {
1578
1579 /* If it gets here it is presumed to be a hostname */
1580
1581 /* make sure the connection to the host is allowed, before we
1582 * give out a hostname
1583 */
1584 if (check) {
1585 @SuppressWarnings("removal")
1586 SecurityManager security = System.getSecurityManager();
1587 if (security != null) {
1588 security.checkConnect(host, -1);
1589 }
1590 }
1591
1592 // remove expired addresses from cache - expirySet keeps them ordered
1593 // by expiry time so we only need to iterate the prefix of the NavigableSet...
1594 long now = System.nanoTime();
1612 // look-up or remove from cache
1613 Addresses addrs;
1614 if (useCache) {
1615 addrs = cache.get(host);
1616 } else {
1617 addrs = cache.remove(host);
1618 if (addrs != null) {
1619 if (addrs instanceof CachedAddresses) {
1620 // try removing from expirySet too if CachedAddresses
1621 expirySet.remove(addrs);
1622 }
1623 addrs = null;
1624 }
1625 }
1626
1627 if (addrs == null) {
1628 // create a NameServiceAddresses instance which will look up
1629 // the name service and install it within cache...
1630 Addresses oldAddrs = cache.putIfAbsent(
1631 host,
1632 addrs = new NameServiceAddresses(host)
1633 );
1634 if (oldAddrs != null) { // lost putIfAbsent race
1635 addrs = oldAddrs;
1636 }
1637 }
1638
1639 // ask Addresses to get an array of InetAddress(es) and clone it
1640 return addrs.get().clone();
1641 }
1642
1643 static InetAddress[] getAddressesFromNameService(String host)
1644 throws UnknownHostException {
1645 Stream<InetAddress> addresses = null;
1646 UnknownHostException ex = null;
1647
1648 var resolver = resolver();
1649 try {
1650 addresses = resolver.lookupAddresses(host, PLATFORM_LOOKUP_POLICY);
1651 } catch (RuntimeException | UnknownHostException x) {
1652 if (host.equalsIgnoreCase("localhost")) {
1653 addresses = Stream.of(impl.loopbackAddress());
1654 } else if (x instanceof UnknownHostException uhe) {
1655 ex = uhe;
1656 } else {
1657 ex = new UnknownHostException();
1658 ex.initCause(x);
1659 }
1660 }
1661
1662 if (addresses == null) {
1663 throw ex == null ? new UnknownHostException(host) : ex;
1664 }
1665 return addresses.toArray(InetAddress[]::new);
1666 }
1667
1668 /**
1669 * Returns an {@code InetAddress} object given the raw IP address .
1670 * The argument is in network byte order: the highest order
1671 * byte of the address is in {@code getAddress()[0]}.
1672 *
1673 * <p> This method doesn't block, i.e. no reverse lookup is performed.
1674 *
1675 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1676 * must be 16 bytes long
1677 *
1678 * @param addr the raw IP address in network byte order
1679 * @return an InetAddress object created from the raw IP address.
1680 * @throws UnknownHostException if IP address is of illegal length
1681 * @since 1.4
1682 */
1683 public static InetAddress getByAddress(byte[] addr)
1684 throws UnknownHostException {
1685 return getByAddress(null, addr);
1686 }
1687
1688 private static final class CachedLocalHost {
1689 final String host;
1690 final InetAddress addr;
1691 final long expiryTime = System.nanoTime() + 5000_000_000L; // now + 5s;
1692
1693 CachedLocalHost(String host, InetAddress addr) {
1732 if (security != null) {
1733 security.checkConnect(clh.host, -1);
1734 }
1735 return clh.addr;
1736 }
1737
1738 String local = impl.getLocalHostName();
1739
1740 if (security != null) {
1741 security.checkConnect(local, -1);
1742 }
1743
1744 InetAddress localAddr;
1745 if (local.equals("localhost")) {
1746 // shortcut for "localhost" host name
1747 localAddr = impl.loopbackAddress();
1748 } else {
1749 // call getAllByName0 without security checks and
1750 // without using cached data
1751 try {
1752 localAddr = getAllByName0(local, false, false)[0];
1753 } catch (UnknownHostException uhe) {
1754 // Rethrow with a more informative error message.
1755 UnknownHostException uhe2 =
1756 new UnknownHostException(local + ": " +
1757 uhe.getMessage());
1758 uhe2.initCause(uhe);
1759 throw uhe2;
1760 }
1761 }
1762 cachedLocalHost = new CachedLocalHost(local, localAddr);
1763 return localAddr;
1764 } catch (java.lang.SecurityException e) {
1765 return impl.loopbackAddress();
1766 }
1767 }
1768
1769 /**
1770 * Perform class load-time initializations.
1771 */
1772 private static native void init();
|