Path: blob/master/src/java.base/share/classes/java/net/InetAddress.java
41152 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 likely1106addrArray = IPAddressUtil.textToNumericFormatV4(addrStr);1107if (addrArray == null) {1108addrArray = IPAddressUtil.textToNumericFormatV6(addrStr);1109}1110return addrArray;1111}11121113/** host to ip address mapping */1114private String extractHostAddr(String hostEntry, String host) {1115String[] mapping = hostEntry.split("\\s+");1116String hostAddr = null;11171118if (mapping.length >= 2) {1119// look at the host aliases1120for (int i = 1; i < mapping.length; i++) {1121if (mapping[i].equalsIgnoreCase(host)) {1122hostAddr = mapping[0];1123}1124}1125}1126return hostAddr;1127}1128}11291130static final InetAddressImpl impl;11311132static {1133// create the impl1134impl = InetAddressImplFactory.create();11351136// create name service1137nameService = createNameService();1138}11391140/**1141* Create an instance of the NameService interface based on1142* the setting of the {@code jdk.net.hosts.file} system property.1143*1144* <p>The default NameService is the PlatformNameService, which typically1145* delegates name and address resolution calls to the underlying1146* OS network libraries.1147*1148* <p> A HostsFileNameService is created if the {@code jdk.net.hosts.file}1149* system property is set. If the specified file doesn't exist, the name or1150* address lookup will result in an UnknownHostException. Thus, non existent1151* hosts file is handled as if the file is empty.1152*1153* @return a NameService1154*/1155private static NameService createNameService() {11561157String hostsFileName =1158GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file");1159NameService theNameService;1160if (hostsFileName != null) {1161theNameService = new HostsFileNameService(hostsFileName);1162} else {1163theNameService = new PlatformNameService();1164}1165return theNameService;1166}11671168/**1169* Creates an InetAddress based on the provided host name and IP address.1170* No name service is checked for the validity of the address.1171*1172* <p> The host name can either be a machine name, such as1173* "{@code www.example.com}", or a textual representation of its IP1174* address.1175* <p> No validity checking is done on the host name either.1176*1177* <p> If addr specifies an IPv4 address an instance of Inet4Address1178* will be returned; otherwise, an instance of Inet6Address1179* will be returned.1180*1181* <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array1182* must be 16 bytes long1183*1184* @param host the specified host1185* @param addr the raw IP address in network byte order1186* @return an InetAddress object created from the raw IP address.1187* @throws UnknownHostException if IP address is of illegal length1188* @since 1.41189*/1190public static InetAddress getByAddress(String host, byte[] addr)1191throws UnknownHostException {1192if (host != null && !host.isEmpty() && host.charAt(0) == '[') {1193if (host.charAt(host.length()-1) == ']') {1194host = host.substring(1, host.length() -1);1195}1196}1197if (addr != null) {1198if (addr.length == Inet4Address.INADDRSZ) {1199return new Inet4Address(host, addr);1200} else if (addr.length == Inet6Address.INADDRSZ) {1201byte[] newAddr1202= IPAddressUtil.convertFromIPv4MappedAddress(addr);1203if (newAddr != null) {1204return new Inet4Address(host, newAddr);1205} else {1206return new Inet6Address(host, addr);1207}1208}1209}1210throw new UnknownHostException("addr is of illegal length");1211}121212131214/**1215* Determines the IP address of a host, given the host's name.1216*1217* <p> The host name can either be a machine name, such as1218* "{@code www.example.com}", or a textual representation of its1219* IP address. If a literal IP address is supplied, only the1220* validity of the address format is checked.1221*1222* <p> For {@code host} specified in literal IPv6 address,1223* either the form defined in RFC 2732 or the literal IPv6 address1224* format defined in RFC 2373 is accepted. IPv6 scoped addresses are also1225* supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv61226* scoped addresses.1227*1228* <p> If the host is {@code null} or {@code host.length()} is equal1229* to zero, then an {@code InetAddress} representing an address of the1230* loopback interface is returned.1231* See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>1232* section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>1233* section 2.5.3.1234*1235* <p> If there is a security manager, and {@code host} is not {@code null}1236* or {@code host.length() } is not equal to zero, the security manager's1237* {@code checkConnect} method is called with the hostname and {@code -1}1238* as its arguments to determine if the operation is allowed.1239*1240* @param host the specified host, or {@code null}.1241* @return an IP address for the given host name.1242* @throws UnknownHostException if no IP address for the1243* {@code host} could be found, or if a scope_id was specified1244* for a global IPv6 address.1245* @throws SecurityException if a security manager exists1246* and its checkConnect method doesn't allow the operation1247*/1248public static InetAddress getByName(String host)1249throws UnknownHostException {1250return InetAddress.getAllByName(host)[0];1251}12521253// called from deployment cache manager1254private static InetAddress getByName(String host, InetAddress reqAddr)1255throws UnknownHostException {1256return InetAddress.getAllByName(host, reqAddr)[0];1257}12581259/**1260* Given the name of a host, returns an array of its IP addresses,1261* based on the configured name service on the system.1262*1263* <p> The host name can either be a machine name, such as1264* "{@code www.example.com}", or a textual representation of its IP1265* address. If a literal IP address is supplied, only the1266* validity of the address format is checked.1267*1268* <p> For {@code host} specified in <i>literal IPv6 address</i>,1269* either the form defined in RFC 2732 or the literal IPv6 address1270* format defined in RFC 2373 is accepted. A literal IPv6 address may1271* also be qualified by appending a scoped zone identifier or scope_id.1272* The syntax and usage of scope_ids is described1273* <a href="Inet6Address.html#scoped">here</a>.1274*1275* <p> If the host is {@code null} or {@code host.length()} is equal1276* to zero, then an {@code InetAddress} representing an address of the1277* loopback interface is returned.1278* See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>1279* section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>1280* section 2.5.3. </p>1281*1282* <p> If there is a security manager, and {@code host} is not {@code null}1283* or {@code host.length() } is not equal to zero, the security manager's1284* {@code checkConnect} method is called with the hostname and {@code -1}1285* as its arguments to determine if the operation is allowed.1286*1287* @param host the name of the host, or {@code null}.1288* @return an array of all the IP addresses for a given host name.1289*1290* @throws UnknownHostException if no IP address for the1291* {@code host} could be found, or if a scope_id was specified1292* for a global IPv6 address.1293* @throws SecurityException if a security manager exists and its1294* {@code checkConnect} method doesn't allow the operation.1295*1296* @see SecurityManager#checkConnect1297*/1298public static InetAddress[] getAllByName(String host)1299throws UnknownHostException {1300return getAllByName(host, null);1301}13021303private static InetAddress[] getAllByName(String host, InetAddress reqAddr)1304throws UnknownHostException {13051306if (host == null || host.isEmpty()) {1307InetAddress[] ret = new InetAddress[1];1308ret[0] = impl.loopbackAddress();1309return ret;1310}13111312boolean ipv6Expected = false;1313if (host.charAt(0) == '[') {1314// This is supposed to be an IPv6 literal1315if (host.length() > 2 && host.charAt(host.length()-1) == ']') {1316host = host.substring(1, host.length() -1);1317ipv6Expected = true;1318} else {1319// This was supposed to be a IPv6 address, but it's not!1320throw new UnknownHostException(host + ": invalid IPv6 address");1321}1322}13231324// if host is an IP address, we won't do further lookup1325if (Character.digit(host.charAt(0), 16) != -11326|| (host.charAt(0) == ':')) {1327byte[] addr = null;1328int numericZone = -1;1329String ifname = null;1330// see if it is IPv4 address1331addr = IPAddressUtil.textToNumericFormatV4(host);1332if (addr == null) {1333// This is supposed to be an IPv6 literal1334// Check if a numeric or string zone id is present1335int pos;1336if ((pos=host.indexOf ('%')) != -1) {1337numericZone = checkNumericZone (host);1338if (numericZone == -1) { /* remainder of string must be an ifname */1339ifname = host.substring (pos+1);1340}1341}1342if ((addr = IPAddressUtil.textToNumericFormatV6(host)) == null && host.contains(":")) {1343throw new UnknownHostException(host + ": invalid IPv6 address");1344}1345} else if (ipv6Expected) {1346// Means an IPv4 literal between brackets!1347throw new UnknownHostException("["+host+"]");1348}1349InetAddress[] ret = new InetAddress[1];1350if(addr != null) {1351if (addr.length == Inet4Address.INADDRSZ) {1352ret[0] = new Inet4Address(null, addr);1353} else {1354if (ifname != null) {1355ret[0] = new Inet6Address(null, addr, ifname);1356} else {1357ret[0] = new Inet6Address(null, addr, numericZone);1358}1359}1360return ret;1361}1362} else if (ipv6Expected) {1363// We were expecting an IPv6 Literal, but got something else1364throw new UnknownHostException("["+host+"]");1365}1366return getAllByName0(host, reqAddr, true, true);1367}13681369/**1370* Returns the loopback address.1371* <p>1372* The InetAddress returned will represent the IPv41373* loopback address, 127.0.0.1, or the IPv6 loopback1374* address, ::1. The IPv4 loopback address returned1375* is only one of many in the form 127.*.*.*1376*1377* @return the InetAddress loopback instance.1378* @since 1.71379*/1380public static InetAddress getLoopbackAddress() {1381return impl.loopbackAddress();1382}138313841385/**1386* check if the literal address string has %nn appended1387* returns -1 if not, or the numeric value otherwise.1388*1389* %nn may also be a string that represents the displayName of1390* a currently available NetworkInterface.1391*/1392private static int checkNumericZone (String s) throws UnknownHostException {1393int percent = s.indexOf ('%');1394int slen = s.length();1395int digit, zone=0;1396if (percent == -1) {1397return -1;1398}1399for (int i=percent+1; i<slen; i++) {1400char c = s.charAt(i);1401if (c == ']') {1402if (i == percent+1) {1403/* empty per-cent field */1404return -1;1405}1406break;1407}1408if ((digit = Character.digit (c, 10)) < 0) {1409return -1;1410}1411zone = (zone * 10) + digit;1412}1413return zone;1414}14151416private static InetAddress[] getAllByName0 (String host)1417throws UnknownHostException1418{1419return getAllByName0(host, true);1420}14211422/**1423* package private so SocketPermission can call it1424*/1425static InetAddress[] getAllByName0 (String host, boolean check)1426throws UnknownHostException {1427return getAllByName0 (host, null, check, true);1428}14291430/**1431* Designated lookup method.1432*1433* @param host host name to look up1434* @param reqAddr requested address to be the 1st in returned array1435* @param check perform security check1436* @param useCache use cached value if not expired else always1437* perform name service lookup (and cache the result)1438* @return array of InetAddress(es)1439* @throws UnknownHostException if host name is not found1440*/1441private static InetAddress[] getAllByName0(String host,1442InetAddress reqAddr,1443boolean check,1444boolean useCache)1445throws UnknownHostException {14461447/* If it gets here it is presumed to be a hostname */14481449/* make sure the connection to the host is allowed, before we1450* give out a hostname1451*/1452if (check) {1453@SuppressWarnings("removal")1454SecurityManager security = System.getSecurityManager();1455if (security != null) {1456security.checkConnect(host, -1);1457}1458}14591460// remove expired addresses from cache - expirySet keeps them ordered1461// by expiry time so we only need to iterate the prefix of the NavigableSet...1462long now = System.nanoTime();1463for (CachedAddresses caddrs : expirySet) {1464// compare difference of time instants rather than1465// time instants directly, to avoid possible overflow.1466// (see System.nanoTime() recommendations...)1467if ((caddrs.expiryTime - now) < 0L) {1468// ConcurrentSkipListSet uses weakly consistent iterator,1469// so removing while iterating is OK...1470if (expirySet.remove(caddrs)) {1471// ... remove from cache1472cache.remove(caddrs.host, caddrs);1473}1474} else {1475// we encountered 1st element that expires in future1476break;1477}1478}14791480// look-up or remove from cache1481Addresses addrs;1482if (useCache) {1483addrs = cache.get(host);1484} else {1485addrs = cache.remove(host);1486if (addrs != null) {1487if (addrs instanceof CachedAddresses) {1488// try removing from expirySet too if CachedAddresses1489expirySet.remove(addrs);1490}1491addrs = null;1492}1493}14941495if (addrs == null) {1496// create a NameServiceAddresses instance which will look up1497// the name service and install it within cache...1498Addresses oldAddrs = cache.putIfAbsent(1499host,1500addrs = new NameServiceAddresses(host, reqAddr)1501);1502if (oldAddrs != null) { // lost putIfAbsent race1503addrs = oldAddrs;1504}1505}15061507// ask Addresses to get an array of InetAddress(es) and clone it1508return addrs.get().clone();1509}15101511static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)1512throws UnknownHostException1513{1514InetAddress[] addresses = null;1515UnknownHostException ex = null;15161517try {1518addresses = nameService.lookupAllHostAddr(host);1519} catch (UnknownHostException uhe) {1520if (host.equalsIgnoreCase("localhost")) {1521addresses = new InetAddress[] { impl.loopbackAddress() };1522}1523else {1524ex = uhe;1525}1526}15271528if (addresses == null) {1529throw ex == null ? new UnknownHostException(host) : ex;1530}15311532// More to do?1533if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {1534// Find it?1535int i = 1;1536for (; i < addresses.length; i++) {1537if (addresses[i].equals(reqAddr)) {1538break;1539}1540}1541// Rotate1542if (i < addresses.length) {1543InetAddress tmp, tmp2 = reqAddr;1544for (int j = 0; j < i; j++) {1545tmp = addresses[j];1546addresses[j] = tmp2;1547tmp2 = tmp;1548}1549addresses[i] = tmp2;1550}1551}15521553return addresses;1554}15551556/**1557* Returns an {@code InetAddress} object given the raw IP address .1558* The argument is in network byte order: the highest order1559* byte of the address is in {@code getAddress()[0]}.1560*1561* <p> This method doesn't block, i.e. no reverse name service lookup1562* is performed.1563*1564* <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array1565* must be 16 bytes long1566*1567* @param addr the raw IP address in network byte order1568* @return an InetAddress object created from the raw IP address.1569* @throws UnknownHostException if IP address is of illegal length1570* @since 1.41571*/1572public static InetAddress getByAddress(byte[] addr)1573throws UnknownHostException {1574return getByAddress(null, addr);1575}15761577private static final class CachedLocalHost {1578final String host;1579final InetAddress addr;1580final long expiryTime = System.nanoTime() + 5000_000_000L; // now + 5s;15811582CachedLocalHost(String host, InetAddress addr) {1583this.host = host;1584this.addr = addr;1585}1586}15871588private static volatile CachedLocalHost cachedLocalHost;15891590/**1591* Returns the address of the local host. This is achieved by retrieving1592* the name of the host from the system, then resolving that name into1593* an {@code InetAddress}.1594*1595* <P>Note: The resolved address may be cached for a short period of time.1596* </P>1597*1598* <p>If there is a security manager, its1599* {@code checkConnect} method is called1600* with the local host name and {@code -1}1601* as its arguments to see if the operation is allowed.1602* If the operation is not allowed, an InetAddress representing1603* the loopback address is returned.1604*1605* @return the address of the local host.1606*1607* @throws UnknownHostException if the local host name could not1608* be resolved into an address.1609*1610* @see SecurityManager#checkConnect1611* @see java.net.InetAddress#getByName(java.lang.String)1612*/1613public static InetAddress getLocalHost() throws UnknownHostException {16141615@SuppressWarnings("removal")1616SecurityManager security = System.getSecurityManager();1617try {1618// is cached data still valid?1619CachedLocalHost clh = cachedLocalHost;1620if (clh != null && (clh.expiryTime - System.nanoTime()) >= 0L) {1621if (security != null) {1622security.checkConnect(clh.host, -1);1623}1624return clh.addr;1625}16261627String local = impl.getLocalHostName();16281629if (security != null) {1630security.checkConnect(local, -1);1631}16321633InetAddress localAddr;1634if (local.equals("localhost")) {1635// shortcut for "localhost" host name1636localAddr = impl.loopbackAddress();1637} else {1638// call getAllByName0 without security checks and1639// without using cached data1640try {1641localAddr = getAllByName0(local, null, false, false)[0];1642} catch (UnknownHostException uhe) {1643// Rethrow with a more informative error message.1644UnknownHostException uhe2 =1645new UnknownHostException(local + ": " +1646uhe.getMessage());1647uhe2.initCause(uhe);1648throw uhe2;1649}1650}1651cachedLocalHost = new CachedLocalHost(local, localAddr);1652return localAddr;1653} catch (java.lang.SecurityException e) {1654return impl.loopbackAddress();1655}1656}16571658/**1659* Perform class load-time initializations.1660*/1661private static native void init();166216631664/*1665* Returns the InetAddress representing anyLocalAddress1666* (typically 0.0.0.0 or ::0)1667*/1668static InetAddress anyLocalAddress() {1669return impl.anyLocalAddress();1670}16711672/*1673* Load and instantiate an underlying impl class1674*/1675static InetAddressImpl loadImpl(String implName) {1676Object impl = null;16771678/*1679* Property "impl.prefix" will be prepended to the classname1680* of the implementation object we instantiate, to which we1681* delegate the real work (like native methods). This1682* property can vary across implementations of the java.1683* classes. The default is an empty String "".1684*/1685String prefix = GetPropertyAction.privilegedGetProperty("impl.prefix", "");1686try {1687@SuppressWarnings("deprecation")1688Object tmp = Class.forName("java.net." + prefix + implName).newInstance();1689impl = tmp;1690} catch (ClassNotFoundException e) {1691System.err.println("Class not found: java.net." + prefix +1692implName + ":\ncheck impl.prefix property " +1693"in your properties file.");1694} catch (InstantiationException e) {1695System.err.println("Could not instantiate: java.net." + prefix +1696implName + ":\ncheck impl.prefix property " +1697"in your properties file.");1698} catch (IllegalAccessException e) {1699System.err.println("Cannot access class: java.net." + prefix +1700implName + ":\ncheck impl.prefix property " +1701"in your properties file.");1702}17031704if (impl == null) {1705try {1706@SuppressWarnings("deprecation")1707Object tmp = Class.forName(implName).newInstance();1708impl = tmp;1709} catch (Exception e) {1710throw new Error("System property impl.prefix incorrect");1711}1712}17131714return (InetAddressImpl) impl;1715}17161717/**1718* Initializes an empty InetAddress.1719*/1720@java.io.Serial1721private void readObjectNoData () {1722if (getClass().getClassLoader() != null) {1723throw new SecurityException ("invalid address type");1724}1725}17261727private static final jdk.internal.misc.Unsafe UNSAFE1728= jdk.internal.misc.Unsafe.getUnsafe();1729private static final long FIELDS_OFFSET1730= UNSAFE.objectFieldOffset(InetAddress.class, "holder");17311732/**1733* Restores the state of this object from the stream.1734*1735* @param s the {@code ObjectInputStream} from which data is read1736* @throws IOException if an I/O error occurs1737* @throws ClassNotFoundException if a serialized class cannot be loaded1738*/1739@java.io.Serial1740private void readObject (ObjectInputStream s) throws1741IOException, ClassNotFoundException {1742if (getClass().getClassLoader() != null) {1743throw new SecurityException ("invalid address type");1744}1745GetField gf = s.readFields();1746String host = (String)gf.get("hostName", null);1747int address = gf.get("address", 0);1748int family = gf.get("family", 0);1749if (family != IPv4 && family != IPv6) {1750throw new InvalidObjectException("invalid address family type: " + family);1751}1752InetAddressHolder h = new InetAddressHolder(host, address, family);1753UNSAFE.putReference(this, FIELDS_OFFSET, h);1754}17551756/* needed because the serializable fields no longer exist */17571758/**1759* @serialField hostName String the hostname for this address1760* @serialField address int holds a 32-bit IPv4 address.1761* @serialField family int specifies the address family type, for instance,1762* {@code '1'} for IPv4 addresses, and {@code '2'} for IPv6 addresses.1763*/1764@java.io.Serial1765private static final ObjectStreamField[] serialPersistentFields = {1766new ObjectStreamField("hostName", String.class),1767new ObjectStreamField("address", int.class),1768new ObjectStreamField("family", int.class),1769};17701771/**1772* Writes the state of this object to the stream.1773*1774* @param s the {@code ObjectOutputStream} to which data is written1775* @throws IOException if an I/O error occurs1776*/1777@java.io.Serial1778private void writeObject (ObjectOutputStream s) throws1779IOException {1780if (getClass().getClassLoader() != null) {1781throw new SecurityException ("invalid address type");1782}1783PutField pf = s.putFields();1784pf.put("hostName", holder().getHostName());1785pf.put("address", holder().getAddress());1786pf.put("family", holder().getFamily());1787s.writeFields();1788}1789}17901791/*1792* Simple factory to create the impl1793*/1794class InetAddressImplFactory {17951796static InetAddressImpl create() {1797return InetAddress.loadImpl(isIPv6Supported() ?1798"Inet6AddressImpl" : "Inet4AddressImpl");1799}18001801static native boolean isIPv6Supported();1802}180318041805