Path: blob/master/src/java.base/share/classes/java/net/InetAddress.java
67862 views
/*1* Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.net;2627import java.util.List;28import java.util.NavigableSet;29import java.util.ArrayList;30import java.util.Objects;31import java.util.Scanner;32import java.io.File;33import java.io.ObjectStreamException;34import java.io.ObjectStreamField;35import java.io.IOException;36import java.io.InvalidObjectException;37import java.io.ObjectInputStream;38import java.io.ObjectInputStream.GetField;39import java.io.ObjectOutputStream;40import java.io.ObjectOutputStream.PutField;41import java.lang.annotation.Native;42import java.util.concurrent.ConcurrentHashMap;43import java.util.concurrent.ConcurrentMap;44import java.util.concurrent.ConcurrentSkipListSet;45import java.util.concurrent.atomic.AtomicLong;46import java.util.Arrays;4748import jdk.internal.access.JavaNetInetAddressAccess;49import jdk.internal.access.SharedSecrets;50import sun.security.action.*;51import sun.net.InetAddressCachePolicy;52import sun.net.util.IPAddressUtil;53import sun.nio.cs.UTF_8;5455/**56* This class represents an Internet Protocol (IP) address.57*58* <p> An IP address is either a 32-bit or 128-bit unsigned number59* used by IP, a lower-level protocol on which protocols like UDP and60* TCP are built. The IP address architecture is defined by <a61* href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC 790:62* Assigned Numbers</i></a>, <a63* href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC 1918:64* Address Allocation for Private Internets</i></a>, <a65* href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:66* Administratively Scoped IP Multicast</i></a>, and <a67* href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP68* Version 6 Addressing Architecture</i></a>. An instance of an69* InetAddress consists of an IP address and possibly its70* corresponding host name (depending on whether it is constructed71* with a host name or whether it has already done reverse host name72* resolution).73*74* <h2> Address types </h2>75*76* <table class="striped" style="margin-left:2em">77* <caption style="display:none">Description of unicast and multicast address types</caption>78* <thead>79* <tr><th scope="col">Address Type</th><th scope="col">Description</th></tr>80* </thead>81* <tbody>82* <tr><th scope="row" style="vertical-align:top">unicast</th>83* <td>An identifier for a single interface. A packet sent to84* a unicast address is delivered to the interface identified by85* that address.86*87* <p> The Unspecified Address -- Also called anylocal or wildcard88* address. It must never be assigned to any node. It indicates the89* absence of an address. One example of its use is as the target of90* bind, which allows a server to accept a client connection on any91* interface, in case the server host has multiple interfaces.92*93* <p> The <i>unspecified</i> address must not be used as94* the destination address of an IP packet.95*96* <p> The <i>Loopback</i> Addresses -- This is the address97* assigned to the loopback interface. Anything sent to this98* IP address loops around and becomes IP input on the local99* host. This address is often used when testing a100* client.</td></tr>101* <tr><th scope="row" style="vertical-align:top">multicast</th>102* <td>An identifier for a set of interfaces (typically belonging103* to different nodes). A packet sent to a multicast address is104* delivered to all interfaces identified by that address.</td></tr>105* </tbody>106* </table>107*108* <h3> IP address scope </h3>109*110* <p> <i>Link-local</i> addresses are designed to be used for addressing111* on a single link for purposes such as auto-address configuration,112* neighbor discovery, or when no routers are present.113*114* <p> <i>Site-local</i> addresses are designed to be used for addressing115* inside of a site without the need for a global prefix.116*117* <p> <i>Global</i> addresses are unique across the internet.118*119* <h3> Textual representation of IP addresses </h3>120*121* The textual representation of an IP address is address family specific.122*123* <p>124*125* For IPv4 address format, please refer to <A126* HREF="Inet4Address.html#format">Inet4Address#format</A>; For IPv6127* address format, please refer to <A128* HREF="Inet6Address.html#format">Inet6Address#format</A>.129*130* <P>There is a <a href="doc-files/net-properties.html#Ipv4IPv6">couple of131* System Properties</a> affecting how IPv4 and IPv6 addresses are used.</P>132*133* <h3> Host Name Resolution </h3>134*135* Host name-to-IP address <i>resolution</i> is accomplished through136* the use of a combination of local machine configuration information137* and network naming services such as the Domain Name System (DNS)138* and Network Information Service(NIS). The particular naming139* services(s) being used is by default the local machine configured140* one. For any host name, its corresponding IP address is returned.141*142* <p> <i>Reverse name resolution</i> means that for any IP address,143* the host associated with the IP address is returned.144*145* <p> The InetAddress class provides methods to resolve host names to146* their IP addresses and vice versa.147*148* <h3> InetAddress Caching </h3>149*150* The InetAddress class has a cache to store successful as well as151* unsuccessful host name resolutions.152*153* <p> By default, when a security manager is installed, in order to154* protect against DNS spoofing attacks,155* the result of positive host name resolutions are156* cached forever. When a security manager is not installed, the default157* behavior is to cache entries for a finite (implementation dependent)158* period of time. The result of unsuccessful host159* name resolution is cached for a very short period of time (10160* seconds) to improve performance.161*162* <p> If the default behavior is not desired, then a Java security property163* can be set to a different Time-to-live (TTL) value for positive164* caching. Likewise, a system admin can configure a different165* negative caching TTL value when needed.166*167* <p> Two Java security properties control the TTL values used for168* positive and negative host name resolution caching:169*170* <dl style="margin-left:2em">171* <dt><b>networkaddress.cache.ttl</b></dt>172* <dd>Indicates the caching policy for successful name lookups from173* the name service. The value is specified as an integer to indicate174* the number of seconds to cache the successful lookup. The default175* setting is to cache for an implementation specific period of time.176* <p>177* A value of -1 indicates "cache forever".178* </dd>179* <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>180* <dd>Indicates the caching policy for un-successful name lookups181* from the name service. The value is specified as an integer to182* indicate the number of seconds to cache the failure for183* un-successful lookups.184* <p>185* A value of 0 indicates "never cache".186* A value of -1 indicates "cache forever".187* </dd>188* </dl>189*190* @author Chris Warth191* @see java.net.InetAddress#getByAddress(byte[])192* @see java.net.InetAddress#getByAddress(java.lang.String, byte[])193* @see java.net.InetAddress#getAllByName(java.lang.String)194* @see java.net.InetAddress#getByName(java.lang.String)195* @see java.net.InetAddress#getLocalHost()196* @since 1.0197*/198public class InetAddress implements java.io.Serializable {199200@Native static final int PREFER_IPV4_VALUE = 0;201@Native static final int PREFER_IPV6_VALUE = 1;202@Native static final int PREFER_SYSTEM_VALUE = 2;203204/**205* Specify the address family: Internet Protocol, Version 4206* @since 1.4207*/208@Native static final int IPv4 = 1;209210/**211* Specify the address family: Internet Protocol, Version 6212* @since 1.4213*/214@Native static final int IPv6 = 2;215216/* Specify address family preference */217static transient final int preferIPv6Address;218219static class InetAddressHolder {220/**221* Reserve the original application specified hostname.222*223* The original hostname is useful for domain-based endpoint224* identification (see RFC 2818 and RFC 6125). If an address225* was created with a raw IP address, a reverse name lookup226* may introduce endpoint identification security issue via227* DNS forging.228*229* Oracle JSSE provider is using this original hostname, via230* jdk.internal.misc.JavaNetAccess, for SSL/TLS endpoint identification.231*232* Note: May define a new public method in the future if necessary.233*/234String originalHostName;235236InetAddressHolder() {}237238InetAddressHolder(String hostName, int address, int family) {239this.originalHostName = hostName;240this.hostName = hostName;241this.address = address;242this.family = family;243}244245void init(String hostName, int family) {246this.originalHostName = hostName;247this.hostName = hostName;248if (family != -1) {249this.family = family;250}251}252253String hostName;254255String getHostName() {256return hostName;257}258259String getOriginalHostName() {260return originalHostName;261}262263/**264* Holds a 32-bit IPv4 address.265*/266int address;267268int getAddress() {269return address;270}271272/**273* Specifies the address family type, for instance, '1' for IPv4274* addresses, and '2' for IPv6 addresses.275*/276int family;277278int getFamily() {279return family;280}281}282283/* Used to store the serializable fields of InetAddress */284final transient InetAddressHolder holder;285286InetAddressHolder holder() {287return holder;288}289290/* Used to store the name service provider */291private static transient NameService nameService;292293/**294* Used to store the best available hostname.295* Lazily initialized via a data race; safe because Strings are immutable.296*/297private transient String canonicalHostName = null;298299/** use serialVersionUID from JDK 1.0.2 for interoperability */300@java.io.Serial301private static final long serialVersionUID = 3286316764910316507L;302303/*304* Load net library into runtime, and perform initializations.305*/306static {307String str = GetPropertyAction.privilegedGetProperty("java.net.preferIPv6Addresses");308if (str == null) {309preferIPv6Address = PREFER_IPV4_VALUE;310} else if (str.equalsIgnoreCase("true")) {311preferIPv6Address = PREFER_IPV6_VALUE;312} else if (str.equalsIgnoreCase("false")) {313preferIPv6Address = PREFER_IPV4_VALUE;314} else if (str.equalsIgnoreCase("system")) {315preferIPv6Address = PREFER_SYSTEM_VALUE;316} else {317preferIPv6Address = PREFER_IPV4_VALUE;318}319jdk.internal.loader.BootLoader.loadLibrary("net");320SharedSecrets.setJavaNetInetAddressAccess(321new JavaNetInetAddressAccess() {322public String getOriginalHostName(InetAddress ia) {323return ia.holder.getOriginalHostName();324}325326public InetAddress getByName(String hostName,327InetAddress hostAddress)328throws UnknownHostException329{330return InetAddress.getByName(hostName, hostAddress);331}332333public int addressValue(Inet4Address inet4Address) {334return inet4Address.addressValue();335}336337public byte[] addressBytes(Inet6Address inet6Address) {338return inet6Address.addressBytes();339}340}341);342init();343}344345/**346* Constructor for the Socket.accept() method.347* This creates an empty InetAddress, which is filled in by348* the accept() method. This InetAddress, however, is not349* put in the address cache, since it is not created by name.350*/351InetAddress() {352holder = new InetAddressHolder();353}354355/**356* Replaces the de-serialized object with an Inet4Address object.357*358* @return the alternate object to the de-serialized object.359*360* @throws ObjectStreamException if a new object replacing this361* object could not be created362*/363@java.io.Serial364private Object readResolve() throws ObjectStreamException {365// will replace the deserialized 'this' object366return new Inet4Address(holder().getHostName(), holder().getAddress());367}368369/**370* Utility routine to check if the InetAddress is an371* IP multicast address.372* @return a {@code boolean} indicating if the InetAddress is373* an IP multicast address374* @since 1.1375*/376public boolean isMulticastAddress() {377return false;378}379380/**381* Utility routine to check if the InetAddress is a wildcard address.382* @return a {@code boolean} indicating if the InetAddress is383* a wildcard address.384* @since 1.4385*/386public boolean isAnyLocalAddress() {387return false;388}389390/**391* Utility routine to check if the InetAddress is a loopback address.392*393* @return a {@code boolean} indicating if the InetAddress is394* a loopback address; or false otherwise.395* @since 1.4396*/397public boolean isLoopbackAddress() {398return false;399}400401/**402* Utility routine to check if the InetAddress is an link local address.403*404* @return a {@code boolean} indicating if the InetAddress is405* a link local address; or false if address is not a link local unicast address.406* @since 1.4407*/408public boolean isLinkLocalAddress() {409return false;410}411412/**413* Utility routine to check if the InetAddress is a site local address.414*415* @return a {@code boolean} indicating if the InetAddress is416* a site local address; or false if address is not a site local unicast address.417* @since 1.4418*/419public boolean isSiteLocalAddress() {420return false;421}422423/**424* Utility routine to check if the multicast address has global scope.425*426* @return a {@code boolean} indicating if the address has427* is a multicast address of global scope, false if it is not428* of global scope or it is not a multicast address429* @since 1.4430*/431public boolean isMCGlobal() {432return false;433}434435/**436* Utility routine to check if the multicast address has node scope.437*438* @return a {@code boolean} indicating if the address has439* is a multicast address of node-local scope, false if it is not440* of node-local scope or it is not a multicast address441* @since 1.4442*/443public boolean isMCNodeLocal() {444return false;445}446447/**448* Utility routine to check if the multicast address has link scope.449*450* @return a {@code boolean} indicating if the address has451* is a multicast address of link-local scope, false if it is not452* of link-local scope or it is not a multicast address453* @since 1.4454*/455public boolean isMCLinkLocal() {456return false;457}458459/**460* Utility routine to check if the multicast address has site scope.461*462* @return a {@code boolean} indicating if the address has463* is a multicast address of site-local scope, false if it is not464* of site-local scope or it is not a multicast address465* @since 1.4466*/467public boolean isMCSiteLocal() {468return false;469}470471/**472* Utility routine to check if the multicast address has organization scope.473*474* @return a {@code boolean} indicating if the address has475* is a multicast address of organization-local scope,476* false if it is not of organization-local scope477* or it is not a multicast address478* @since 1.4479*/480public boolean isMCOrgLocal() {481return false;482}483484485/**486* Test whether that address is reachable. Best effort is made by the487* implementation to try to reach the host, but firewalls and server488* configuration may block requests resulting in a unreachable status489* while some specific ports may be accessible.490* A typical implementation will use ICMP ECHO REQUESTs if the491* privilege can be obtained, otherwise it will try to establish492* a TCP connection on port 7 (Echo) of the destination host.493* <p>494* The timeout value, in milliseconds, indicates the maximum amount of time495* the try should take. If the operation times out before getting an496* answer, the host is deemed unreachable. A negative value will result497* in an IllegalArgumentException being thrown.498*499* @param timeout the time, in milliseconds, before the call aborts500* @return a {@code boolean} indicating if the address is reachable.501* @throws IOException if a network error occurs502* @throws IllegalArgumentException if {@code timeout} is negative.503* @since 1.5504*/505public boolean isReachable(int timeout) throws IOException {506return isReachable(null, 0 , timeout);507}508509/**510* Test whether that address is reachable. Best effort is made by the511* implementation to try to reach the host, but firewalls and server512* configuration may block requests resulting in a unreachable status513* while some specific ports may be accessible.514* A typical implementation will use ICMP ECHO REQUESTs if the515* privilege can be obtained, otherwise it will try to establish516* a TCP connection on port 7 (Echo) of the destination host.517* <p>518* The {@code network interface} and {@code ttl} parameters519* let the caller specify which network interface the test will go through520* and the maximum number of hops the packets should go through.521* A negative value for the {@code ttl} will result in an522* IllegalArgumentException being thrown.523* <p>524* The timeout value, in milliseconds, indicates the maximum amount of time525* the try should take. If the operation times out before getting an526* answer, the host is deemed unreachable. A negative value will result527* in an IllegalArgumentException being thrown.528*529* @param netif the NetworkInterface through which the530* test will be done, or null for any interface531* @param ttl the maximum numbers of hops to try or 0 for the532* default533* @param timeout the time, in milliseconds, before the call aborts534* @throws IllegalArgumentException if either {@code timeout}535* or {@code ttl} are negative.536* @return a {@code boolean} indicating if the address is reachable.537* @throws IOException if a network error occurs538* @since 1.5539*/540public boolean isReachable(NetworkInterface netif, int ttl,541int timeout) throws IOException {542if (ttl < 0)543throw new IllegalArgumentException("ttl can't be negative");544if (timeout < 0)545throw new IllegalArgumentException("timeout can't be negative");546547return impl.isReachable(this, timeout, netif, ttl);548}549550/**551* Gets the host name for this IP address.552*553* <p>If this InetAddress was created with a host name,554* this host name will be remembered and returned;555* otherwise, a reverse name lookup will be performed556* and the result will be returned based on the system557* configured name lookup service. If a lookup of the name service558* is required, call559* {@link #getCanonicalHostName() getCanonicalHostName}.560*561* <p>If there is a security manager, its562* {@code checkConnect} method is first called563* with the hostname and {@code -1}564* as its arguments to see if the operation is allowed.565* If the operation is not allowed, it will return566* the textual representation of the IP address.567*568* @return the host name for this IP address, or if the operation569* is not allowed by the security check, the textual570* representation of the IP address.571*572* @see InetAddress#getCanonicalHostName573* @see SecurityManager#checkConnect574*/575public String getHostName() {576return getHostName(true);577}578579/**580* Returns the hostname for this address.581* If the host is equal to null, then this address refers to any582* of the local machine's available network addresses.583* this is package private so SocketPermission can make calls into584* here without a security check.585*586* <p>If there is a security manager, this method first587* calls its {@code checkConnect} method588* with the hostname and {@code -1}589* as its arguments to see if the calling code is allowed to know590* the hostname for this IP address, i.e., to connect to the host.591* If the operation is not allowed, it will return592* the textual representation of the IP address.593*594* @return the host name for this IP address, or if the operation595* is not allowed by the security check, the textual596* representation of the IP address.597*598* @param check make security check if true599*600* @see SecurityManager#checkConnect601*/602String getHostName(boolean check) {603if (holder().getHostName() == null) {604holder().hostName = InetAddress.getHostFromNameService(this, check);605}606return holder().getHostName();607}608609/**610* Gets the fully qualified domain name for this IP address.611* Best effort method, meaning we may not be able to return612* the FQDN depending on the underlying system configuration.613*614* <p>If there is a security manager, this method first615* calls its {@code checkConnect} method616* with the hostname and {@code -1}617* as its arguments to see if the calling code is allowed to know618* the hostname for this IP address, i.e., to connect to the host.619* If the operation is not allowed, it will return620* the textual representation of the IP address.621*622* @return the fully qualified domain name for this IP address,623* or if the operation is not allowed by the security check,624* the textual representation of the IP address.625*626* @see SecurityManager#checkConnect627*628* @since 1.4629*/630public String getCanonicalHostName() {631String value = canonicalHostName;632if (value == null)633canonicalHostName = value =634InetAddress.getHostFromNameService(this, true);635return value;636}637638/**639* Returns the hostname for this address.640*641* <p>If there is a security manager, this method first642* calls its {@code checkConnect} method643* with the hostname and {@code -1}644* as its arguments to see if the calling code is allowed to know645* the hostname for this IP address, i.e., to connect to the host.646* If the operation is not allowed, it will return647* the textual representation of the IP address.648*649* @return the host name for this IP address, or if the operation650* is not allowed by the security check, the textual651* representation of the IP address.652*653* @param check make security check if true654*655* @see SecurityManager#checkConnect656*/657private static String getHostFromNameService(InetAddress addr, boolean check) {658String host = null;659try {660// first lookup the hostname661host = nameService.getHostByAddr(addr.getAddress());662663/* check to see if calling code is allowed to know664* the hostname for this IP address, ie, connect to the host665*/666if (check) {667@SuppressWarnings("removal")668SecurityManager sec = System.getSecurityManager();669if (sec != null) {670sec.checkConnect(host, -1);671}672}673674/* now get all the IP addresses for this hostname,675* and make sure one of them matches the original IP676* address. We do this to try and prevent spoofing.677*/678679InetAddress[] arr = InetAddress.getAllByName0(host, check);680boolean ok = false;681682if(arr != null) {683for(int i = 0; !ok && i < arr.length; i++) {684ok = addr.equals(arr[i]);685}686}687688//XXX: if it looks a spoof just return the address?689if (!ok) {690host = addr.getHostAddress();691return host;692}693} catch (SecurityException e) {694host = addr.getHostAddress();695} catch (UnknownHostException e) {696host = addr.getHostAddress();697// let next provider resolve the hostname698}699return host;700}701702/**703* Returns the raw IP address of this {@code InetAddress}704* object. The result is in network byte order: the highest order705* byte of the address is in {@code getAddress()[0]}.706*707* @return the raw IP address of this object.708*/709public byte[] getAddress() {710return null;711}712713/**714* Returns the IP address string in textual presentation.715*716* @return the raw IP address in a string format.717* @since 1.0.2718*/719public String getHostAddress() {720return null;721}722723/**724* Returns a hashcode for this IP address.725*726* @return a hash code value for this IP address.727*/728public int hashCode() {729return -1;730}731732/**733* Compares this object against the specified object.734* The result is {@code true} if and only if the argument is735* not {@code null} and it represents the same IP address as736* this object.737* <p>738* Two instances of {@code InetAddress} represent the same IP739* address if the length of the byte arrays returned by740* {@code getAddress} is the same for both, and each of the741* array components is the same for the byte arrays.742*743* @param obj the object to compare against.744* @return {@code true} if the objects are the same;745* {@code false} otherwise.746* @see java.net.InetAddress#getAddress()747*/748public boolean equals(Object obj) {749return false;750}751752/**753* Converts this IP address to a {@code String}. The754* string returned is of the form: hostname / literal IP755* address.756*757* If the host name is unresolved, no reverse name service lookup758* is performed. The hostname part will be represented by an empty string.759*760* @return a string representation of this IP address.761*/762public String toString() {763String hostName = holder().getHostName();764return Objects.toString(hostName, "")765+ "/" + getHostAddress();766}767768// mapping from host name to Addresses - either NameServiceAddresses (while769// still being looked-up by NameService(s)) or CachedAddresses when cached770private static final ConcurrentMap<String, Addresses> cache =771new ConcurrentHashMap<>();772773// CachedAddresses that have to expire are kept ordered in this NavigableSet774// which is scanned on each access775private static final NavigableSet<CachedAddresses> expirySet =776new ConcurrentSkipListSet<>();777778// common interface779private interface Addresses {780InetAddress[] get() throws UnknownHostException;781}782783// a holder for cached addresses with required metadata784private static final class CachedAddresses implements Addresses, Comparable<CachedAddresses> {785private static final AtomicLong seq = new AtomicLong();786final String host;787final InetAddress[] inetAddresses;788final long expiryTime; // time of expiry (in terms of System.nanoTime())789final long id = seq.incrementAndGet(); // each instance is unique790791CachedAddresses(String host, InetAddress[] inetAddresses, long expiryTime) {792this.host = host;793this.inetAddresses = inetAddresses;794this.expiryTime = expiryTime;795}796797@Override798public InetAddress[] get() throws UnknownHostException {799if (inetAddresses == null) {800throw new UnknownHostException(host);801}802return inetAddresses;803}804805@Override806public int compareTo(CachedAddresses other) {807// natural order is expiry time -808// compare difference of expiry times rather than809// expiry times directly, to avoid possible overflow.810// (see System.nanoTime() recommendations...)811long diff = this.expiryTime - other.expiryTime;812if (diff < 0L) return -1;813if (diff > 0L) return 1;814// ties are broken using unique id815return Long.compare(this.id, other.id);816}817}818819// a name service lookup based Addresses implementation which replaces itself820// in cache when the result is obtained821private static final class NameServiceAddresses implements Addresses {822private final String host;823private final InetAddress reqAddr;824825NameServiceAddresses(String host, InetAddress reqAddr) {826this.host = host;827this.reqAddr = reqAddr;828}829830@Override831public InetAddress[] get() throws UnknownHostException {832Addresses addresses;833// only one thread is doing lookup to name service834// for particular host at any time.835synchronized (this) {836// re-check that we are still us + re-install us if slot empty837addresses = cache.putIfAbsent(host, this);838if (addresses == null) {839// this can happen when we were replaced by CachedAddresses in840// some other thread, then CachedAddresses expired and were841// removed from cache while we were waiting for lock...842addresses = this;843}844// still us ?845if (addresses == this) {846// lookup name services847InetAddress[] inetAddresses;848UnknownHostException ex;849int cachePolicy;850try {851inetAddresses = getAddressesFromNameService(host, reqAddr);852ex = null;853cachePolicy = InetAddressCachePolicy.get();854} catch (UnknownHostException uhe) {855inetAddresses = null;856ex = uhe;857cachePolicy = InetAddressCachePolicy.getNegative();858}859// remove or replace us with cached addresses according to cachePolicy860if (cachePolicy == InetAddressCachePolicy.NEVER) {861cache.remove(host, this);862} else {863CachedAddresses cachedAddresses = new CachedAddresses(864host,865inetAddresses,866cachePolicy == InetAddressCachePolicy.FOREVER867? 0L868// cachePolicy is in [s] - we need [ns]869: System.nanoTime() + 1000_000_000L * cachePolicy870);871if (cache.replace(host, this, cachedAddresses) &&872cachePolicy != InetAddressCachePolicy.FOREVER) {873// schedule expiry874expirySet.add(cachedAddresses);875}876}877if (inetAddresses == null) {878throw ex == null ? new UnknownHostException(host) : ex;879}880return inetAddresses;881}882// else addresses != this883}884// delegate to different addresses when we are already replaced885// but outside of synchronized block to avoid any chance of dead-locking886return addresses.get();887}888}889890/**891* NameService provides host and address lookup service892*893* @since 9894*/895private interface NameService {896897/**898* Lookup a host mapping by name. Retrieve the IP addresses899* associated with a host900*901* @param host the specified hostname902* @return array of IP addresses for the requested host903* @throws UnknownHostException904* if no IP address for the {@code host} could be found905*/906InetAddress[] lookupAllHostAddr(String host)907throws UnknownHostException;908909/**910* Lookup the host corresponding to the IP address provided911*912* @param addr byte array representing an IP address913* @return {@code String} representing the host name mapping914* @throws UnknownHostException915* if no host found for the specified IP address916*/917String getHostByAddr(byte[] addr) throws UnknownHostException;918919}920921/**922* The default NameService implementation, which delegates to the underlying923* OS network libraries to resolve host address mappings.924*925* @since 9926*/927private static final class PlatformNameService implements NameService {928929public InetAddress[] lookupAllHostAddr(String host)930throws UnknownHostException931{932return impl.lookupAllHostAddr(host);933}934935public String getHostByAddr(byte[] addr)936throws UnknownHostException937{938return impl.getHostByAddr(addr);939}940}941942/**943* The HostsFileNameService provides host address mapping944* by reading the entries in a hosts file, which is specified by945* {@code jdk.net.hosts.file} system property946*947* <p>The file format is that which corresponds with the /etc/hosts file948* IP Address host alias list.949*950* <p>When the file lookup is enabled it replaces the default NameService951* implementation952*953* @since 9954*/955private static final class HostsFileNameService implements NameService {956957private static final InetAddress[] EMPTY_ARRAY = new InetAddress[0];958959// Specify if only IPv4 addresses should be returned by HostsFileService implementation960private static final boolean preferIPv4Stack = Boolean.parseBoolean(961GetPropertyAction.privilegedGetProperty("java.net.preferIPv4Stack"));962963private final String hostsFile;964965public HostsFileNameService(String hostsFileName) {966this.hostsFile = hostsFileName;967}968969/**970* Lookup the host name corresponding to the IP address provided.971* Search the configured host file a host name corresponding to972* the specified IP address.973*974* @param addr byte array representing an IP address975* @return {@code String} representing the host name mapping976* @throws UnknownHostException977* if no host found for the specified IP address978*/979@Override980public String getHostByAddr(byte[] addr) throws UnknownHostException {981String hostEntry;982String host = null;983984try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),985UTF_8.INSTANCE))986{987while (hostsFileScanner.hasNextLine()) {988hostEntry = hostsFileScanner.nextLine();989if (!hostEntry.startsWith("#")) {990hostEntry = removeComments(hostEntry);991String[] mapping = hostEntry.split("\\s+");992if (mapping.length >= 2 &&993Arrays.equals(addr, createAddressByteArray(mapping[0]))) {994host = mapping[1];995break;996}997}998}999} catch (IOException e) {1000throw new UnknownHostException("Unable to resolve address "1001+ Arrays.toString(addr) + " as hosts file " + hostsFile1002+ " not found ");1003}10041005if ((host == null) || (host.isEmpty()) || (host.equals(" "))) {1006throw new UnknownHostException("Requested address "1007+ Arrays.toString(addr)1008+ " resolves to an invalid entry in hosts file "1009+ hostsFile);1010}1011return host;1012}10131014/**1015* <p>Lookup a host mapping by name. Retrieve the IP addresses1016* associated with a host.1017*1018* <p>Search the configured hosts file for the addresses associated1019* with the specified host name.1020*1021* @param host the specified hostname1022* @return array of IP addresses for the requested host1023* @throws UnknownHostException1024* if no IP address for the {@code host} could be found1025*/1026public InetAddress[] lookupAllHostAddr(String host)1027throws UnknownHostException {1028String hostEntry;1029String addrStr;1030byte addr[];1031List<InetAddress> inetAddresses = new ArrayList<>();1032List<InetAddress> inet4Addresses = new ArrayList<>();1033List<InetAddress> inet6Addresses = new ArrayList<>();10341035// lookup the file and create a list InetAddress for the specified host1036try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),1037UTF_8.INSTANCE)) {1038while (hostsFileScanner.hasNextLine()) {1039hostEntry = hostsFileScanner.nextLine();1040if (!hostEntry.startsWith("#")) {1041hostEntry = removeComments(hostEntry);1042if (hostEntry.contains(host)) {1043addrStr = extractHostAddr(hostEntry, host);1044if ((addrStr != null) && (!addrStr.isEmpty())) {1045addr = createAddressByteArray(addrStr);1046if (addr != null) {1047InetAddress address = InetAddress.getByAddress(host, addr);1048inetAddresses.add(address);1049if (address instanceof Inet4Address) {1050inet4Addresses.add(address);1051}1052if (address instanceof Inet6Address) {1053inet6Addresses.add(address);1054}1055}1056}1057}1058}1059}1060} catch (IOException e) {1061throw new UnknownHostException("Unable to resolve host " + host1062+ " as hosts file " + hostsFile + " not found ");1063}10641065List<InetAddress> res;1066// If "preferIPv4Stack" system property is set to "true" then return1067// only IPv4 addresses1068if (preferIPv4Stack) {1069res = inet4Addresses;1070} else {1071// Otherwise, analyse "preferIPv6Addresses" value1072res = switch (preferIPv6Address) {1073case PREFER_IPV4_VALUE -> concatAddresses(inet4Addresses, inet6Addresses);1074case PREFER_IPV6_VALUE -> concatAddresses(inet6Addresses, inet4Addresses);1075default -> inetAddresses;1076};1077}10781079if (res.isEmpty()) {1080throw new UnknownHostException("Unable to resolve host " + host1081+ " in hosts file " + hostsFile);1082}1083return res.toArray(EMPTY_ARRAY);1084}10851086private static List<InetAddress> concatAddresses(List<InetAddress> firstPart,1087List<InetAddress> secondPart) {1088List<InetAddress> result = new ArrayList<>(firstPart);1089result.addAll(secondPart);1090return result;1091}10921093private String removeComments(String hostsEntry) {1094String filteredEntry = hostsEntry;1095int hashIndex;10961097if ((hashIndex = hostsEntry.indexOf("#")) != -1) {1098filteredEntry = hostsEntry.substring(0, hashIndex);1099}1100return filteredEntry;1101}11021103private byte [] createAddressByteArray(String addrStr) {1104byte[] addrArray;1105// check if IPV4 address - most likely1106try {1107addrArray = IPAddressUtil.validateNumericFormatV4(addrStr);1108} catch (IllegalArgumentException iae) {1109return null;1110}1111if (addrArray == null) {1112addrArray = IPAddressUtil.textToNumericFormatV6(addrStr);1113}1114return addrArray;1115}11161117/** host to ip address mapping */1118private String extractHostAddr(String hostEntry, String host) {1119String[] mapping = hostEntry.split("\\s+");1120String hostAddr = null;11211122if (mapping.length >= 2) {1123// look at the host aliases1124for (int i = 1; i < mapping.length; i++) {1125if (mapping[i].equalsIgnoreCase(host)) {1126hostAddr = mapping[0];1127}1128}1129}1130return hostAddr;1131}1132}11331134static final InetAddressImpl impl;11351136static {1137// create the impl1138impl = InetAddressImplFactory.create();11391140// create name service1141nameService = createNameService();1142}11431144/**1145* Create an instance of the NameService interface based on1146* the setting of the {@code jdk.net.hosts.file} system property.1147*1148* <p>The default NameService is the PlatformNameService, which typically1149* delegates name and address resolution calls to the underlying1150* OS network libraries.1151*1152* <p> A HostsFileNameService is created if the {@code jdk.net.hosts.file}1153* system property is set. If the specified file doesn't exist, the name or1154* address lookup will result in an UnknownHostException. Thus, non existent1155* hosts file is handled as if the file is empty.1156*1157* @return a NameService1158*/1159private static NameService createNameService() {11601161String hostsFileName =1162GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file");1163NameService theNameService;1164if (hostsFileName != null) {1165theNameService = new HostsFileNameService(hostsFileName);1166} else {1167theNameService = new PlatformNameService();1168}1169return theNameService;1170}11711172/**1173* Creates an InetAddress based on the provided host name and IP address.1174* No name service is checked for the validity of the address.1175*1176* <p> The host name can either be a machine name, such as1177* "{@code www.example.com}", or a textual representation of its IP1178* address.1179* <p> No validity checking is done on the host name either.1180*1181* <p> If addr specifies an IPv4 address an instance of Inet4Address1182* will be returned; otherwise, an instance of Inet6Address1183* will be returned.1184*1185* <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array1186* must be 16 bytes long1187*1188* @param host the specified host1189* @param addr the raw IP address in network byte order1190* @return an InetAddress object created from the raw IP address.1191* @throws UnknownHostException if IP address is of illegal length1192* @since 1.41193*/1194public static InetAddress getByAddress(String host, byte[] addr)1195throws UnknownHostException {1196if (host != null && !host.isEmpty() && host.charAt(0) == '[') {1197if (host.charAt(host.length()-1) == ']') {1198host = host.substring(1, host.length() -1);1199}1200}1201if (addr != null) {1202if (addr.length == Inet4Address.INADDRSZ) {1203return new Inet4Address(host, addr);1204} else if (addr.length == Inet6Address.INADDRSZ) {1205byte[] newAddr1206= IPAddressUtil.convertFromIPv4MappedAddress(addr);1207if (newAddr != null) {1208return new Inet4Address(host, newAddr);1209} else {1210return new Inet6Address(host, addr);1211}1212}1213}1214throw new UnknownHostException("addr is of illegal length");1215}121612171218/**1219* Determines the IP address of a host, given the host's name.1220*1221* <p> The host name can either be a machine name, such as1222* "{@code www.example.com}", or a textual representation of its1223* IP address. If a literal IP address is supplied, only the1224* validity of the address format is checked.1225*1226* <p> For {@code host} specified in literal IPv6 address,1227* either the form defined in RFC 2732 or the literal IPv6 address1228* format defined in RFC 2373 is accepted. IPv6 scoped addresses are also1229* supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv61230* scoped addresses.1231*1232* <p> If the host is {@code null} or {@code host.length()} is equal1233* to zero, then an {@code InetAddress} representing an address of the1234* loopback interface is returned.1235* See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>1236* section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>1237* section 2.5.3.1238*1239* <p> If there is a security manager, and {@code host} is not {@code null}1240* or {@code host.length() } is not equal to zero, the security manager's1241* {@code checkConnect} method is called with the hostname and {@code -1}1242* as its arguments to determine if the operation is allowed.1243*1244* @param host the specified host, or {@code null}.1245* @return an IP address for the given host name.1246* @throws UnknownHostException if no IP address for the1247* {@code host} could be found, or if a scope_id was specified1248* for a global IPv6 address.1249* @throws SecurityException if a security manager exists1250* and its checkConnect method doesn't allow the operation1251*/1252public static InetAddress getByName(String host)1253throws UnknownHostException {1254return InetAddress.getAllByName(host)[0];1255}12561257// called from deployment cache manager1258private static InetAddress getByName(String host, InetAddress reqAddr)1259throws UnknownHostException {1260return InetAddress.getAllByName(host, reqAddr)[0];1261}12621263/**1264* Given the name of a host, returns an array of its IP addresses,1265* based on the configured name service on the system.1266*1267* <p> The host name can either be a machine name, such as1268* "{@code www.example.com}", or a textual representation of its IP1269* address. If a literal IP address is supplied, only the1270* validity of the address format is checked.1271*1272* <p> For {@code host} specified in <i>literal IPv6 address</i>,1273* either the form defined in RFC 2732 or the literal IPv6 address1274* format defined in RFC 2373 is accepted. A literal IPv6 address may1275* also be qualified by appending a scoped zone identifier or scope_id.1276* The syntax and usage of scope_ids is described1277* <a href="Inet6Address.html#scoped">here</a>.1278*1279* <p> If the host is {@code null} or {@code host.length()} is equal1280* to zero, then an {@code InetAddress} representing an address of the1281* loopback interface is returned.1282* See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>1283* section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>1284* section 2.5.3. </p>1285*1286* <p> If there is a security manager, and {@code host} is not {@code null}1287* or {@code host.length() } is not equal to zero, the security manager's1288* {@code checkConnect} method is called with the hostname and {@code -1}1289* as its arguments to determine if the operation is allowed.1290*1291* @param host the name of the host, or {@code null}.1292* @return an array of all the IP addresses for a given host name.1293*1294* @throws UnknownHostException if no IP address for the1295* {@code host} could be found, or if a scope_id was specified1296* for a global IPv6 address.1297* @throws SecurityException if a security manager exists and its1298* {@code checkConnect} method doesn't allow the operation.1299*1300* @see SecurityManager#checkConnect1301*/1302public static InetAddress[] getAllByName(String host)1303throws UnknownHostException {1304return getAllByName(host, null);1305}13061307private static InetAddress[] getAllByName(String host, InetAddress reqAddr)1308throws UnknownHostException {13091310if (host == null || host.isEmpty()) {1311InetAddress[] ret = new InetAddress[1];1312ret[0] = impl.loopbackAddress();1313return ret;1314}13151316boolean ipv6Expected = false;1317if (host.charAt(0) == '[') {1318// This is supposed to be an IPv6 literal1319if (host.length() > 2 && host.charAt(host.length()-1) == ']') {1320host = host.substring(1, host.length() -1);1321ipv6Expected = true;1322} else {1323// This was supposed to be a IPv6 address, but it's not!1324throw new UnknownHostException(host + ": invalid IPv6 address");1325}1326}13271328// if host is an IP address, we won't do further lookup1329if (IPAddressUtil.digit(host.charAt(0), 16) != -11330|| (host.charAt(0) == ':')) {1331byte[] addr;1332int numericZone = -1;1333String ifname = null;1334// see if it is IPv4 address1335try {1336addr = IPAddressUtil.validateNumericFormatV4(host);1337} catch (IllegalArgumentException iae) {1338var uhe = new UnknownHostException(host);1339uhe.initCause(iae);1340throw uhe;1341}1342if (addr == null) {1343// This is supposed to be an IPv6 literal1344// Check if a numeric or string zone id is present1345int pos;1346if ((pos=host.indexOf ('%')) != -1) {1347numericZone = checkNumericZone (host);1348if (numericZone == -1) { /* remainder of string must be an ifname */1349ifname = host.substring (pos+1);1350}1351}1352if ((addr = IPAddressUtil.textToNumericFormatV6(host)) == null && host.contains(":")) {1353throw new UnknownHostException(host + ": invalid IPv6 address");1354}1355} else if (ipv6Expected) {1356// Means an IPv4 literal between brackets!1357throw new UnknownHostException("["+host+"]");1358}1359InetAddress[] ret = new InetAddress[1];1360if(addr != null) {1361if (addr.length == Inet4Address.INADDRSZ) {1362ret[0] = new Inet4Address(null, addr);1363} else {1364if (ifname != null) {1365ret[0] = new Inet6Address(null, addr, ifname);1366} else {1367ret[0] = new Inet6Address(null, addr, numericZone);1368}1369}1370return ret;1371}1372} else if (ipv6Expected) {1373// We were expecting an IPv6 Literal, but got something else1374throw new UnknownHostException("["+host+"]");1375}1376return getAllByName0(host, reqAddr, true, true);1377}13781379/**1380* Returns the loopback address.1381* <p>1382* The InetAddress returned will represent the IPv41383* loopback address, 127.0.0.1, or the IPv6 loopback1384* address, ::1. The IPv4 loopback address returned1385* is only one of many in the form 127.*.*.*1386*1387* @return the InetAddress loopback instance.1388* @since 1.71389*/1390public static InetAddress getLoopbackAddress() {1391return impl.loopbackAddress();1392}139313941395/**1396* check if the literal address string has %nn appended1397* returns -1 if not, or the numeric value otherwise.1398*1399* %nn may also be a string that represents the displayName of1400* a currently available NetworkInterface.1401*/1402private static int checkNumericZone (String s) throws UnknownHostException {1403int percent = s.indexOf ('%');1404int slen = s.length();1405int digit, zone=0;1406if (percent == -1) {1407return -1;1408}1409for (int i=percent+1; i<slen; i++) {1410char c = s.charAt(i);1411if (c == ']') {1412if (i == percent+1) {1413/* empty per-cent field */1414return -1;1415}1416break;1417}1418if ((digit = Character.digit (c, 10)) < 0) {1419return -1;1420}1421zone = (zone * 10) + digit;1422}1423return zone;1424}14251426private static InetAddress[] getAllByName0 (String host)1427throws UnknownHostException1428{1429return getAllByName0(host, true);1430}14311432/**1433* package private so SocketPermission can call it1434*/1435static InetAddress[] getAllByName0 (String host, boolean check)1436throws UnknownHostException {1437return getAllByName0 (host, null, check, true);1438}14391440/**1441* Designated lookup method.1442*1443* @param host host name to look up1444* @param reqAddr requested address to be the 1st in returned array1445* @param check perform security check1446* @param useCache use cached value if not expired else always1447* perform name service lookup (and cache the result)1448* @return array of InetAddress(es)1449* @throws UnknownHostException if host name is not found1450*/1451private static InetAddress[] getAllByName0(String host,1452InetAddress reqAddr,1453boolean check,1454boolean useCache)1455throws UnknownHostException {14561457/* If it gets here it is presumed to be a hostname */14581459/* make sure the connection to the host is allowed, before we1460* give out a hostname1461*/1462if (check) {1463@SuppressWarnings("removal")1464SecurityManager security = System.getSecurityManager();1465if (security != null) {1466security.checkConnect(host, -1);1467}1468}14691470// remove expired addresses from cache - expirySet keeps them ordered1471// by expiry time so we only need to iterate the prefix of the NavigableSet...1472long now = System.nanoTime();1473for (CachedAddresses caddrs : expirySet) {1474// compare difference of time instants rather than1475// time instants directly, to avoid possible overflow.1476// (see System.nanoTime() recommendations...)1477if ((caddrs.expiryTime - now) < 0L) {1478// ConcurrentSkipListSet uses weakly consistent iterator,1479// so removing while iterating is OK...1480if (expirySet.remove(caddrs)) {1481// ... remove from cache1482cache.remove(caddrs.host, caddrs);1483}1484} else {1485// we encountered 1st element that expires in future1486break;1487}1488}14891490// look-up or remove from cache1491Addresses addrs;1492if (useCache) {1493addrs = cache.get(host);1494} else {1495addrs = cache.remove(host);1496if (addrs != null) {1497if (addrs instanceof CachedAddresses) {1498// try removing from expirySet too if CachedAddresses1499expirySet.remove(addrs);1500}1501addrs = null;1502}1503}15041505if (addrs == null) {1506// create a NameServiceAddresses instance which will look up1507// the name service and install it within cache...1508Addresses oldAddrs = cache.putIfAbsent(1509host,1510addrs = new NameServiceAddresses(host, reqAddr)1511);1512if (oldAddrs != null) { // lost putIfAbsent race1513addrs = oldAddrs;1514}1515}15161517// ask Addresses to get an array of InetAddress(es) and clone it1518return addrs.get().clone();1519}15201521static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)1522throws UnknownHostException1523{1524InetAddress[] addresses = null;1525UnknownHostException ex = null;15261527try {1528addresses = nameService.lookupAllHostAddr(host);1529} catch (UnknownHostException uhe) {1530if (host.equalsIgnoreCase("localhost")) {1531addresses = new InetAddress[] { impl.loopbackAddress() };1532}1533else {1534ex = uhe;1535}1536}15371538if (addresses == null) {1539throw ex == null ? new UnknownHostException(host) : ex;1540}15411542// More to do?1543if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {1544// Find it?1545int i = 1;1546for (; i < addresses.length; i++) {1547if (addresses[i].equals(reqAddr)) {1548break;1549}1550}1551// Rotate1552if (i < addresses.length) {1553InetAddress tmp, tmp2 = reqAddr;1554for (int j = 0; j < i; j++) {1555tmp = addresses[j];1556addresses[j] = tmp2;1557tmp2 = tmp;1558}1559addresses[i] = tmp2;1560}1561}15621563return addresses;1564}15651566/**1567* Returns an {@code InetAddress} object given the raw IP address .1568* The argument is in network byte order: the highest order1569* byte of the address is in {@code getAddress()[0]}.1570*1571* <p> This method doesn't block, i.e. no reverse name service lookup1572* is performed.1573*1574* <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array1575* must be 16 bytes long1576*1577* @param addr the raw IP address in network byte order1578* @return an InetAddress object created from the raw IP address.1579* @throws UnknownHostException if IP address is of illegal length1580* @since 1.41581*/1582public static InetAddress getByAddress(byte[] addr)1583throws UnknownHostException {1584return getByAddress(null, addr);1585}15861587private static final class CachedLocalHost {1588final String host;1589final InetAddress addr;1590final long expiryTime = System.nanoTime() + 5000_000_000L; // now + 5s;15911592CachedLocalHost(String host, InetAddress addr) {1593this.host = host;1594this.addr = addr;1595}1596}15971598private static volatile CachedLocalHost cachedLocalHost;15991600/**1601* Returns the address of the local host. This is achieved by retrieving1602* the name of the host from the system, then resolving that name into1603* an {@code InetAddress}.1604*1605* <P>Note: The resolved address may be cached for a short period of time.1606* </P>1607*1608* <p>If there is a security manager, its1609* {@code checkConnect} method is called1610* with the local host name and {@code -1}1611* as its arguments to see if the operation is allowed.1612* If the operation is not allowed, an InetAddress representing1613* the loopback address is returned.1614*1615* @return the address of the local host.1616*1617* @throws UnknownHostException if the local host name could not1618* be resolved into an address.1619*1620* @see SecurityManager#checkConnect1621* @see java.net.InetAddress#getByName(java.lang.String)1622*/1623public static InetAddress getLocalHost() throws UnknownHostException {16241625@SuppressWarnings("removal")1626SecurityManager security = System.getSecurityManager();1627try {1628// is cached data still valid?1629CachedLocalHost clh = cachedLocalHost;1630if (clh != null && (clh.expiryTime - System.nanoTime()) >= 0L) {1631if (security != null) {1632security.checkConnect(clh.host, -1);1633}1634return clh.addr;1635}16361637String local = impl.getLocalHostName();16381639if (security != null) {1640security.checkConnect(local, -1);1641}16421643InetAddress localAddr;1644if (local.equals("localhost")) {1645// shortcut for "localhost" host name1646localAddr = impl.loopbackAddress();1647} else {1648// call getAllByName0 without security checks and1649// without using cached data1650try {1651localAddr = getAllByName0(local, null, false, false)[0];1652} catch (UnknownHostException uhe) {1653// Rethrow with a more informative error message.1654UnknownHostException uhe2 =1655new UnknownHostException(local + ": " +1656uhe.getMessage());1657uhe2.initCause(uhe);1658throw uhe2;1659}1660}1661cachedLocalHost = new CachedLocalHost(local, localAddr);1662return localAddr;1663} catch (java.lang.SecurityException e) {1664return impl.loopbackAddress();1665}1666}16671668/**1669* Perform class load-time initializations.1670*/1671private static native void init();167216731674/*1675* Returns the InetAddress representing anyLocalAddress1676* (typically 0.0.0.0 or ::0)1677*/1678static InetAddress anyLocalAddress() {1679return impl.anyLocalAddress();1680}16811682/*1683* Load and instantiate an underlying impl class1684*/1685static InetAddressImpl loadImpl(String implName) {1686Object impl = null;16871688/*1689* Property "impl.prefix" will be prepended to the classname1690* of the implementation object we instantiate, to which we1691* delegate the real work (like native methods). This1692* property can vary across implementations of the java.1693* classes. The default is an empty String "".1694*/1695String prefix = GetPropertyAction.privilegedGetProperty("impl.prefix", "");1696try {1697@SuppressWarnings("deprecation")1698Object tmp = Class.forName("java.net." + prefix + implName).newInstance();1699impl = tmp;1700} catch (ClassNotFoundException e) {1701System.err.println("Class not found: java.net." + prefix +1702implName + ":\ncheck impl.prefix property " +1703"in your properties file.");1704} catch (InstantiationException e) {1705System.err.println("Could not instantiate: java.net." + prefix +1706implName + ":\ncheck impl.prefix property " +1707"in your properties file.");1708} catch (IllegalAccessException e) {1709System.err.println("Cannot access class: java.net." + prefix +1710implName + ":\ncheck impl.prefix property " +1711"in your properties file.");1712}17131714if (impl == null) {1715try {1716@SuppressWarnings("deprecation")1717Object tmp = Class.forName(implName).newInstance();1718impl = tmp;1719} catch (Exception e) {1720throw new Error("System property impl.prefix incorrect");1721}1722}17231724return (InetAddressImpl) impl;1725}17261727/**1728* Initializes an empty InetAddress.1729*/1730@java.io.Serial1731private void readObjectNoData () {1732if (getClass().getClassLoader() != null) {1733throw new SecurityException ("invalid address type");1734}1735}17361737private static final jdk.internal.misc.Unsafe UNSAFE1738= jdk.internal.misc.Unsafe.getUnsafe();1739private static final long FIELDS_OFFSET1740= UNSAFE.objectFieldOffset(InetAddress.class, "holder");17411742/**1743* Restores the state of this object from the stream.1744*1745* @param s the {@code ObjectInputStream} from which data is read1746* @throws IOException if an I/O error occurs1747* @throws ClassNotFoundException if a serialized class cannot be loaded1748*/1749@java.io.Serial1750private void readObject (ObjectInputStream s) throws1751IOException, ClassNotFoundException {1752if (getClass().getClassLoader() != null) {1753throw new SecurityException ("invalid address type");1754}1755GetField gf = s.readFields();1756String host = (String)gf.get("hostName", null);1757int address = gf.get("address", 0);1758int family = gf.get("family", 0);1759if (family != IPv4 && family != IPv6) {1760throw new InvalidObjectException("invalid address family type: " + family);1761}1762InetAddressHolder h = new InetAddressHolder(host, address, family);1763UNSAFE.putReference(this, FIELDS_OFFSET, h);1764}17651766/* needed because the serializable fields no longer exist */17671768/**1769* @serialField hostName String the hostname for this address1770* @serialField address int holds a 32-bit IPv4 address.1771* @serialField family int specifies the address family type, for instance,1772* {@code '1'} for IPv4 addresses, and {@code '2'} for IPv6 addresses.1773*/1774@java.io.Serial1775private static final ObjectStreamField[] serialPersistentFields = {1776new ObjectStreamField("hostName", String.class),1777new ObjectStreamField("address", int.class),1778new ObjectStreamField("family", int.class),1779};17801781/**1782* Writes the state of this object to the stream.1783*1784* @param s the {@code ObjectOutputStream} to which data is written1785* @throws IOException if an I/O error occurs1786*/1787@java.io.Serial1788private void writeObject (ObjectOutputStream s) throws1789IOException {1790if (getClass().getClassLoader() != null) {1791throw new SecurityException ("invalid address type");1792}1793PutField pf = s.putFields();1794pf.put("hostName", holder().getHostName());1795pf.put("address", holder().getAddress());1796pf.put("family", holder().getFamily());1797s.writeFields();1798}1799}18001801/*1802* Simple factory to create the impl1803*/1804class InetAddressImplFactory {18051806static InetAddressImpl create() {1807return InetAddress.loadImpl(isIPv6Supported() ?1808"Inet6AddressImpl" : "Inet4AddressImpl");1809}18101811static native boolean isIPv6Supported();1812}181318141815