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>
111 * <p> <i>Link-local</i> addresses are designed to be used for addressing
112 * on a single link for purposes such as auto-address configuration,
113 * neighbor discovery, or when no routers are present.
114 *
115 * <p> <i>Site-local</i> addresses are designed to be used for addressing
116 * inside of a site without the need for a global prefix.
117 *
118 * <p> <i>Global</i> addresses are unique across the internet.
119 *
120 * <h3> Textual representation of IP addresses </h3>
121 *
122 * The textual representation of an IP address is address family specific.
123 *
124 * <p>
125 *
126 * For IPv4 address format, please refer to <A
127 * HREF="Inet4Address.html#format">Inet4Address#format</A>; For IPv6
128 * address format, please refer to <A
129 * HREF="Inet6Address.html#format">Inet6Address#format</A>.
130 *
131 * <P>There is a <a href="doc-files/net-properties.html#Ipv4IPv6">couple of
132 * System Properties</a> affecting how IPv4 and IPv6 addresses are used.</P>
133 *
134 * <h3> Host Name Resolution </h3>
135 *
136 * Host name-to-IP address <i>resolution</i> is accomplished through
137 * the use of a combination of local machine configuration information
138 * and network naming services such as the Domain Name System (DNS)
139 * and Network Information Service(NIS). The particular naming
140 * services(s) being used is by default the local machine configured
141 * one. For any host name, its corresponding IP address is returned.
142 *
143 * <p> <i>Reverse name resolution</i> means that for any IP address,
144 * the host associated with the IP address is returned.
145 *
146 * <p> The InetAddress class provides methods to resolve host names to
147 * their IP addresses and vice versa.
148 *
149 * <h3> InetAddress Caching </h3>
150 *
151 * The InetAddress class has a cache to store successful as well as
152 * unsuccessful host name resolutions.
153 *
154 * <p> By default, when a security manager is installed, in order to
155 * protect against DNS spoofing attacks,
156 * the result of positive host name resolutions are
157 * cached forever. When a security manager is not installed, the default
158 * behavior is to cache entries for a finite (implementation dependent)
159 * period of time. The result of unsuccessful host
160 * name resolution is cached for a very short period of time (10
161 * seconds) to improve performance.
162 *
163 * <p> If the default behavior is not desired, then a Java security property
164 * can be set to a different Time-to-live (TTL) value for positive
165 * caching. Likewise, a system admin can configure a different
166 * negative caching TTL value when needed.
167 *
168 * <p> Two Java security properties control the TTL values used for
169 * positive and negative host name resolution caching:
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 jdk.internal.vm.annotation.Stable;
62 import sun.net.ResolverProviderConfiguration;
63 import sun.security.action.*;
64 import sun.net.InetAddressCachePolicy;
65 import sun.net.util.IPAddressUtil;
66 import sun.nio.cs.UTF_8;
67
68 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4;
69 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST;
70 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6;
71 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST;
72
73 /**
74 * This class represents an Internet Protocol (IP) address.
75 *
76 * <p> An IP address is either a 32-bit or 128-bit unsigned number
77 * used by IP, a lower-level protocol on which protocols like UDP and
78 * TCP are built. The IP address architecture is defined by <a
79 * href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC 790:
80 * Assigned Numbers</i></a>, <a
81 * href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC 1918:
82 * Address Allocation for Private Internets</i></a>, <a
83 * href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:
84 * Administratively Scoped IP Multicast</i></a>, and <a
85 * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP
86 * Version 6 Addressing Architecture</i></a>. An instance of an
87 * InetAddress consists of an IP address and possibly its
88 * corresponding host name (depending on whether it is constructed
89 * with a host name or whether it has already done reverse host name
90 * resolution).
91 *
92 * <h2> Address types </h2>
128 * <p> <i>Link-local</i> addresses are designed to be used for addressing
129 * on a single link for purposes such as auto-address configuration,
130 * neighbor discovery, or when no routers are present.
131 *
132 * <p> <i>Site-local</i> addresses are designed to be used for addressing
133 * inside of a site without the need for a global prefix.
134 *
135 * <p> <i>Global</i> addresses are unique across the internet.
136 *
137 * <h3> Textual representation of IP addresses </h3>
138 *
139 * The textual representation of an IP address is address family specific.
140 *
141 * <p>
142 *
143 * For IPv4 address format, please refer to <A
144 * HREF="Inet4Address.html#format">Inet4Address#format</A>; For IPv6
145 * address format, please refer to <A
146 * HREF="Inet6Address.html#format">Inet6Address#format</A>.
147 *
148 * <p> There is a <a href="doc-files/net-properties.html#Ipv4IPv6">couple of
149 * System Properties</a> affecting how IPv4 and IPv6 addresses are used.
150 *
151 * <h2 id="host-name-resolution"> Host Name Resolution </h2>
152 *
153 * <p> The InetAddress class provides methods to resolve host names to
154 * their IP addresses and vice versa. The actual resolution is delegated to an
155 * {@linkplain InetAddressResolver InetAddress resolver}.
156 *
157 * <p> <i>Host name-to-IP address resolution</i> maps a host name to an IP address.
158 * For any host name, its corresponding IP address is returned.
159 *
160 * <p> <i>Reverse name resolution</i> means that for any IP address,
161 * the host associated with the IP address is returned.
162 *
163 * <p id="built-in-resolver"> The built-in InetAddress resolver implementation does
164 * host name-to-IP address resolution and vice versa through the use of
165 * a combination of local machine configuration information and network
166 * naming services such as the Domain Name System (DNS) and the Lightweight Directory
167 * Access Protocol (LDAP).
168 * The particular naming services that the built-in resolver uses by default
169 * depends on the configuration of the local machine.
170 *
171 * <p> {@code InetAddress} has a service provider mechanism for InetAddress resolvers
172 * that allows a custom InetAddress resolver to be used instead of the built-in implementation.
173 * {@link InetAddressResolverProvider} is the service provider class. Its API docs provide all the
174 * details on this mechanism.
175 *
176 * <h2> InetAddress Caching </h2>
177 *
178 * The InetAddress class has a cache to store successful as well as
179 * unsuccessful host name resolutions.
180 *
181 * <p> By default, when a security manager is installed, in order to
182 * protect against DNS spoofing attacks,
183 * the result of positive host name resolutions are
184 * cached forever. When a security manager is not installed, the default
185 * behavior is to cache entries for a finite (implementation dependent)
186 * period of time. The result of unsuccessful host
187 * name resolution is cached for a very short period of time (10
188 * seconds) to improve performance.
189 *
190 * <p> If the default behavior is not desired, then a Java security property
191 * can be set to a different Time-to-live (TTL) value for positive
192 * caching. Likewise, a system admin can configure a different
193 * negative caching TTL value when needed.
194 *
195 * <p> Two Java security properties control the TTL values used for
196 * positive and negative host name resolution caching:
208 * <dd>Indicates the caching policy for un-successful name lookups
209 * from the name service. The value is specified as an integer to
210 * indicate the number of seconds to cache the failure for
211 * un-successful lookups.
212 * <p>
213 * A value of 0 indicates "never cache".
214 * A value of -1 indicates "cache forever".
215 * </dd>
216 * </dl>
217 *
218 * @author Chris Warth
219 * @see java.net.InetAddress#getByAddress(byte[])
220 * @see java.net.InetAddress#getByAddress(java.lang.String, byte[])
221 * @see java.net.InetAddress#getAllByName(java.lang.String)
222 * @see java.net.InetAddress#getByName(java.lang.String)
223 * @see java.net.InetAddress#getLocalHost()
224 * @since 1.0
225 */
226 public class InetAddress implements java.io.Serializable {
227
228 /**
229 * Specify the address family: Internet Protocol, Version 4
230 * @since 1.4
231 */
232 @Native static final int IPv4 = 1;
233
234 /**
235 * Specify the address family: Internet Protocol, Version 6
236 * @since 1.4
237 */
238 @Native static final int IPv6 = 2;
239
240 static class InetAddressHolder {
241 /**
242 * Reserve the original application specified hostname.
243 *
244 * The original hostname is useful for domain-based endpoint
245 * identification (see RFC 2818 and RFC 6125). If an address
246 * was created with a raw IP address, a reverse name lookup
247 * may introduce endpoint identification security issue via
248 * DNS forging.
249 *
250 * Oracle JSSE provider is using this original hostname, via
251 * jdk.internal.misc.JavaNetAccess, for SSL/TLS endpoint identification.
252 *
253 * Note: May define a new public method in the future if necessary.
254 */
255 String originalHostName;
256
257 InetAddressHolder() {}
258
259 InetAddressHolder(String hostName, int address, int family) {
291 }
292
293 /**
294 * Specifies the address family type, for instance, '1' for IPv4
295 * addresses, and '2' for IPv6 addresses.
296 */
297 int family;
298
299 int getFamily() {
300 return family;
301 }
302 }
303
304 /* Used to store the serializable fields of InetAddress */
305 final transient InetAddressHolder holder;
306
307 InetAddressHolder holder() {
308 return holder;
309 }
310
311 /* Used to store the system-wide resolver */
312 @Stable
313 private static volatile InetAddressResolver resolver;
314
315 private static final InetAddressResolver BUILTIN_RESOLVER;
316
317 /**
318 * Used to store the best available hostname.
319 * Lazily initialized via a data race; safe because Strings are immutable.
320 */
321 private transient String canonicalHostName = null;
322
323 /** use serialVersionUID from JDK 1.0.2 for interoperability */
324 @java.io.Serial
325 private static final long serialVersionUID = 3286316764910316507L;
326
327 // "java.net.preferIPv4Stack" system property value
328 private static final String PREFER_IPV4_STACK_VALUE;
329
330 // "java.net.preferIPv6Addresses" system property value
331 private static final String PREFER_IPV6_ADDRESSES_VALUE;
332
333 // "jdk.net.hosts.file" system property value
334 private static final String HOSTS_FILE_NAME;
335
336 /*
337 * Load net library into runtime, and perform initializations.
338 */
339 static {
340 PREFER_IPV4_STACK_VALUE =
341 GetPropertyAction.privilegedGetProperty("java.net.preferIPv4Stack");
342 PREFER_IPV6_ADDRESSES_VALUE =
343 GetPropertyAction.privilegedGetProperty("java.net.preferIPv6Addresses");
344 HOSTS_FILE_NAME =
345 GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file");
346 jdk.internal.loader.BootLoader.loadLibrary("net");
347 SharedSecrets.setJavaNetInetAddressAccess(
348 new JavaNetInetAddressAccess() {
349 public String getOriginalHostName(InetAddress ia) {
350 return ia.holder.getOriginalHostName();
351 }
352
353 public int addressValue(Inet4Address inet4Address) {
354 return inet4Address.addressValue();
355 }
356
357 public byte[] addressBytes(Inet6Address inet6Address) {
358 return inet6Address.addressBytes();
359 }
360 }
361 );
362 init();
363 }
364
365 /**
366 * Creates an address lookup policy from {@code "java.net.preferIPv4Stack"},
367 * {@code "java.net.preferIPv6Addresses"} system property values, and O/S configuration.
368 */
369 private static final LookupPolicy initializePlatformLookupPolicy() {
370 // Calculate AddressFamily value first
371 boolean ipv4Available = isIPv4Available();
372 if ("true".equals(PREFER_IPV4_STACK_VALUE) && ipv4Available) {
373 return LookupPolicy.of(IPV4);
374 }
375 // Check if IPv6 is not supported
376 if (InetAddress.impl instanceof Inet4AddressImpl) {
377 return LookupPolicy.of(IPV4);
378 }
379 // Check if system supports IPv4, if not use IPv6
380 if (!ipv4Available) {
381 return LookupPolicy.of(IPV6);
382 }
383 // If both address families are needed - check preferIPv6Addresses value
384 if (PREFER_IPV6_ADDRESSES_VALUE != null) {
385 if (PREFER_IPV6_ADDRESSES_VALUE.equalsIgnoreCase("true")) {
386 return LookupPolicy.of(IPV4 | IPV6 | IPV6_FIRST);
387 }
388 if (PREFER_IPV6_ADDRESSES_VALUE.equalsIgnoreCase("false")) {
389 return LookupPolicy.of(IPV4 | IPV6 | IPV4_FIRST);
390 }
391 if (PREFER_IPV6_ADDRESSES_VALUE.equalsIgnoreCase("system")) {
392 return LookupPolicy.of(IPV4 | IPV6);
393 }
394 }
395 // Default value with both address families needed - IPv4 addresses come first
396 return LookupPolicy.of(IPV4 | IPV6 | IPV4_FIRST);
397 }
398
399 static boolean systemAddressesOrder(int lookupCharacteristics) {
400 return (lookupCharacteristics & (IPV4_FIRST | IPV6_FIRST)) == 0;
401 }
402
403 static boolean ipv4AddressesFirst(int lookupCharacteristics) {
404 return (lookupCharacteristics & IPV4_FIRST) != 0;
405 }
406
407 static boolean ipv6AddressesFirst(int lookupCharacteristics) {
408 return (lookupCharacteristics & IPV6_FIRST) != 0;
409 }
410
411 // Native method to check if IPv4 is available
412 private static native boolean isIPv4Available();
413
414 /**
415 * The {@code RuntimePermission("inetAddressResolverProvider")} is
416 * necessary to subclass and instantiate the {@code InetAddressResolverProvider}
417 * class, as well as to obtain resolver from an instance of that class,
418 * and it is also required to obtain the operating system name resolution configurations.
419 */
420 private static final RuntimePermission INET_ADDRESS_RESOLVER_PERMISSION =
421 new RuntimePermission("inetAddressResolverProvider");
422
423 private static final ReentrantLock RESOLVER_LOCK = new ReentrantLock();
424 private static volatile InetAddressResolver bootstrapResolver;
425
426 @SuppressWarnings("removal")
427 private static InetAddressResolver resolver() {
428 InetAddressResolver cns = resolver;
429 if (cns != null) {
430 return cns;
431 }
432 if (VM.isBooted()) {
433 RESOLVER_LOCK.lock();
434 boolean bootstrapSet = false;
435 try {
436 cns = resolver;
437 if (cns != null) {
438 return cns;
439 }
440 // Protection against provider calling InetAddress APIs during initialization
441 if (bootstrapResolver != null) {
442 return bootstrapResolver;
443 }
444 bootstrapResolver = BUILTIN_RESOLVER;
445 bootstrapSet = true;
446
447 if (HOSTS_FILE_NAME != null) {
448 // The default resolver service is already host file resolver
449 cns = BUILTIN_RESOLVER;
450 } else if (System.getSecurityManager() != null) {
451 PrivilegedAction<InetAddressResolver> pa = InetAddress::loadResolver;
452 cns = AccessController.doPrivileged(
453 pa, null, INET_ADDRESS_RESOLVER_PERMISSION);
454 } else {
455 cns = loadResolver();
456 }
457
458 InetAddress.resolver = cns;
459 return cns;
460 } finally {
461 // We want to clear bootstrap resolver reference only after an attempt to
462 // instantiate a resolver has been completed.
463 if (bootstrapSet) {
464 bootstrapResolver = null;
465 }
466 RESOLVER_LOCK.unlock();
467 }
468 } else {
469 return BUILTIN_RESOLVER;
470 }
471 }
472
473 private static InetAddressResolver loadResolver() {
474 return ServiceLoader.load(InetAddressResolverProvider.class)
475 .findFirst()
476 .map(nsp -> nsp.get(builtinConfiguration()))
477 .orElse(BUILTIN_RESOLVER);
478 }
479
480 private static InetAddressResolverProvider.Configuration builtinConfiguration() {
481 return new ResolverProviderConfiguration(BUILTIN_RESOLVER, () -> {
482 try {
483 return impl.getLocalHostName();
484 } catch (UnknownHostException unknownHostException) {
485 return "localhost";
486 }
487 });
488 }
489
490 /**
491 * Constructor for the Socket.accept() method.
492 * This creates an empty InetAddress, which is filled in by
493 * the accept() method. This InetAddress, however, is not
494 * put in the address cache, since it is not created by name.
495 */
496 InetAddress() {
497 holder = new InetAddressHolder();
498 }
499
500 /**
501 * Replaces the de-serialized object with an Inet4Address object.
502 *
503 * @return the alternate object to the de-serialized object.
504 *
505 * @throws ObjectStreamException if a new object replacing this
506 * object could not be created
507 */
508 @java.io.Serial
509 private Object readResolve() throws ObjectStreamException {
682 * @throws IOException if a network error occurs
683 * @since 1.5
684 */
685 public boolean isReachable(NetworkInterface netif, int ttl,
686 int timeout) throws IOException {
687 if (ttl < 0)
688 throw new IllegalArgumentException("ttl can't be negative");
689 if (timeout < 0)
690 throw new IllegalArgumentException("timeout can't be negative");
691
692 return impl.isReachable(this, timeout, netif, ttl);
693 }
694
695 /**
696 * Gets the host name for this IP address.
697 *
698 * <p>If this InetAddress was created with a host name,
699 * this host name will be remembered and returned;
700 * otherwise, a reverse name lookup will be performed
701 * and the result will be returned based on the system
702 * configured resolver. If a lookup of the name service
703 * is required, call
704 * {@link #getCanonicalHostName() getCanonicalHostName}.
705 *
706 * <p>If there is a security manager, its
707 * {@code checkConnect} method is first called
708 * with the hostname and {@code -1}
709 * as its arguments to see if the operation is allowed.
710 * If the operation is not allowed, it will return
711 * the textual representation of the IP address.
712 *
713 * @return the host name for this IP address, or if the operation
714 * is not allowed by the security check, the textual
715 * representation of the IP address.
716 *
717 * @see InetAddress#getCanonicalHostName
718 * @see SecurityManager#checkConnect
719 */
720 public String getHostName() {
721 return getHostName(true);
722 }
783 /**
784 * Returns the hostname for this address.
785 *
786 * <p>If there is a security manager, this method first
787 * calls its {@code checkConnect} method
788 * with the hostname and {@code -1}
789 * as its arguments to see if the calling code is allowed to know
790 * the hostname for this IP address, i.e., to connect to the host.
791 * If the operation is not allowed, it will return
792 * the textual representation of the IP address.
793 *
794 * @return the host name for this IP address, or if the operation
795 * is not allowed by the security check, the textual
796 * representation of the IP address.
797 *
798 * @param check make security check if true
799 *
800 * @see SecurityManager#checkConnect
801 */
802 private static String getHostFromNameService(InetAddress addr, boolean check) {
803 String host;
804 var resolver = resolver();
805 try {
806 // first lookup the hostname
807 host = resolver.lookupByAddress(addr.getAddress());
808
809 /* check to see if calling code is allowed to know
810 * the hostname for this IP address, ie, connect to the host
811 */
812 if (check) {
813 @SuppressWarnings("removal")
814 SecurityManager sec = System.getSecurityManager();
815 if (sec != null) {
816 sec.checkConnect(host, -1);
817 }
818 }
819
820 /* now get all the IP addresses for this hostname,
821 * and make sure one of them matches the original IP
822 * address. We do this to try and prevent spoofing.
823 */
824
825 InetAddress[] arr = InetAddress.getAllByName0(host, check);
826 boolean ok = false;
827
828 if (arr != null) {
829 for (int i = 0; !ok && i < arr.length; i++) {
830 ok = addr.equals(arr[i]);
831 }
832 }
833
834 //XXX: if it looks like a spoof just return the address?
835 if (!ok) {
836 host = addr.getHostAddress();
837 return host;
838 }
839 // 'resolver.lookupByAddress' and 'InetAddress.getAllByName0' delegate to the system-wide resolver,
840 // which could be a custom one. At that point we treat any unexpected RuntimeException thrown by
841 // the resolver as we would treat an UnknownHostException or an unmatched host name.
842 } catch (RuntimeException | UnknownHostException e) {
843 host = addr.getHostAddress();
844 }
845 return host;
846 }
847
848 /**
849 * Returns the raw IP address of this {@code InetAddress}
850 * object. The result is in network byte order: the highest order
851 * byte of the address is in {@code getAddress()[0]}.
852 *
853 * @return the raw IP address of this object.
854 */
855 public byte[] getAddress() {
856 return null;
857 }
858
859 /**
860 * Returns the IP address string in textual presentation.
861 *
862 * @return the raw IP address in a string format.
863 * @since 1.0.2
883 * <p>
884 * Two instances of {@code InetAddress} represent the same IP
885 * address if the length of the byte arrays returned by
886 * {@code getAddress} is the same for both, and each of the
887 * array components is the same for the byte arrays.
888 *
889 * @param obj the object to compare against.
890 * @return {@code true} if the objects are the same;
891 * {@code false} otherwise.
892 * @see java.net.InetAddress#getAddress()
893 */
894 public boolean equals(Object obj) {
895 return false;
896 }
897
898 /**
899 * Converts this IP address to a {@code String}. The
900 * string returned is of the form: hostname / literal IP
901 * address.
902 *
903 * If the host name is unresolved, no reverse lookup
904 * is performed. The hostname part will be represented
905 * by an empty string.
906 *
907 * @return a string representation of this IP address.
908 */
909 public String toString() {
910 String hostName = holder().getHostName();
911 return Objects.toString(hostName, "")
912 + "/" + getHostAddress();
913 }
914
915 // mapping from host name to Addresses - either NameServiceAddresses (while
916 // still being looked-up by NameService(s)) or CachedAddresses when cached
917 private static final ConcurrentMap<String, Addresses> cache =
918 new ConcurrentHashMap<>();
919
920 // CachedAddresses that have to expire are kept ordered in this NavigableSet
921 // which is scanned on each access
922 private static final NavigableSet<CachedAddresses> expirySet =
923 new ConcurrentSkipListSet<>();
924
925 // common interface
950 }
951
952 @Override
953 public int compareTo(CachedAddresses other) {
954 // natural order is expiry time -
955 // compare difference of expiry times rather than
956 // expiry times directly, to avoid possible overflow.
957 // (see System.nanoTime() recommendations...)
958 long diff = this.expiryTime - other.expiryTime;
959 if (diff < 0L) return -1;
960 if (diff > 0L) return 1;
961 // ties are broken using unique id
962 return Long.compare(this.id, other.id);
963 }
964 }
965
966 // a name service lookup based Addresses implementation which replaces itself
967 // in cache when the result is obtained
968 private static final class NameServiceAddresses implements Addresses {
969 private final String host;
970
971 NameServiceAddresses(String host) {
972 this.host = host;
973 }
974
975 @Override
976 public InetAddress[] get() throws UnknownHostException {
977 Addresses addresses;
978 // only one thread is doing lookup to name service
979 // for particular host at any time.
980 synchronized (this) {
981 // re-check that we are still us + re-install us if slot empty
982 addresses = cache.putIfAbsent(host, this);
983 if (addresses == null) {
984 // this can happen when we were replaced by CachedAddresses in
985 // some other thread, then CachedAddresses expired and were
986 // removed from cache while we were waiting for lock...
987 addresses = this;
988 }
989 // still us ?
990 if (addresses == this) {
991 // lookup name services
992 InetAddress[] inetAddresses;
993 UnknownHostException ex;
994 int cachePolicy;
995 try {
996 inetAddresses = getAddressesFromNameService(host);
997 ex = null;
998 cachePolicy = InetAddressCachePolicy.get();
999 } catch (UnknownHostException uhe) {
1000 inetAddresses = null;
1001 ex = uhe;
1002 cachePolicy = InetAddressCachePolicy.getNegative();
1003 }
1004 // remove or replace us with cached addresses according to cachePolicy
1005 if (cachePolicy == InetAddressCachePolicy.NEVER) {
1006 cache.remove(host, this);
1007 } else {
1008 CachedAddresses cachedAddresses = new CachedAddresses(
1009 host,
1010 inetAddresses,
1011 cachePolicy == InetAddressCachePolicy.FOREVER
1012 ? 0L
1013 // cachePolicy is in [s] - we need [ns]
1014 : System.nanoTime() + 1000_000_000L * cachePolicy
1015 );
1016 if (cache.replace(host, this, cachedAddresses) &&
1017 cachePolicy != InetAddressCachePolicy.FOREVER) {
1018 // schedule expiry
1019 expirySet.add(cachedAddresses);
1020 }
1021 }
1022 if (inetAddresses == null || inetAddresses.length == 0) {
1023 throw ex == null ? new UnknownHostException(host) : ex;
1024 }
1025 return inetAddresses;
1026 }
1027 // else addresses != this
1028 }
1029 // delegate to different addresses when we are already replaced
1030 // but outside of synchronized block to avoid any chance of dead-locking
1031 return addresses.get();
1032 }
1033 }
1034
1035 /**
1036 * The default InetAddressResolver implementation, which delegates to the underlying
1037 * OS network libraries to resolve host address mappings.
1038 *
1039 * @since 9
1040 */
1041 private static final class PlatformResolver implements InetAddressResolver {
1042
1043 public Stream<InetAddress> lookupByName(String host, LookupPolicy policy)
1044 throws UnknownHostException {
1045 Objects.requireNonNull(host);
1046 Objects.requireNonNull(policy);
1047 return Arrays.stream(impl.lookupAllHostAddr(host, policy));
1048 }
1049
1050 public String lookupByAddress(byte[] addr)
1051 throws UnknownHostException {
1052 Objects.requireNonNull(addr);
1053 if (addr.length != Inet4Address.INADDRSZ && addr.length != Inet6Address.INADDRSZ) {
1054 throw new IllegalArgumentException("Invalid address length");
1055 }
1056 return impl.getHostByAddr(addr);
1057 }
1058 }
1059
1060 /**
1061 * The HostsFileResolver provides host address mapping
1062 * by reading the entries in a hosts file, which is specified by
1063 * {@code jdk.net.hosts.file} system property
1064 *
1065 * <p>The file format is that which corresponds with the /etc/hosts file
1066 * IP Address host alias list.
1067 *
1068 * <p>When the file lookup is enabled it replaces the default InetAddressResolver
1069 * implementation
1070 *
1071 * @since 9
1072 */
1073 private static final class HostsFileResolver implements InetAddressResolver {
1074
1075 private final String hostsFile;
1076
1077 public HostsFileResolver(String hostsFileName) {
1078 this.hostsFile = hostsFileName;
1079 }
1080
1081 /**
1082 * Lookup the host name corresponding to the IP address provided.
1083 * Search the configured host file a host name corresponding to
1084 * the specified IP address.
1085 *
1086 * @param addr byte array representing an IP address
1087 * @return {@code String} representing the host name mapping
1088 * @throws UnknownHostException if no host found for the specified IP address
1089 * @throws IllegalArgumentException if IP address is of illegal length
1090 */
1091 @Override
1092 public String lookupByAddress(byte[] addr) throws UnknownHostException {
1093 String hostEntry;
1094 String host = null;
1095 Objects.requireNonNull(addr);
1096 // Check the length of the address array
1097 if (addr.length != Inet4Address.INADDRSZ && addr.length != Inet6Address.INADDRSZ) {
1098 throw new IllegalArgumentException("Invalid address length");
1099 }
1100
1101 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
1102 UTF_8.INSTANCE)) {
1103 while (hostsFileScanner.hasNextLine()) {
1104 hostEntry = hostsFileScanner.nextLine();
1105 if (!hostEntry.startsWith("#")) {
1106 hostEntry = removeComments(hostEntry);
1107 String[] mapping = hostEntry.split("\\s+");
1108 if (mapping.length >= 2 &&
1109 Arrays.equals(addr, createAddressByteArray(mapping[0]))) {
1110 host = mapping[1];
1111 break;
1112 }
1113 }
1114 }
1115 } catch (IOException e) {
1116 throw new UnknownHostException("Unable to resolve address "
1117 + Arrays.toString(addr) + " as hosts file " + hostsFile
1118 + " not found ");
1119 }
1120
1121 if ((host == null) || (host.isEmpty()) || (host.equals(" "))) {
1122 throw new UnknownHostException("Requested address "
1123 + Arrays.toString(addr)
1124 + " resolves to an invalid entry in hosts file "
1125 + hostsFile);
1126 }
1127 return host;
1128 }
1129
1130 /**
1131 * <p>Lookup a host mapping by name. Retrieve the IP addresses
1132 * associated with a host.
1133 *
1134 * <p>Search the configured hosts file for the addresses associated
1135 * with the specified host name.
1136 *
1137 * @param host the specified hostname
1138 * @param lookupPolicy IP addresses lookup policy which specifies addresses
1139 * family and their order
1140 * @return stream of IP addresses for the requested host
1141 * @throws UnknownHostException
1142 * if no IP address for the {@code host} could be found
1143 */
1144 public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy)
1145 throws UnknownHostException {
1146 String hostEntry;
1147 String addrStr;
1148 byte addr[];
1149
1150 Objects.requireNonNull(host);
1151 Objects.requireNonNull(lookupPolicy);
1152 List<InetAddress> inetAddresses = new ArrayList<>();
1153 List<InetAddress> inet4Addresses = new ArrayList<>();
1154 List<InetAddress> inet6Addresses = new ArrayList<>();
1155 int flags = lookupPolicy.characteristics();
1156 boolean needIPv4 = (flags & IPv4) != 0;
1157 boolean needIPv6 = (flags & IPv6) != 0;
1158
1159 // lookup the file and create a list InetAddress for the specified host
1160 try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
1161 UTF_8.INSTANCE)) {
1162 while (hostsFileScanner.hasNextLine()) {
1163 hostEntry = hostsFileScanner.nextLine();
1164 if (!hostEntry.startsWith("#")) {
1165 hostEntry = removeComments(hostEntry);
1166 if (hostEntry.contains(host)) {
1167 addrStr = extractHostAddr(hostEntry, host);
1168 if ((addrStr != null) && (!addrStr.isEmpty())) {
1169 addr = createAddressByteArray(addrStr);
1170 if (addr != null) {
1171 InetAddress address = InetAddress.getByAddress(host, addr);
1172 inetAddresses.add(address);
1173 if (address instanceof Inet4Address && needIPv4) {
1174 inet4Addresses.add(address);
1175 }
1176 if (address instanceof Inet6Address && needIPv6) {
1177 inet6Addresses.add(address);
1178 }
1179 }
1180 }
1181 }
1182 }
1183 }
1184 } catch (IOException e) {
1185 throw new UnknownHostException("Unable to resolve host " + host
1186 + " as hosts file " + hostsFile + " not found ");
1187 }
1188 // Check if only IPv4 addresses are requested
1189 if (needIPv4 && !needIPv6) {
1190 checkResultsList(inet4Addresses, host);
1191 return inet4Addresses.stream();
1192 }
1193 // Check if only IPv6 addresses are requested
1194 if (!needIPv4 && needIPv6) {
1195 checkResultsList(inet6Addresses, host);
1196 return inet6Addresses.stream();
1197 }
1198 // If both type of addresses are requested:
1199 // First, check if there is any results. Then arrange
1200 // addresses according to LookupPolicy value.
1201 checkResultsList(inetAddresses, host);
1202 if (ipv6AddressesFirst(flags)) {
1203 return Stream.concat(inet6Addresses.stream(), inet4Addresses.stream());
1204 } else if (ipv4AddressesFirst(flags)) {
1205 return Stream.concat(inet4Addresses.stream(), inet6Addresses.stream());
1206 }
1207 // Only "system" addresses order is possible at this stage
1208 assert systemAddressesOrder(flags);
1209 return inetAddresses.stream();
1210 }
1211
1212 // Checks if result list with addresses is not empty.
1213 // If it is empty throw an UnknownHostException.
1214 private void checkResultsList(List<InetAddress> addressesList, String hostName)
1215 throws UnknownHostException {
1216 if (addressesList.isEmpty()) {
1217 throw new UnknownHostException("Unable to resolve host " + hostName
1218 + " in hosts file " + hostsFile);
1219 }
1220 }
1221
1222 private String removeComments(String hostsEntry) {
1223 String filteredEntry = hostsEntry;
1224 int hashIndex;
1225
1226 if ((hashIndex = hostsEntry.indexOf("#")) != -1) {
1227 filteredEntry = hostsEntry.substring(0, hashIndex);
1228 }
1229 return filteredEntry;
1230 }
1231
1232 private byte [] createAddressByteArray(String addrStr) {
1233 byte[] addrArray;
1234 // check if IPV4 address - most likely
1235 addrArray = IPAddressUtil.textToNumericFormatV4(addrStr);
1236 if (addrArray == null) {
1237 addrArray = IPAddressUtil.textToNumericFormatV6(addrStr);
1238 }
1239 return addrArray;
1241
1242 /** host to ip address mapping */
1243 private String extractHostAddr(String hostEntry, String host) {
1244 String[] mapping = hostEntry.split("\\s+");
1245 String hostAddr = null;
1246
1247 if (mapping.length >= 2) {
1248 // look at the host aliases
1249 for (int i = 1; i < mapping.length; i++) {
1250 if (mapping[i].equalsIgnoreCase(host)) {
1251 hostAddr = mapping[0];
1252 }
1253 }
1254 }
1255 return hostAddr;
1256 }
1257 }
1258
1259 static final InetAddressImpl impl;
1260
1261 /**
1262 * Platform-wide {@code LookupPolicy} initialized from {@code "java.net.preferIPv4Stack"},
1263 * {@code "java.net.preferIPv6Addresses"} system properties.
1264 */
1265 static final LookupPolicy PLATFORM_LOOKUP_POLICY;
1266
1267 static {
1268 // create the impl
1269 impl = InetAddressImplFactory.create();
1270
1271 // impl must be initialized before calling this method
1272 PLATFORM_LOOKUP_POLICY = initializePlatformLookupPolicy();
1273
1274 // create built-in resolver
1275 BUILTIN_RESOLVER = createBuiltinInetAddressResolver();
1276 }
1277
1278 /**
1279 * Create an instance of the InetAddressResolver interface based on
1280 * the setting of the {@code jdk.net.hosts.file} system property.
1281 *
1282 * <p>The default InetAddressResolver is the PlatformResolver, which typically
1283 * delegates name and address resolution calls to the underlying
1284 * OS network libraries.
1285 *
1286 * <p> A HostsFileResolver is created if the {@code jdk.net.hosts.file}
1287 * system property is set. If the specified file doesn't exist, the name or
1288 * address lookup will result in an UnknownHostException. Thus, non existent
1289 * hosts file is handled as if the file is empty.
1290 *
1291 * @return an InetAddressResolver
1292 */
1293 private static InetAddressResolver createBuiltinInetAddressResolver() {
1294 InetAddressResolver theResolver;
1295 if (HOSTS_FILE_NAME != null) {
1296 theResolver = new HostsFileResolver(HOSTS_FILE_NAME);
1297 } else {
1298 theResolver = new PlatformResolver();
1299 }
1300 return theResolver;
1301 }
1302
1303 /**
1304 * Creates an InetAddress based on the provided host name and IP address.
1305 * System {@linkplain InetAddressResolver resolver} is not used to check
1306 * the validity of the address.
1307 *
1308 * <p> The host name can either be a machine name, such as
1309 * "{@code www.example.com}", or a textual representation of its IP
1310 * address.
1311 * <p> No validity checking is done on the host name either.
1312 *
1313 * <p> If addr specifies an IPv4 address an instance of Inet4Address
1314 * will be returned; otherwise, an instance of Inet6Address
1315 * will be returned.
1316 *
1317 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1318 * must be 16 bytes long
1319 *
1320 * @param host the specified host
1321 * @param addr the raw IP address in network byte order
1322 * @return an InetAddress object created from the raw IP address.
1323 * @throws UnknownHostException if IP address is of illegal length
1324 * @since 1.4
1325 */
1326 public static InetAddress getByAddress(String host, byte[] addr)
1369 * section 2.5.3.
1370 *
1371 * <p> If there is a security manager, and {@code host} is not {@code null}
1372 * or {@code host.length() } is not equal to zero, the security manager's
1373 * {@code checkConnect} method is called with the hostname and {@code -1}
1374 * as its arguments to determine if the operation is allowed.
1375 *
1376 * @param host the specified host, or {@code null}.
1377 * @return an IP address for the given host name.
1378 * @throws UnknownHostException if no IP address for the
1379 * {@code host} could be found, or if a scope_id was specified
1380 * for a global IPv6 address.
1381 * @throws SecurityException if a security manager exists
1382 * and its checkConnect method doesn't allow the operation
1383 */
1384 public static InetAddress getByName(String host)
1385 throws UnknownHostException {
1386 return InetAddress.getAllByName(host)[0];
1387 }
1388
1389 /**
1390 * Given the name of a host, returns an array of its IP addresses,
1391 * based on the configured system {@linkplain InetAddressResolver resolver}.
1392 *
1393 * <p> The host name can either be a machine name, such as
1394 * "{@code www.example.com}", or a textual representation of its IP
1395 * address. If a literal IP address is supplied, only the
1396 * validity of the address format is checked.
1397 *
1398 * <p> For {@code host} specified in <i>literal IPv6 address</i>,
1399 * either the form defined in RFC 2732 or the literal IPv6 address
1400 * format defined in RFC 2373 is accepted. A literal IPv6 address may
1401 * also be qualified by appending a scoped zone identifier or scope_id.
1402 * The syntax and usage of scope_ids is described
1403 * <a href="Inet6Address.html#scoped">here</a>.
1404 *
1405 * <p> If the host is {@code null} or {@code host.length()} is equal
1406 * to zero, then an {@code InetAddress} representing an address of the
1407 * loopback interface is returned.
1408 * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
1409 * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
1410 * section 2.5.3. </p>
1411 *
1412 * <p> If there is a security manager, and {@code host} is not {@code null}
1413 * or {@code host.length() } is not equal to zero, the security manager's
1414 * {@code checkConnect} method is called with the hostname and {@code -1}
1415 * as its arguments to determine if the operation is allowed.
1416 *
1417 * @param host the name of the host, or {@code null}.
1418 * @return an array of all the IP addresses for a given host name.
1419 *
1420 * @throws UnknownHostException if no IP address for the
1421 * {@code host} could be found, or if a scope_id was specified
1422 * for a global IPv6 address.
1423 * @throws SecurityException if a security manager exists and its
1424 * {@code checkConnect} method doesn't allow the operation.
1425 *
1426 * @see SecurityManager#checkConnect
1427 */
1428 public static InetAddress[] getAllByName(String host)
1429 throws UnknownHostException {
1430
1431 if (host == null || host.isEmpty()) {
1432 InetAddress[] ret = new InetAddress[1];
1433 ret[0] = impl.loopbackAddress();
1434 return ret;
1435 }
1436
1437 boolean ipv6Expected = false;
1438 if (host.charAt(0) == '[') {
1439 // This is supposed to be an IPv6 literal
1440 if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
1441 host = host.substring(1, host.length() -1);
1442 ipv6Expected = true;
1443 } else {
1444 // This was supposed to be a IPv6 address, but it's not!
1445 throw new UnknownHostException(host + ": invalid IPv6 address");
1446 }
1447 }
1448
1449 // if host is an IP address, we won't do further lookup
1471 // Means an IPv4 literal between brackets!
1472 throw new UnknownHostException("["+host+"]");
1473 }
1474 InetAddress[] ret = new InetAddress[1];
1475 if(addr != null) {
1476 if (addr.length == Inet4Address.INADDRSZ) {
1477 ret[0] = new Inet4Address(null, addr);
1478 } else {
1479 if (ifname != null) {
1480 ret[0] = new Inet6Address(null, addr, ifname);
1481 } else {
1482 ret[0] = new Inet6Address(null, addr, numericZone);
1483 }
1484 }
1485 return ret;
1486 }
1487 } else if (ipv6Expected) {
1488 // We were expecting an IPv6 Literal, but got something else
1489 throw new UnknownHostException("["+host+"]");
1490 }
1491 return getAllByName0(host, true, true);
1492 }
1493
1494 /**
1495 * Returns the loopback address.
1496 * <p>
1497 * The InetAddress returned will represent the IPv4
1498 * loopback address, 127.0.0.1, or the IPv6 loopback
1499 * address, ::1. The IPv4 loopback address returned
1500 * is only one of many in the form 127.*.*.*
1501 *
1502 * @return the InetAddress loopback instance.
1503 * @since 1.7
1504 */
1505 public static InetAddress getLoopbackAddress() {
1506 return impl.loopbackAddress();
1507 }
1508
1509
1510 /**
1511 * check if the literal address string has %nn appended
1521 if (percent == -1) {
1522 return -1;
1523 }
1524 for (int i=percent+1; i<slen; i++) {
1525 char c = s.charAt(i);
1526 if (c == ']') {
1527 if (i == percent+1) {
1528 /* empty per-cent field */
1529 return -1;
1530 }
1531 break;
1532 }
1533 if ((digit = Character.digit (c, 10)) < 0) {
1534 return -1;
1535 }
1536 zone = (zone * 10) + digit;
1537 }
1538 return zone;
1539 }
1540
1541 /**
1542 * package private so SocketPermission can call it
1543 */
1544 static InetAddress[] getAllByName0 (String host, boolean check)
1545 throws UnknownHostException {
1546 return getAllByName0(host, check, true);
1547 }
1548
1549 /**
1550 * Designated lookup method.
1551 *
1552 * @param host host name to look up
1553 * @param check perform security check
1554 * @param useCache use cached value if not expired else always
1555 * perform name service lookup (and cache the result)
1556 * @return array of InetAddress(es)
1557 * @throws UnknownHostException if host name is not found
1558 */
1559 private static InetAddress[] getAllByName0(String host,
1560 boolean check,
1561 boolean useCache)
1562 throws UnknownHostException {
1563
1564 /* If it gets here it is presumed to be a hostname */
1565
1566 /* make sure the connection to the host is allowed, before we
1567 * give out a hostname
1568 */
1569 if (check) {
1570 @SuppressWarnings("removal")
1571 SecurityManager security = System.getSecurityManager();
1572 if (security != null) {
1573 security.checkConnect(host, -1);
1574 }
1575 }
1576
1577 // remove expired addresses from cache - expirySet keeps them ordered
1578 // by expiry time so we only need to iterate the prefix of the NavigableSet...
1579 long now = System.nanoTime();
1597 // look-up or remove from cache
1598 Addresses addrs;
1599 if (useCache) {
1600 addrs = cache.get(host);
1601 } else {
1602 addrs = cache.remove(host);
1603 if (addrs != null) {
1604 if (addrs instanceof CachedAddresses) {
1605 // try removing from expirySet too if CachedAddresses
1606 expirySet.remove(addrs);
1607 }
1608 addrs = null;
1609 }
1610 }
1611
1612 if (addrs == null) {
1613 // create a NameServiceAddresses instance which will look up
1614 // the name service and install it within cache...
1615 Addresses oldAddrs = cache.putIfAbsent(
1616 host,
1617 addrs = new NameServiceAddresses(host)
1618 );
1619 if (oldAddrs != null) { // lost putIfAbsent race
1620 addrs = oldAddrs;
1621 }
1622 }
1623
1624 // ask Addresses to get an array of InetAddress(es) and clone it
1625 return addrs.get().clone();
1626 }
1627
1628 static InetAddress[] getAddressesFromNameService(String host)
1629 throws UnknownHostException {
1630 Stream<InetAddress> addresses = null;
1631 UnknownHostException ex = null;
1632
1633 var resolver = resolver();
1634 try {
1635 addresses = resolver.lookupByName(host, PLATFORM_LOOKUP_POLICY);
1636 } catch (RuntimeException | UnknownHostException x) {
1637 if (host.equalsIgnoreCase("localhost")) {
1638 addresses = Stream.of(impl.loopbackAddress());
1639 } else if (x instanceof UnknownHostException uhe) {
1640 ex = uhe;
1641 } else {
1642 ex = new UnknownHostException();
1643 ex.initCause(x);
1644 }
1645 }
1646 InetAddress[] result = addresses == null ? null
1647 : addresses.toArray(InetAddress[]::new);
1648 if (result == null || result.length == 0) {
1649 throw ex == null ? new UnknownHostException(host) : ex;
1650 }
1651 return result;
1652 }
1653
1654 /**
1655 * Returns an {@code InetAddress} object given the raw IP address .
1656 * The argument is in network byte order: the highest order
1657 * byte of the address is in {@code getAddress()[0]}.
1658 *
1659 * <p> This method doesn't block, i.e. no reverse lookup is performed.
1660 *
1661 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1662 * must be 16 bytes long
1663 *
1664 * @param addr the raw IP address in network byte order
1665 * @return an InetAddress object created from the raw IP address.
1666 * @throws UnknownHostException if IP address is of illegal length
1667 * @since 1.4
1668 */
1669 public static InetAddress getByAddress(byte[] addr)
1670 throws UnknownHostException {
1671 return getByAddress(null, addr);
1672 }
1673
1674 private static final class CachedLocalHost {
1675 final String host;
1676 final InetAddress addr;
1677 final long expiryTime = System.nanoTime() + 5000_000_000L; // now + 5s;
1678
1679 CachedLocalHost(String host, InetAddress addr) {
1718 if (security != null) {
1719 security.checkConnect(clh.host, -1);
1720 }
1721 return clh.addr;
1722 }
1723
1724 String local = impl.getLocalHostName();
1725
1726 if (security != null) {
1727 security.checkConnect(local, -1);
1728 }
1729
1730 InetAddress localAddr;
1731 if (local.equals("localhost")) {
1732 // shortcut for "localhost" host name
1733 localAddr = impl.loopbackAddress();
1734 } else {
1735 // call getAllByName0 without security checks and
1736 // without using cached data
1737 try {
1738 localAddr = getAllByName0(local, false, false)[0];
1739 } catch (UnknownHostException uhe) {
1740 // Rethrow with a more informative error message.
1741 UnknownHostException uhe2 =
1742 new UnknownHostException(local + ": " +
1743 uhe.getMessage());
1744 uhe2.initCause(uhe);
1745 throw uhe2;
1746 }
1747 }
1748 cachedLocalHost = new CachedLocalHost(local, localAddr);
1749 return localAddr;
1750 } catch (java.lang.SecurityException e) {
1751 return impl.loopbackAddress();
1752 }
1753 }
1754
1755 /**
1756 * Perform class load-time initializations.
1757 */
1758 private static native void init();
|