Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/net/InetAddress.java
38829 views
/*1* Copyright (c) 1995, 2018, 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.HashMap;28import java.util.LinkedHashMap;29import java.util.Random;30import java.util.Iterator;31import java.util.LinkedList;32import java.util.List;33import java.util.ArrayList;34import java.util.ServiceLoader;35import java.security.AccessController;36import java.io.ObjectStreamException;37import java.io.ObjectStreamField;38import java.io.IOException;39import java.io.InvalidObjectException;40import java.io.ObjectInputStream;41import java.io.ObjectInputStream.GetField;42import java.io.ObjectOutputStream;43import java.io.ObjectOutputStream.PutField;44import sun.security.action.*;45import sun.net.InetAddressCachePolicy;46import sun.net.util.IPAddressUtil;47import sun.net.spi.nameservice.*;4849/**50* This class represents an Internet Protocol (IP) address.51*52* <p> An IP address is either a 32-bit or 128-bit unsigned number53* used by IP, a lower-level protocol on which protocols like UDP and54* TCP are built. The IP address architecture is defined by <a55* href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC 790:56* Assigned Numbers</i></a>, <a57* href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC 1918:58* Address Allocation for Private Internets</i></a>, <a59* href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:60* Administratively Scoped IP Multicast</i></a>, and <a61* href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP62* Version 6 Addressing Architecture</i></a>. An instance of an63* InetAddress consists of an IP address and possibly its64* corresponding host name (depending on whether it is constructed65* with a host name or whether it has already done reverse host name66* resolution).67*68* <h3> Address types </h3>69*70* <blockquote><table cellspacing=2 summary="Description of unicast and multicast address types">71* <tr><th valign=top><i>unicast</i></th>72* <td>An identifier for a single interface. A packet sent to73* a unicast address is delivered to the interface identified by74* that address.75*76* <p> The Unspecified Address -- Also called anylocal or wildcard77* address. It must never be assigned to any node. It indicates the78* absence of an address. One example of its use is as the target of79* bind, which allows a server to accept a client connection on any80* interface, in case the server host has multiple interfaces.81*82* <p> The <i>unspecified</i> address must not be used as83* the destination address of an IP packet.84*85* <p> The <i>Loopback</i> Addresses -- This is the address86* assigned to the loopback interface. Anything sent to this87* IP address loops around and becomes IP input on the local88* host. This address is often used when testing a89* client.</td></tr>90* <tr><th valign=top><i>multicast</i></th>91* <td>An identifier for a set of interfaces (typically belonging92* to different nodes). A packet sent to a multicast address is93* delivered to all interfaces identified by that address.</td></tr>94* </table></blockquote>95*96* <h4> IP address scope </h4>97*98* <p> <i>Link-local</i> addresses are designed to be used for addressing99* on a single link for purposes such as auto-address configuration,100* neighbor discovery, or when no routers are present.101*102* <p> <i>Site-local</i> addresses are designed to be used for addressing103* inside of a site without the need for a global prefix.104*105* <p> <i>Global</i> addresses are unique across the internet.106*107* <h4> Textual representation of IP addresses </h4>108*109* The textual representation of an IP address is address family specific.110*111* <p>112*113* For IPv4 address format, please refer to <A114* HREF="Inet4Address.html#format">Inet4Address#format</A>; For IPv6115* address format, please refer to <A116* HREF="Inet6Address.html#format">Inet6Address#format</A>.117*118* <P>There is a <a href="doc-files/net-properties.html#Ipv4IPv6">couple of119* System Properties</a> affecting how IPv4 and IPv6 addresses are used.</P>120*121* <h4> Host Name Resolution </h4>122*123* Host name-to-IP address <i>resolution</i> is accomplished through124* the use of a combination of local machine configuration information125* and network naming services such as the Domain Name System (DNS)126* and Network Information Service(NIS). The particular naming127* services(s) being used is by default the local machine configured128* one. For any host name, its corresponding IP address is returned.129*130* <p> <i>Reverse name resolution</i> means that for any IP address,131* the host associated with the IP address is returned.132*133* <p> The InetAddress class provides methods to resolve host names to134* their IP addresses and vice versa.135*136* <h4> InetAddress Caching </h4>137*138* The InetAddress class has a cache to store successful as well as139* unsuccessful host name resolutions.140*141* <p> By default, when a security manager is installed, in order to142* protect against DNS spoofing attacks,143* the result of positive host name resolutions are144* cached forever. When a security manager is not installed, the default145* behavior is to cache entries for a finite (implementation dependent)146* period of time. The result of unsuccessful host147* name resolution is cached for a very short period of time (10148* seconds) to improve performance.149*150* <p> If the default behavior is not desired, then a Java security property151* can be set to a different Time-to-live (TTL) value for positive152* caching. Likewise, a system admin can configure a different153* negative caching TTL value when needed.154*155* <p> Two Java security properties control the TTL values used for156* positive and negative host name resolution caching:157*158* <blockquote>159* <dl>160* <dt><b>networkaddress.cache.ttl</b></dt>161* <dd>Indicates the caching policy for successful name lookups from162* the name service. The value is specified as as integer to indicate163* the number of seconds to cache the successful lookup. The default164* setting is to cache for an implementation specific period of time.165* <p>166* A value of -1 indicates "cache forever".167* </dd>168* <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>169* <dd>Indicates the caching policy for un-successful name lookups170* from the name service. The value is specified as as integer to171* indicate the number of seconds to cache the failure for172* un-successful lookups.173* <p>174* A value of 0 indicates "never cache".175* A value of -1 indicates "cache forever".176* </dd>177* </dl>178* </blockquote>179*180* @author Chris Warth181* @see java.net.InetAddress#getByAddress(byte[])182* @see java.net.InetAddress#getByAddress(java.lang.String, byte[])183* @see java.net.InetAddress#getAllByName(java.lang.String)184* @see java.net.InetAddress#getByName(java.lang.String)185* @see java.net.InetAddress#getLocalHost()186* @since JDK1.0187*/188public189class InetAddress implements java.io.Serializable {190/**191* Specify the address family: Internet Protocol, Version 4192* @since 1.4193*/194static final int IPv4 = 1;195196/**197* Specify the address family: Internet Protocol, Version 6198* @since 1.4199*/200static final int IPv6 = 2;201202/* Specify address family preference */203static transient boolean preferIPv6Address = false;204205static class InetAddressHolder {206/**207* Reserve the original application specified hostname.208*209* The original hostname is useful for domain-based endpoint210* identification (see RFC 2818 and RFC 6125). If an address211* was created with a raw IP address, a reverse name lookup212* may introduce endpoint identification security issue via213* DNS forging.214*215* Oracle JSSE provider is using this original hostname, via216* sun.misc.JavaNetAccess, for SSL/TLS endpoint identification.217*218* Note: May define a new public method in the future if necessary.219*/220String originalHostName;221222InetAddressHolder() {}223224InetAddressHolder(String hostName, int address, int family) {225this.originalHostName = hostName;226this.hostName = hostName;227this.address = address;228this.family = family;229}230231void init(String hostName, int family) {232this.originalHostName = hostName;233this.hostName = hostName;234if (family != -1) {235this.family = family;236}237}238239String hostName;240241String getHostName() {242return hostName;243}244245String getOriginalHostName() {246return originalHostName;247}248249/**250* Holds a 32-bit IPv4 address.251*/252int address;253254int getAddress() {255return address;256}257258/**259* Specifies the address family type, for instance, '1' for IPv4260* addresses, and '2' for IPv6 addresses.261*/262int family;263264int getFamily() {265return family;266}267}268269/* Used to store the serializable fields of InetAddress */270final transient InetAddressHolder holder;271272InetAddressHolder holder() {273return holder;274}275276/* Used to store the name service provider */277private static List<NameService> nameServices = null;278279/* Used to store the best available hostname */280private transient String canonicalHostName = null;281282/** use serialVersionUID from JDK 1.0.2 for interoperability */283private static final long serialVersionUID = 3286316764910316507L;284285/*286* Load net library into runtime, and perform initializations.287*/288static {289preferIPv6Address = java.security.AccessController.doPrivileged(290new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue();291AccessController.doPrivileged(292new java.security.PrivilegedAction<Void>() {293public Void run() {294System.loadLibrary("net");295return null;296}297});298init();299}300301/**302* Constructor for the Socket.accept() method.303* This creates an empty InetAddress, which is filled in by304* the accept() method. This InetAddress, however, is not305* put in the address cache, since it is not created by name.306*/307InetAddress() {308holder = new InetAddressHolder();309}310311/**312* Replaces the de-serialized object with an Inet4Address object.313*314* @return the alternate object to the de-serialized object.315*316* @throws ObjectStreamException if a new object replacing this317* object could not be created318*/319private Object readResolve() throws ObjectStreamException {320// will replace the deserialized 'this' object321return new Inet4Address(holder().getHostName(), holder().getAddress());322}323324/**325* Utility routine to check if the InetAddress is an326* IP multicast address.327* @return a {@code boolean} indicating if the InetAddress is328* an IP multicast address329* @since JDK1.1330*/331public boolean isMulticastAddress() {332return false;333}334335/**336* Utility routine to check if the InetAddress in a wildcard address.337* @return a {@code boolean} indicating if the Inetaddress is338* a wildcard address.339* @since 1.4340*/341public boolean isAnyLocalAddress() {342return false;343}344345/**346* Utility routine to check if the InetAddress is a loopback address.347*348* @return a {@code boolean} indicating if the InetAddress is349* a loopback address; or false otherwise.350* @since 1.4351*/352public boolean isLoopbackAddress() {353return false;354}355356/**357* Utility routine to check if the InetAddress is an link local address.358*359* @return a {@code boolean} indicating if the InetAddress is360* a link local address; or false if address is not a link local unicast address.361* @since 1.4362*/363public boolean isLinkLocalAddress() {364return false;365}366367/**368* Utility routine to check if the InetAddress is a site local address.369*370* @return a {@code boolean} indicating if the InetAddress is371* a site local address; or false if address is not a site local unicast address.372* @since 1.4373*/374public boolean isSiteLocalAddress() {375return false;376}377378/**379* Utility routine to check if the multicast address has global scope.380*381* @return a {@code boolean} indicating if the address has382* is a multicast address of global scope, false if it is not383* of global scope or it is not a multicast address384* @since 1.4385*/386public boolean isMCGlobal() {387return false;388}389390/**391* Utility routine to check if the multicast address has node scope.392*393* @return a {@code boolean} indicating if the address has394* is a multicast address of node-local scope, false if it is not395* of node-local scope or it is not a multicast address396* @since 1.4397*/398public boolean isMCNodeLocal() {399return false;400}401402/**403* Utility routine to check if the multicast address has link scope.404*405* @return a {@code boolean} indicating if the address has406* is a multicast address of link-local scope, false if it is not407* of link-local scope or it is not a multicast address408* @since 1.4409*/410public boolean isMCLinkLocal() {411return false;412}413414/**415* Utility routine to check if the multicast address has site scope.416*417* @return a {@code boolean} indicating if the address has418* is a multicast address of site-local scope, false if it is not419* of site-local scope or it is not a multicast address420* @since 1.4421*/422public boolean isMCSiteLocal() {423return false;424}425426/**427* Utility routine to check if the multicast address has organization scope.428*429* @return a {@code boolean} indicating if the address has430* is a multicast address of organization-local scope,431* false if it is not of organization-local scope432* or it is not a multicast address433* @since 1.4434*/435public boolean isMCOrgLocal() {436return false;437}438439440/**441* Test whether that address is reachable. Best effort is made by the442* implementation to try to reach the host, but firewalls and server443* configuration may block requests resulting in a unreachable status444* while some specific ports may be accessible.445* A typical implementation will use ICMP ECHO REQUESTs if the446* privilege can be obtained, otherwise it will try to establish447* a TCP connection on port 7 (Echo) of the destination host.448* <p>449* The timeout value, in milliseconds, indicates the maximum amount of time450* the try should take. If the operation times out before getting an451* answer, the host is deemed unreachable. A negative value will result452* in an IllegalArgumentException being thrown.453*454* @param timeout the time, in milliseconds, before the call aborts455* @return a {@code boolean} indicating if the address is reachable.456* @throws IOException if a network error occurs457* @throws IllegalArgumentException if {@code timeout} is negative.458* @since 1.5459*/460public boolean isReachable(int timeout) throws IOException {461return isReachable(null, 0 , timeout);462}463464/**465* Test whether that address is reachable. Best effort is made by the466* implementation to try to reach the host, but firewalls and server467* configuration may block requests resulting in a unreachable status468* while some specific ports may be accessible.469* A typical implementation will use ICMP ECHO REQUESTs if the470* privilege can be obtained, otherwise it will try to establish471* a TCP connection on port 7 (Echo) of the destination host.472* <p>473* The {@code network interface} and {@code ttl} parameters474* let the caller specify which network interface the test will go through475* and the maximum number of hops the packets should go through.476* A negative value for the {@code ttl} will result in an477* IllegalArgumentException being thrown.478* <p>479* The timeout value, in milliseconds, indicates the maximum amount of time480* the try should take. If the operation times out before getting an481* answer, the host is deemed unreachable. A negative value will result482* in an IllegalArgumentException being thrown.483*484* @param netif the NetworkInterface through which the485* test will be done, or null for any interface486* @param ttl the maximum numbers of hops to try or 0 for the487* default488* @param timeout the time, in milliseconds, before the call aborts489* @throws IllegalArgumentException if either {@code timeout}490* or {@code ttl} are negative.491* @return a {@code boolean}indicating if the address is reachable.492* @throws IOException if a network error occurs493* @since 1.5494*/495public boolean isReachable(NetworkInterface netif, int ttl,496int timeout) throws IOException {497if (ttl < 0)498throw new IllegalArgumentException("ttl can't be negative");499if (timeout < 0)500throw new IllegalArgumentException("timeout can't be negative");501502return impl.isReachable(this, timeout, netif, ttl);503}504505/**506* Gets the host name for this IP address.507*508* <p>If this InetAddress was created with a host name,509* this host name will be remembered and returned;510* otherwise, a reverse name lookup will be performed511* and the result will be returned based on the system512* configured name lookup service. If a lookup of the name service513* is required, call514* {@link #getCanonicalHostName() getCanonicalHostName}.515*516* <p>If there is a security manager, its517* {@code checkConnect} method is first called518* with the hostname and {@code -1}519* as its arguments to see if the operation is allowed.520* If the operation is not allowed, it will return521* the textual representation of the IP address.522*523* @return the host name for this IP address, or if the operation524* is not allowed by the security check, the textual525* representation of the IP address.526*527* @see InetAddress#getCanonicalHostName528* @see SecurityManager#checkConnect529*/530public String getHostName() {531return getHostName(true);532}533534/**535* Returns the hostname for this address.536* If the host is equal to null, then this address refers to any537* of the local machine's available network addresses.538* this is package private so SocketPermission can make calls into539* here without a security check.540*541* <p>If there is a security manager, this method first542* calls its {@code checkConnect} method543* with the hostname and {@code -1}544* as its arguments to see if the calling code is allowed to know545* the hostname for this IP address, i.e., to connect to the host.546* If the operation is not allowed, it will return547* the textual representation of the IP address.548*549* @return the host name for this IP address, or if the operation550* is not allowed by the security check, the textual551* representation of the IP address.552*553* @param check make security check if true554*555* @see SecurityManager#checkConnect556*/557String getHostName(boolean check) {558if (holder().getHostName() == null) {559holder().hostName = InetAddress.getHostFromNameService(this, check);560}561return holder().getHostName();562}563564/**565* Gets the fully qualified domain name for this IP address.566* Best effort method, meaning we may not be able to return567* the FQDN depending on the underlying system configuration.568*569* <p>If there is a security manager, this method first570* calls its {@code checkConnect} method571* with the hostname and {@code -1}572* as its arguments to see if the calling code is allowed to know573* the hostname for this IP address, i.e., to connect to the host.574* If the operation is not allowed, it will return575* the textual representation of the IP address.576*577* @return the fully qualified domain name for this IP address,578* or if the operation is not allowed by the security check,579* the textual representation of the IP address.580*581* @see SecurityManager#checkConnect582*583* @since 1.4584*/585public String getCanonicalHostName() {586if (canonicalHostName == null) {587canonicalHostName =588InetAddress.getHostFromNameService(this, true);589}590return canonicalHostName;591}592593/**594* Returns the hostname for this address.595*596* <p>If there is a security manager, this method first597* calls its {@code checkConnect} method598* with the hostname and {@code -1}599* as its arguments to see if the calling code is allowed to know600* the hostname for this IP address, i.e., to connect to the host.601* If the operation is not allowed, it will return602* the textual representation of the IP address.603*604* @return the host name for this IP address, or if the operation605* is not allowed by the security check, the textual606* representation of the IP address.607*608* @param check make security check if true609*610* @see SecurityManager#checkConnect611*/612private static String getHostFromNameService(InetAddress addr, boolean check) {613String host = null;614for (NameService nameService : nameServices) {615try {616// first lookup the hostname617host = nameService.getHostByAddr(addr.getAddress());618619/* check to see if calling code is allowed to know620* the hostname for this IP address, ie, connect to the host621*/622if (check) {623SecurityManager sec = System.getSecurityManager();624if (sec != null) {625sec.checkConnect(host, -1);626}627}628629/* now get all the IP addresses for this hostname,630* and make sure one of them matches the original IP631* address. We do this to try and prevent spoofing.632*/633634InetAddress[] arr = InetAddress.getAllByName0(host, check);635boolean ok = false;636637if(arr != null) {638for(int i = 0; !ok && i < arr.length; i++) {639ok = addr.equals(arr[i]);640}641}642643//XXX: if it looks a spoof just return the address?644if (!ok) {645host = addr.getHostAddress();646return host;647}648649break;650651} catch (SecurityException e) {652host = addr.getHostAddress();653break;654} catch (UnknownHostException e) {655host = addr.getHostAddress();656// let next provider resolve the hostname657}658}659660return host;661}662663/**664* Returns the raw IP address of this {@code InetAddress}665* object. The result is in network byte order: the highest order666* byte of the address is in {@code getAddress()[0]}.667*668* @return the raw IP address of this object.669*/670public byte[] getAddress() {671return null;672}673674/**675* Returns the IP address string in textual presentation.676*677* @return the raw IP address in a string format.678* @since JDK1.0.2679*/680public String getHostAddress() {681return null;682}683684/**685* Returns a hashcode for this IP address.686*687* @return a hash code value for this IP address.688*/689public int hashCode() {690return -1;691}692693/**694* Compares this object against the specified object.695* The result is {@code true} if and only if the argument is696* not {@code null} and it represents the same IP address as697* this object.698* <p>699* Two instances of {@code InetAddress} represent the same IP700* address if the length of the byte arrays returned by701* {@code getAddress} is the same for both, and each of the702* array components is the same for the byte arrays.703*704* @param obj the object to compare against.705* @return {@code true} if the objects are the same;706* {@code false} otherwise.707* @see java.net.InetAddress#getAddress()708*/709public boolean equals(Object obj) {710return false;711}712713/**714* Converts this IP address to a {@code String}. The715* string returned is of the form: hostname / literal IP716* address.717*718* If the host name is unresolved, no reverse name service lookup719* is performed. The hostname part will be represented by an empty string.720*721* @return a string representation of this IP address.722*/723public String toString() {724String hostName = holder().getHostName();725return ((hostName != null) ? hostName : "")726+ "/" + getHostAddress();727}728729/*730* Cached addresses - our own litle nis, not!731*/732private static Cache addressCache = new Cache(Cache.Type.Positive);733734private static Cache negativeCache = new Cache(Cache.Type.Negative);735736private static boolean addressCacheInit = false;737738static InetAddress[] unknown_array; // put THIS in cache739740static InetAddressImpl impl;741742private static final HashMap<String, Void> lookupTable = new HashMap<>();743744/**745* Represents a cache entry746*/747static final class CacheEntry {748749CacheEntry(InetAddress[] addresses, long expiration) {750this.addresses = addresses;751this.expiration = expiration;752}753754InetAddress[] addresses;755long expiration;756}757758/**759* A cache that manages entries based on a policy specified760* at creation time.761*/762static final class Cache {763private LinkedHashMap<String, CacheEntry> cache;764private Type type;765766enum Type {Positive, Negative};767768/**769* Create cache770*/771public Cache(Type type) {772this.type = type;773cache = new LinkedHashMap<String, CacheEntry>();774}775776private int getPolicy() {777if (type == Type.Positive) {778return InetAddressCachePolicy.get();779} else {780return InetAddressCachePolicy.getNegative();781}782}783784/**785* Add an entry to the cache. If there's already an786* entry then for this host then the entry will be787* replaced.788*/789public Cache put(String host, InetAddress[] addresses) {790int policy = getPolicy();791if (policy == InetAddressCachePolicy.NEVER) {792return this;793}794795// purge any expired entries796797if (policy != InetAddressCachePolicy.FOREVER) {798799// As we iterate in insertion order we can800// terminate when a non-expired entry is found.801LinkedList<String> expired = new LinkedList<>();802long now = System.currentTimeMillis();803for (String key : cache.keySet()) {804CacheEntry entry = cache.get(key);805806if (entry.expiration >= 0 && entry.expiration < now) {807expired.add(key);808} else {809break;810}811}812813for (String key : expired) {814cache.remove(key);815}816}817818// create new entry and add it to the cache819// -- as a HashMap replaces existing entries we820// don't need to explicitly check if there is821// already an entry for this host.822long expiration;823if (policy == InetAddressCachePolicy.FOREVER) {824expiration = -1;825} else {826expiration = System.currentTimeMillis() + (policy * 1000);827}828CacheEntry entry = new CacheEntry(addresses, expiration);829cache.put(host, entry);830return this;831}832833/**834* Query the cache for the specific host. If found then835* return its CacheEntry, or null if not found.836*/837public CacheEntry get(String host) {838int policy = getPolicy();839if (policy == InetAddressCachePolicy.NEVER) {840return null;841}842CacheEntry entry = cache.get(host);843844// check if entry has expired845if (entry != null && policy != InetAddressCachePolicy.FOREVER) {846if (entry.expiration >= 0 &&847entry.expiration < System.currentTimeMillis()) {848cache.remove(host);849entry = null;850}851}852853return entry;854}855}856857/*858* Initialize cache and insert anyLocalAddress into the859* unknown array with no expiry.860*/861private static void cacheInitIfNeeded() {862assert Thread.holdsLock(addressCache);863if (addressCacheInit) {864return;865}866unknown_array = new InetAddress[1];867unknown_array[0] = impl.anyLocalAddress();868869addressCache.put(impl.anyLocalAddress().getHostName(),870unknown_array);871872addressCacheInit = true;873}874875/*876* Cache the given hostname and addresses.877*/878private static void cacheAddresses(String hostname,879InetAddress[] addresses,880boolean success) {881hostname = hostname.toLowerCase();882synchronized (addressCache) {883cacheInitIfNeeded();884if (success) {885addressCache.put(hostname, addresses);886} else {887negativeCache.put(hostname, addresses);888}889}890}891892/*893* Lookup hostname in cache (positive & negative cache). If894* found return addresses, null if not found.895*/896private static InetAddress[] getCachedAddresses(String hostname) {897hostname = hostname.toLowerCase();898899// search both positive & negative caches900901synchronized (addressCache) {902cacheInitIfNeeded();903904CacheEntry entry = addressCache.get(hostname);905if (entry == null) {906entry = negativeCache.get(hostname);907}908909if (entry != null) {910return entry.addresses;911}912}913914// not found915return null;916}917918private static NameService createNSProvider(String provider) {919if (provider == null)920return null;921922NameService nameService = null;923if (provider.equals("default")) {924// initialize the default name service925nameService = new NameService() {926public InetAddress[] lookupAllHostAddr(String host)927throws UnknownHostException {928return impl.lookupAllHostAddr(host);929}930public String getHostByAddr(byte[] addr)931throws UnknownHostException {932return impl.getHostByAddr(addr);933}934};935} else {936final String providerName = provider;937try {938nameService = java.security.AccessController.doPrivileged(939new java.security.PrivilegedExceptionAction<NameService>() {940public NameService run() {941Iterator<NameServiceDescriptor> itr =942ServiceLoader.load(NameServiceDescriptor.class)943.iterator();944while (itr.hasNext()) {945NameServiceDescriptor nsd = itr.next();946if (providerName.947equalsIgnoreCase(nsd.getType()+","948+nsd.getProviderName())) {949try {950return nsd.createNameService();951} catch (Exception e) {952e.printStackTrace();953System.err.println(954"Cannot create name service:"955+providerName+": " + e);956}957}958}959960return null;961}962}963);964} catch (java.security.PrivilegedActionException e) {965}966}967968return nameService;969}970971static {972// create the impl973impl = InetAddressImplFactory.create();974975// get name service if provided and requested976String provider = null;;977String propPrefix = "sun.net.spi.nameservice.provider.";978int n = 1;979nameServices = new ArrayList<NameService>();980provider = AccessController.doPrivileged(981new GetPropertyAction(propPrefix + n));982while (provider != null) {983NameService ns = createNSProvider(provider);984if (ns != null)985nameServices.add(ns);986987n++;988provider = AccessController.doPrivileged(989new GetPropertyAction(propPrefix + n));990}991992// if not designate any name services provider,993// create a default one994if (nameServices.size() == 0) {995NameService ns = createNSProvider("default");996nameServices.add(ns);997}998}9991000/**1001* Creates an InetAddress based on the provided host name and IP address.1002* No name service is checked for the validity of the address.1003*1004* <p> The host name can either be a machine name, such as1005* "{@code java.sun.com}", or a textual representation of its IP1006* address.1007* <p> No validity checking is done on the host name either.1008*1009* <p> If addr specifies an IPv4 address an instance of Inet4Address1010* will be returned; otherwise, an instance of Inet6Address1011* will be returned.1012*1013* <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array1014* must be 16 bytes long1015*1016* @param host the specified host1017* @param addr the raw IP address in network byte order1018* @return an InetAddress object created from the raw IP address.1019* @exception UnknownHostException if IP address is of illegal length1020* @since 1.41021*/1022public static InetAddress getByAddress(String host, byte[] addr)1023throws UnknownHostException {1024if (host != null && host.length() > 0 && host.charAt(0) == '[') {1025if (host.charAt(host.length()-1) == ']') {1026host = host.substring(1, host.length() -1);1027}1028}1029if (addr != null) {1030if (addr.length == Inet4Address.INADDRSZ) {1031return new Inet4Address(host, addr);1032} else if (addr.length == Inet6Address.INADDRSZ) {1033byte[] newAddr1034= IPAddressUtil.convertFromIPv4MappedAddress(addr);1035if (newAddr != null) {1036return new Inet4Address(host, newAddr);1037} else {1038return new Inet6Address(host, addr);1039}1040}1041}1042throw new UnknownHostException("addr is of illegal length");1043}104410451046/**1047* Determines the IP address of a host, given the host's name.1048*1049* <p> The host name can either be a machine name, such as1050* "{@code java.sun.com}", or a textual representation of its1051* IP address. If a literal IP address is supplied, only the1052* validity of the address format is checked.1053*1054* <p> For {@code host} specified in literal IPv6 address,1055* either the form defined in RFC 2732 or the literal IPv6 address1056* format defined in RFC 2373 is accepted. IPv6 scoped addresses are also1057* supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv61058* scoped addresses.1059*1060* <p> If the host is {@code null} then an {@code InetAddress}1061* representing an address of the loopback interface is returned.1062* See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>1063* section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>1064* section 2.5.3. </p>1065*1066* @param host the specified host, or {@code null}.1067* @return an IP address for the given host name.1068* @exception UnknownHostException if no IP address for the1069* {@code host} could be found, or if a scope_id was specified1070* for a global IPv6 address.1071* @exception SecurityException if a security manager exists1072* and its checkConnect method doesn't allow the operation1073*/1074public static InetAddress getByName(String host)1075throws UnknownHostException {1076return InetAddress.getAllByName(host)[0];1077}10781079// called from deployment cache manager1080private static InetAddress getByName(String host, InetAddress reqAddr)1081throws UnknownHostException {1082return InetAddress.getAllByName(host, reqAddr)[0];1083}10841085/**1086* Given the name of a host, returns an array of its IP addresses,1087* based on the configured name service on the system.1088*1089* <p> The host name can either be a machine name, such as1090* "{@code java.sun.com}", or a textual representation of its IP1091* address. If a literal IP address is supplied, only the1092* validity of the address format is checked.1093*1094* <p> For {@code host} specified in <i>literal IPv6 address</i>,1095* either the form defined in RFC 2732 or the literal IPv6 address1096* format defined in RFC 2373 is accepted. A literal IPv6 address may1097* also be qualified by appending a scoped zone identifier or scope_id.1098* The syntax and usage of scope_ids is described1099* <a href="Inet6Address.html#scoped">here</a>.1100* <p> If the host is {@code null} then an {@code InetAddress}1101* representing an address of the loopback interface is returned.1102* See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>1103* section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>1104* section 2.5.3. </p>1105*1106* <p> If there is a security manager and {@code host} is not1107* null and {@code host.length() } is not equal to zero, the1108* security manager's1109* {@code checkConnect} method is called1110* with the hostname and {@code -1}1111* as its arguments to see if the operation is allowed.1112*1113* @param host the name of the host, or {@code null}.1114* @return an array of all the IP addresses for a given host name.1115*1116* @exception UnknownHostException if no IP address for the1117* {@code host} could be found, or if a scope_id was specified1118* for a global IPv6 address.1119* @exception SecurityException if a security manager exists and its1120* {@code checkConnect} method doesn't allow the operation.1121*1122* @see SecurityManager#checkConnect1123*/1124public static InetAddress[] getAllByName(String host)1125throws UnknownHostException {1126return getAllByName(host, null);1127}11281129private static InetAddress[] getAllByName(String host, InetAddress reqAddr)1130throws UnknownHostException {11311132if (host == null || host.length() == 0) {1133InetAddress[] ret = new InetAddress[1];1134ret[0] = impl.loopbackAddress();1135return ret;1136}11371138boolean ipv6Expected = false;1139if (host.charAt(0) == '[') {1140// This is supposed to be an IPv6 literal1141if (host.length() > 2 && host.charAt(host.length()-1) == ']') {1142host = host.substring(1, host.length() -1);1143ipv6Expected = true;1144} else {1145// This was supposed to be a IPv6 address, but it's not!1146throw new UnknownHostException(host + ": invalid IPv6 address");1147}1148}11491150// if host is an IP address, we won't do further lookup1151if (Character.digit(host.charAt(0), 16) != -11152|| (host.charAt(0) == ':')) {1153byte[] addr = null;1154int numericZone = -1;1155String ifname = null;1156// see if it is IPv4 address1157addr = IPAddressUtil.textToNumericFormatV4(host);1158if (addr == null) {1159// This is supposed to be an IPv6 literal1160// Check if a numeric or string zone id is present1161int pos;1162if ((pos=host.indexOf ("%")) != -1) {1163numericZone = checkNumericZone (host);1164if (numericZone == -1) { /* remainder of string must be an ifname */1165ifname = host.substring (pos+1);1166}1167}1168if ((addr = IPAddressUtil.textToNumericFormatV6(host)) == null && host.contains(":")) {1169throw new UnknownHostException(host + ": invalid IPv6 address");1170}1171} else if (ipv6Expected) {1172// Means an IPv4 litteral between brackets!1173throw new UnknownHostException("["+host+"]");1174}1175InetAddress[] ret = new InetAddress[1];1176if(addr != null) {1177if (addr.length == Inet4Address.INADDRSZ) {1178ret[0] = new Inet4Address(null, addr);1179} else {1180if (ifname != null) {1181ret[0] = new Inet6Address(null, addr, ifname);1182} else {1183ret[0] = new Inet6Address(null, addr, numericZone);1184}1185}1186return ret;1187}1188} else if (ipv6Expected) {1189// We were expecting an IPv6 Litteral, but got something else1190throw new UnknownHostException("["+host+"]");1191}1192return getAllByName0(host, reqAddr, true);1193}11941195/**1196* Returns the loopback address.1197* <p>1198* The InetAddress returned will represent the IPv41199* loopback address, 127.0.0.1, or the IPv6 loopback1200* address, ::1. The IPv4 loopback address returned1201* is only one of many in the form 127.*.*.*1202*1203* @return the InetAddress loopback instance.1204* @since 1.71205*/1206public static InetAddress getLoopbackAddress() {1207return impl.loopbackAddress();1208}120912101211/**1212* check if the literal address string has %nn appended1213* returns -1 if not, or the numeric value otherwise.1214*1215* %nn may also be a string that represents the displayName of1216* a currently available NetworkInterface.1217*/1218private static int checkNumericZone (String s) throws UnknownHostException {1219int percent = s.indexOf ('%');1220int slen = s.length();1221int digit, zone=0;1222if (percent == -1) {1223return -1;1224}1225for (int i=percent+1; i<slen; i++) {1226char c = s.charAt(i);1227if (c == ']') {1228if (i == percent+1) {1229/* empty per-cent field */1230return -1;1231}1232break;1233}1234if ((digit = Character.digit (c, 10)) < 0) {1235return -1;1236}1237zone = (zone * 10) + digit;1238}1239return zone;1240}12411242private static InetAddress[] getAllByName0 (String host)1243throws UnknownHostException1244{1245return getAllByName0(host, true);1246}12471248/**1249* package private so SocketPermission can call it1250*/1251static InetAddress[] getAllByName0 (String host, boolean check)1252throws UnknownHostException {1253return getAllByName0 (host, null, check);1254}12551256private static InetAddress[] getAllByName0 (String host, InetAddress reqAddr, boolean check)1257throws UnknownHostException {12581259/* If it gets here it is presumed to be a hostname */1260/* Cache.get can return: null, unknownAddress, or InetAddress[] */12611262/* make sure the connection to the host is allowed, before we1263* give out a hostname1264*/1265if (check) {1266SecurityManager security = System.getSecurityManager();1267if (security != null) {1268security.checkConnect(host, -1);1269}1270}12711272InetAddress[] addresses = getCachedAddresses(host);12731274/* If no entry in cache, then do the host lookup */1275if (addresses == null) {1276addresses = getAddressesFromNameService(host, reqAddr);1277}12781279if (addresses == unknown_array)1280throw new UnknownHostException(host);12811282return addresses.clone();1283}12841285private static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)1286throws UnknownHostException1287{1288InetAddress[] addresses = null;1289boolean success = false;1290UnknownHostException ex = null;12911292// Check whether the host is in the lookupTable.1293// 1) If the host isn't in the lookupTable when1294// checkLookupTable() is called, checkLookupTable()1295// would add the host in the lookupTable and1296// return null. So we will do the lookup.1297// 2) If the host is in the lookupTable when1298// checkLookupTable() is called, the current thread1299// would be blocked until the host is removed1300// from the lookupTable. Then this thread1301// should try to look up the addressCache.1302// i) if it found the addresses in the1303// addressCache, checkLookupTable() would1304// return the addresses.1305// ii) if it didn't find the addresses in the1306// addressCache for any reason,1307// it should add the host in the1308// lookupTable and return null so the1309// following code would do a lookup itself.1310if ((addresses = checkLookupTable(host)) == null) {1311try {1312// This is the first thread which looks up the addresses1313// this host or the cache entry for this host has been1314// expired so this thread should do the lookup.1315for (NameService nameService : nameServices) {1316try {1317/*1318* Do not put the call to lookup() inside the1319* constructor. if you do you will still be1320* allocating space when the lookup fails.1321*/13221323addresses = nameService.lookupAllHostAddr(host);1324success = true;1325break;1326} catch (UnknownHostException uhe) {1327if (host.equalsIgnoreCase("localhost")) {1328InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };1329addresses = local;1330success = true;1331break;1332}1333else {1334addresses = unknown_array;1335success = false;1336ex = uhe;1337}1338}1339}13401341// More to do?1342if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {1343// Find it?1344int i = 1;1345for (; i < addresses.length; i++) {1346if (addresses[i].equals(reqAddr)) {1347break;1348}1349}1350// Rotate1351if (i < addresses.length) {1352InetAddress tmp, tmp2 = reqAddr;1353for (int j = 0; j < i; j++) {1354tmp = addresses[j];1355addresses[j] = tmp2;1356tmp2 = tmp;1357}1358addresses[i] = tmp2;1359}1360}1361// Cache the address.1362cacheAddresses(host, addresses, success);13631364if (!success && ex != null)1365throw ex;13661367} finally {1368// Delete host from the lookupTable and notify1369// all threads waiting on the lookupTable monitor.1370updateLookupTable(host);1371}1372}13731374return addresses;1375}137613771378private static InetAddress[] checkLookupTable(String host) {1379synchronized (lookupTable) {1380// If the host isn't in the lookupTable, add it in the1381// lookuptable and return null. The caller should do1382// the lookup.1383if (lookupTable.containsKey(host) == false) {1384lookupTable.put(host, null);1385return null;1386}13871388// If the host is in the lookupTable, it means that another1389// thread is trying to look up the addresses of this host.1390// This thread should wait.1391while (lookupTable.containsKey(host)) {1392try {1393lookupTable.wait();1394} catch (InterruptedException e) {1395}1396}1397}13981399// The other thread has finished looking up the addresses of1400// the host. This thread should retry to get the addresses1401// from the addressCache. If it doesn't get the addresses from1402// the cache, it will try to look up the addresses itself.1403InetAddress[] addresses = getCachedAddresses(host);1404if (addresses == null) {1405synchronized (lookupTable) {1406lookupTable.put(host, null);1407return null;1408}1409}14101411return addresses;1412}14131414private static void updateLookupTable(String host) {1415synchronized (lookupTable) {1416lookupTable.remove(host);1417lookupTable.notifyAll();1418}1419}14201421/**1422* Returns an {@code InetAddress} object given the raw IP address .1423* The argument is in network byte order: the highest order1424* byte of the address is in {@code getAddress()[0]}.1425*1426* <p> This method doesn't block, i.e. no reverse name service lookup1427* is performed.1428*1429* <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array1430* must be 16 bytes long1431*1432* @param addr the raw IP address in network byte order1433* @return an InetAddress object created from the raw IP address.1434* @exception UnknownHostException if IP address is of illegal length1435* @since 1.41436*/1437public static InetAddress getByAddress(byte[] addr)1438throws UnknownHostException {1439return getByAddress(null, addr);1440}14411442private static InetAddress cachedLocalHost = null;1443private static long cacheTime = 0;1444private static final long maxCacheTime = 5000L;1445private static final Object cacheLock = new Object();14461447/**1448* Returns the address of the local host. This is achieved by retrieving1449* the name of the host from the system, then resolving that name into1450* an {@code InetAddress}.1451*1452* <P>Note: The resolved address may be cached for a short period of time.1453* </P>1454*1455* <p>If there is a security manager, its1456* {@code checkConnect} method is called1457* with the local host name and {@code -1}1458* as its arguments to see if the operation is allowed.1459* If the operation is not allowed, an InetAddress representing1460* the loopback address is returned.1461*1462* @return the address of the local host.1463*1464* @exception UnknownHostException if the local host name could not1465* be resolved into an address.1466*1467* @see SecurityManager#checkConnect1468* @see java.net.InetAddress#getByName(java.lang.String)1469*/1470public static InetAddress getLocalHost() throws UnknownHostException {14711472SecurityManager security = System.getSecurityManager();1473try {1474String local = impl.getLocalHostName();14751476if (security != null) {1477security.checkConnect(local, -1);1478}14791480if (local.equals("localhost")) {1481return impl.loopbackAddress();1482}14831484InetAddress ret = null;1485synchronized (cacheLock) {1486long now = System.currentTimeMillis();1487if (cachedLocalHost != null) {1488if ((now - cacheTime) < maxCacheTime) // Less than 5s old?1489ret = cachedLocalHost;1490else1491cachedLocalHost = null;1492}14931494// we are calling getAddressesFromNameService directly1495// to avoid getting localHost from cache1496if (ret == null) {1497InetAddress[] localAddrs;1498try {1499localAddrs =1500InetAddress.getAddressesFromNameService(local, null);1501} catch (UnknownHostException uhe) {1502// Rethrow with a more informative error message.1503UnknownHostException uhe2 =1504new UnknownHostException(local + ": " +1505uhe.getMessage());1506uhe2.initCause(uhe);1507throw uhe2;1508}1509cachedLocalHost = localAddrs[0];1510cacheTime = now;1511ret = localAddrs[0];1512}1513}1514return ret;1515} catch (java.lang.SecurityException e) {1516return impl.loopbackAddress();1517}1518}15191520/**1521* Perform class load-time initializations.1522*/1523private static native void init();152415251526/*1527* Returns the InetAddress representing anyLocalAddress1528* (typically 0.0.0.0 or ::0)1529*/1530static InetAddress anyLocalAddress() {1531return impl.anyLocalAddress();1532}15331534/*1535* Load and instantiate an underlying impl class1536*/1537static InetAddressImpl loadImpl(String implName) {1538Object impl = null;15391540/*1541* Property "impl.prefix" will be prepended to the classname1542* of the implementation object we instantiate, to which we1543* delegate the real work (like native methods). This1544* property can vary across implementations of the java.1545* classes. The default is an empty String "".1546*/1547String prefix = AccessController.doPrivileged(1548new GetPropertyAction("impl.prefix", ""));1549try {1550impl = Class.forName("java.net." + prefix + implName).newInstance();1551} catch (ClassNotFoundException e) {1552System.err.println("Class not found: java.net." + prefix +1553implName + ":\ncheck impl.prefix property " +1554"in your properties file.");1555} catch (InstantiationException e) {1556System.err.println("Could not instantiate: java.net." + prefix +1557implName + ":\ncheck impl.prefix property " +1558"in your properties file.");1559} catch (IllegalAccessException e) {1560System.err.println("Cannot access class: java.net." + prefix +1561implName + ":\ncheck impl.prefix property " +1562"in your properties file.");1563}15641565if (impl == null) {1566try {1567impl = Class.forName(implName).newInstance();1568} catch (Exception e) {1569throw new Error("System property impl.prefix incorrect");1570}1571}15721573return (InetAddressImpl) impl;1574}15751576private void readObjectNoData (ObjectInputStream s) throws1577IOException, ClassNotFoundException {1578if (getClass().getClassLoader() != null) {1579throw new SecurityException ("invalid address type");1580}1581}15821583private static final long FIELDS_OFFSET;1584private static final sun.misc.Unsafe UNSAFE;15851586static {1587try {1588sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();1589FIELDS_OFFSET = unsafe.objectFieldOffset(1590InetAddress.class.getDeclaredField("holder")1591);1592UNSAFE = unsafe;1593} catch (ReflectiveOperationException e) {1594throw new Error(e);1595}1596}15971598private void readObject (ObjectInputStream s) throws1599IOException, ClassNotFoundException {1600if (getClass().getClassLoader() != null) {1601throw new SecurityException ("invalid address type");1602}1603GetField gf = s.readFields();1604String host = (String)gf.get("hostName", null);1605int address = gf.get("address", 0);1606int family = gf.get("family", 0);1607if (family != IPv4 && family != IPv6) {1608throw new InvalidObjectException("invalid address family type: " + family);1609}1610InetAddressHolder h = new InetAddressHolder(host, address, family);1611UNSAFE.putObject(this, FIELDS_OFFSET, h);1612}16131614/* needed because the serializable fields no longer exist */16151616/**1617* @serialField hostName String1618* @serialField address int1619* @serialField family int1620*/1621private static final ObjectStreamField[] serialPersistentFields = {1622new ObjectStreamField("hostName", String.class),1623new ObjectStreamField("address", int.class),1624new ObjectStreamField("family", int.class),1625};16261627private void writeObject (ObjectOutputStream s) throws1628IOException {1629if (getClass().getClassLoader() != null) {1630throw new SecurityException ("invalid address type");1631}1632PutField pf = s.putFields();1633pf.put("hostName", holder().getHostName());1634pf.put("address", holder().getAddress());1635pf.put("family", holder().getFamily());1636s.writeFields();1637}1638}16391640/*1641* Simple factory to create the impl1642*/1643class InetAddressImplFactory {16441645static InetAddressImpl create() {1646return InetAddress.loadImpl(isIPv6Supported() ?1647"Inet6AddressImpl" : "Inet4AddressImpl");1648}16491650static native boolean isIPv6Supported();1651}165216531654