Source Home >> Java Source 1.6.0 >> java.net.InetAddress V 0.09
  • 0001/*
  • 0002 * @(#)InetAddress.java 1.116 07/09/05
  • 0003 *
  • 0004 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  • 0005 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  • 0006 */
  • 0007
  • 0008package java.net;
  • 0009
  • 0010import java.util.HashMap;
  • 0011import java.util.LinkedHashMap;
  • 0012import java.util.Random;
  • 0013import java.util.Iterator;
  • 0014import java.util.LinkedList;
  • 0015import java.security.AccessController;
  • 0016import java.io.ObjectStreamException;
  • 0017import java.io.IOException;
  • 0018import sun.security.action.*;
  • 0019import sun.net.InetAddressCachePolicy;
  • 0020import sun.net.util.IPAddressUtil;
  • 0021import sun.misc.Service;
  • 0022import sun.net.spi.nameservice.*;
  • 0023
  • 0024/**
  • 0025 * This class represents an Internet Protocol (IP) address.
  • 0026 *
  • 0027 * <p> An IP address is either a 32-bit or 128-bit unsigned number
  • 0028 * used by IP, a lower-level protocol on which protocols like UDP and
  • 0029 * TCP are built. The IP address architecture is defined by <a
  • 0030 * href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC 790:
  • 0031 * Assigned Numbers</i></a>, <a
  • 0032 * href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC 1918:
  • 0033 * Address Allocation for Private Internets</i></a>, <a
  • 0034 * href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:
  • 0035 * Administratively Scoped IP Multicast</i></a>, and <a
  • 0036 * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP
  • 0037 * Version 6 Addressing Architecture</i></a>. An instance of an
  • 0038 * InetAddress consists of an IP address and possibly its
  • 0039 * corresponding host name (depending on whether it is constructed
  • 0040 * with a host name or whether it has already done reverse host name
  • 0041 * resolution).
  • 0042 *
  • 0043 * <h4> Address types </h4>
  • 0044 *
  • 0045 * <blockquote><table cellspacing=2 summary="Description of unicast and multicast address types">
  • 0046 * <tr><th valign=top><i>unicast</i></th>
  • 0047 * <td>An identifier for a single interface. A packet sent to
  • 0048 * a unicast address is delivered to the interface identified by
  • 0049 * that address.
  • 0050 *
  • 0051 * <p> The Unspecified Address -- Also called anylocal or wildcard
  • 0052 * address. It must never be assigned to any node. It indicates the
  • 0053 * absence of an address. One example of its use is as the target of
  • 0054 * bind, which allows a server to accept a client connection on any
  • 0055 * interface, in case the server host has multiple interfaces.
  • 0056 *
  • 0057 * <p> The <i>unspecified</i> address must not be used as
  • 0058 * the destination address of an IP packet.
  • 0059 *
  • 0060 * <p> The <i>Loopback</i> Addresses -- This is the address
  • 0061 * assigned to the loopback interface. Anything sent to this
  • 0062 * IP address loops around and becomes IP input on the local
  • 0063 * host. This address is often used when testing a
  • 0064 * client.</td></tr>
  • 0065 * <tr><th valign=top><i>multicast</i></th>
  • 0066 * <td>An identifier for a set of interfaces (typically belonging
  • 0067 * to different nodes). A packet sent to a multicast address is
  • 0068 * delivered to all interfaces identified by that address.</td></tr>
  • 0069 * </table></blockquote>
  • 0070 *
  • 0071 * <h4> IP address scope </h4>
  • 0072 *
  • 0073 * <p> <i>Link-local</i> addresses are designed to be used for addressing
  • 0074 * on a single link for purposes such as auto-address configuration,
  • 0075 * neighbor discovery, or when no routers are present.
  • 0076 *
  • 0077 * <p> <i>Site-local</i> addresses are designed to be used for addressing
  • 0078 * inside of a site without the need for a global prefix.
  • 0079 *
  • 0080 * <p> <i>Global</i> addresses are unique across the internet.
  • 0081 *
  • 0082 * <h4> Textual representation of IP addresses </h4>
  • 0083 *
  • 0084 * The textual representation of an IP address is address family specific.
  • 0085 *
  • 0086 * <p>
  • 0087 *
  • 0088 * For IPv4 address format, please refer to <A
  • 0089 * HREF="Inet4Address.html#format">Inet4Address#format</A>; For IPv6
  • 0090 * address format, please refer to <A
  • 0091 * HREF="Inet6Address.html#format">Inet6Address#format</A>.
  • 0092 *
  • 0093 * <h4> Host Name Resolution </h4>
  • 0094 *
  • 0095 * Host name-to-IP address <i>resolution</i> is accomplished through
  • 0096 * the use of a combination of local machine configuration information
  • 0097 * and network naming services such as the Domain Name System (DNS)
  • 0098 * and Network Information Service(NIS). The particular naming
  • 0099 * services(s) being used is by default the local machine configured
  • 0100 * one. For any host name, its corresponding IP address is returned.
  • 0101 *
  • 0102 * <p> <i>Reverse name resolution</i> means that for any IP address,
  • 0103 * the host associated with the IP address is returned.
  • 0104 *
  • 0105 * <p> The InetAddress class provides methods to resolve host names to
  • 0106 * their IP addresses and vice versa.
  • 0107 *
  • 0108 * <h4> InetAddress Caching </h4>
  • 0109 *
  • 0110 * The InetAddress class has a cache to store successful as well as
  • 0111 * unsuccessful host name resolutions.
  • 0112 *
  • 0113 * <p> By default, when a security manager is installed, in order to
  • 0114 * protect against DNS spoofing attacks,
  • 0115 * the result of positive host name resolutions are
  • 0116 * cached forever. When a security manager is not installed, the default
  • 0117 * behavior is to cache entries for a finite (implementation dependent)
  • 0118 * period of time. The result of unsuccessful host
  • 0119 * name resolution is cached for a very short period of time (10
  • 0120 * seconds) to improve performance.
  • 0121 *
  • 0122 * <p> If the default behavior is not desired, then a Java security property
  • 0123 * can be set to a different Time-to-live (TTL) value for positive
  • 0124 * caching. Likewise, a system admin can configure a different
  • 0125 * negative caching TTL value when needed.
  • 0126 *
  • 0127 * <p> Two Java security properties control the TTL values used for
  • 0128 * positive and negative host name resolution caching:
  • 0129 *
  • 0130 * <blockquote>
  • 0131 * <dl>
  • 0132 * <dt><b>networkaddress.cache.ttl</b></dt>
  • 0133 * <dd>Indicates the caching policy for successful name lookups from
  • 0134 * the name service. The value is specified as as integer to indicate
  • 0135 * the number of seconds to cache the successful lookup. The default
  • 0136 * setting is to cache for an implementation specific period of time.
  • 0137 * <p>
  • 0138 * A value of -1 indicates "cache forever".
  • 0139 * </dd>
  • 0140 * <p>
  • 0141 * <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>
  • 0142 * <dd>Indicates the caching policy for un-successful name lookups
  • 0143 * from the name service. The value is specified as as integer to
  • 0144 * indicate the number of seconds to cache the failure for
  • 0145 * un-successful lookups.
  • 0146 * <p>
  • 0147 * A value of 0 indicates "never cache".
  • 0148 * A value of -1 indicates "cache forever".
  • 0149 * </dd>
  • 0150 * </dl>
  • 0151 * </blockquote>
  • 0152 *
  • 0153 * @author Chris Warth
  • 0154 * @version 1.116, 09/05/07
  • 0155 * @see java.net.InetAddress#getByAddress(byte[])
  • 0156 * @see java.net.InetAddress#getByAddress(java.lang.String, byte[])
  • 0157 * @see java.net.InetAddress#getAllByName(java.lang.String)
  • 0158 * @see java.net.InetAddress#getByName(java.lang.String)
  • 0159 * @see java.net.InetAddress#getLocalHost()
  • 0160 * @since JDK1.0
  • 0161 */
  • 0162public
  • 0163class InetAddress implements java.io.Serializable {
  • 0164 /**
  • 0165 * Specify the address family: Internet Protocol, Version 4
  • 0166 * @since 1.4
  • 0167 */
  • 0168 static final int IPv4 = 1;
  • 0169
  • 0170 /**
  • 0171 * Specify the address family: Internet Protocol, Version 6
  • 0172 * @since 1.4
  • 0173 */
  • 0174 static final int IPv6 = 2;
  • 0175
  • 0176 /* Specify address family preference */
  • 0177 static transient boolean preferIPv6Address = false;
  • 0178
  • 0179 /**
  • 0180 * @serial
  • 0181 */
  • 0182 String hostName;
  • 0183
  • 0184 /**
  • 0185 * Holds a 32-bit IPv4 address.
  • 0186 *
  • 0187 * @serial
  • 0188 */
  • 0189 int address;
  • 0190
  • 0191 /**
  • 0192 * Specifies the address family type, for instance, '1' for IPv4
  • 0193 * addresses, and '2' for IPv6 addresses.
  • 0194 *
  • 0195 * @serial
  • 0196 */
  • 0197 int family;
  • 0198
  • 0199 /* Used to store the name service provider */
  • 0200 private static NameService nameService = null;
  • 0201
  • 0202 /* Used to store the best available hostname */
  • 0203 private transient String canonicalHostName = null;
  • 0204
  • 0205 /** use serialVersionUID from JDK 1.0.2 for interoperability */
  • 0206 private static final long serialVersionUID = 3286316764910316507L;
  • 0207
  • 0208 /*
  • 0209 * Load net library into runtime, and perform initializations.
  • 0210 */
  • 0211 static {
  • 0212 preferIPv6Address =
  • 0213 ((Boolean)java.security.AccessController.doPrivileged(
  • 0214 new GetBooleanAction("java.net.preferIPv6Addresses"))).booleanValue();
  • 0215 AccessController.doPrivileged(new LoadLibraryAction("net"));
  • 0216 init();
  • 0217 }
  • 0218
  • 0219 /**
  • 0220 * Constructor for the Socket.accept() method.
  • 0221 * This creates an empty InetAddress, which is filled in by
  • 0222 * the accept() method. This InetAddress, however, is not
  • 0223 * put in the address cache, since it is not created by name.
  • 0224 */
  • 0225 InetAddress() {
  • 0226 }
  • 0227
  • 0228 /**
  • 0229 * Replaces the de-serialized object with an Inet4Address object.
  • 0230 *
  • 0231 * @return the alternate object to the de-serialized object.
  • 0232 *
  • 0233 * @throws ObjectStreamException if a new object replacing this
  • 0234 * object could not be created
  • 0235 */
  • 0236 private Object readResolve() throws ObjectStreamException {
  • 0237 // will replace the deserialized 'this' object
  • 0238 return new Inet4Address(this.hostName, this.address);
  • 0239 }
  • 0240
  • 0241 /**
  • 0242 * Utility routine to check if the InetAddress is an
  • 0243 * IP multicast address.
  • 0244 * @return a <code>boolean</code> indicating if the InetAddress is
  • 0245 * an IP multicast address
  • 0246 * @since JDK1.1
  • 0247 */
  • 0248 public boolean isMulticastAddress() {
  • 0249 return false;
  • 0250 }
  • 0251
  • 0252 /**
  • 0253 * Utility routine to check if the InetAddress in a wildcard address.
  • 0254 * @return a <code>boolean</code> indicating if the Inetaddress is
  • 0255 * a wildcard address.
  • 0256 * @since 1.4
  • 0257 */
  • 0258 public boolean isAnyLocalAddress() {
  • 0259 return false;
  • 0260 }
  • 0261
  • 0262 /**
  • 0263 * Utility routine to check if the InetAddress is a loopback address.
  • 0264 *
  • 0265 * @return a <code>boolean</code> indicating if the InetAddress is
  • 0266 * a loopback address; or false otherwise.
  • 0267 * @since 1.4
  • 0268 */
  • 0269 public boolean isLoopbackAddress() {
  • 0270 return false;
  • 0271 }
  • 0272
  • 0273 /**
  • 0274 * Utility routine to check if the InetAddress is an link local address.
  • 0275 *
  • 0276 * @return a <code>boolean</code> indicating if the InetAddress is
  • 0277 * a link local address; or false if address is not a link local unicast address.
  • 0278 * @since 1.4
  • 0279 */
  • 0280 public boolean isLinkLocalAddress() {
  • 0281 return false;
  • 0282 }
  • 0283
  • 0284 /**
  • 0285 * Utility routine to check if the InetAddress is a site local address.
  • 0286 *
  • 0287 * @return a <code>boolean</code> indicating if the InetAddress is
  • 0288 * a site local address; or false if address is not a site local unicast address.
  • 0289 * @since 1.4
  • 0290 */
  • 0291 public boolean isSiteLocalAddress() {
  • 0292 return false;
  • 0293 }
  • 0294
  • 0295 /**
  • 0296 * Utility routine to check if the multicast address has global scope.
  • 0297 *
  • 0298 * @return a <code>boolean</code> indicating if the address has
  • 0299 * is a multicast address of global scope, false if it is not
  • 0300 * of global scope or it is not a multicast address
  • 0301 * @since 1.4
  • 0302 */
  • 0303 public boolean isMCGlobal() {
  • 0304 return false;
  • 0305 }
  • 0306
  • 0307 /**
  • 0308 * Utility routine to check if the multicast address has node scope.
  • 0309 *
  • 0310 * @return a <code>boolean</code> indicating if the address has
  • 0311 * is a multicast address of node-local scope, false if it is not
  • 0312 * of node-local scope or it is not a multicast address
  • 0313 * @since 1.4
  • 0314 */
  • 0315 public boolean isMCNodeLocal() {
  • 0316 return false;
  • 0317 }
  • 0318
  • 0319 /**
  • 0320 * Utility routine to check if the multicast address has link scope.
  • 0321 *
  • 0322 * @return a <code>boolean</code> indicating if the address has
  • 0323 * is a multicast address of link-local scope, false if it is not
  • 0324 * of link-local scope or it is not a multicast address
  • 0325 * @since 1.4
  • 0326 */
  • 0327 public boolean isMCLinkLocal() {
  • 0328 return false;
  • 0329 }
  • 0330
  • 0331 /**
  • 0332 * Utility routine to check if the multicast address has site scope.
  • 0333 *
  • 0334 * @return a <code>boolean</code> indicating if the address has
  • 0335 * is a multicast address of site-local scope, false if it is not
  • 0336 * of site-local scope or it is not a multicast address
  • 0337 * @since 1.4
  • 0338 */
  • 0339 public boolean isMCSiteLocal() {
  • 0340 return false;
  • 0341 }
  • 0342
  • 0343 /**
  • 0344 * Utility routine to check if the multicast address has organization scope.
  • 0345 *
  • 0346 * @return a <code>boolean</code> indicating if the address has
  • 0347 * is a multicast address of organization-local scope,
  • 0348 * false if it is not of organization-local scope
  • 0349 * or it is not a multicast address
  • 0350 * @since 1.4
  • 0351 */
  • 0352 public boolean isMCOrgLocal() {
  • 0353 return false;
  • 0354 }
  • 0355
  • 0356
  • 0357 /**
  • 0358 * Test whether that address is reachable. Best effort is made by the
  • 0359 * implementation to try to reach the host, but firewalls and server
  • 0360 * configuration may block requests resulting in a unreachable status
  • 0361 * while some specific ports may be accessible.
  • 0362 * A typical implementation will use ICMP ECHO REQUESTs if the
  • 0363 * privilege can be obtained, otherwise it will try to establish
  • 0364 * a TCP connection on port 7 (Echo) of the destination host.
  • 0365 * <p>
  • 0366 * The timeout value, in milliseconds, indicates the maximum amount of time
  • 0367 * the try should take. If the operation times out before getting an
  • 0368 * answer, the host is deemed unreachable. A negative value will result
  • 0369 * in an IllegalArgumentException being thrown.
  • 0370 *
  • 0371 * @param timeout the time, in milliseconds, before the call aborts
  • 0372 * @return a <code>boolean</code> indicating if the address is reachable.
  • 0373 * @throws IOException if a network error occurs
  • 0374 * @throws IllegalArgumentException if <code>timeout</code> is negative.
  • 0375 * @since 1.5
  • 0376 */
  • 0377 public boolean isReachable(int timeout) throws IOException {
  • 0378 return isReachable(null, 0 , timeout);
  • 0379 }
  • 0380
  • 0381 /**
  • 0382 * Test whether that address is reachable. Best effort is made by the
  • 0383 * implementation to try to reach the host, but firewalls and server
  • 0384 * configuration may block requests resulting in a unreachable status
  • 0385 * while some specific ports may be accessible.
  • 0386 * A typical implementation will use ICMP ECHO REQUESTs if the
  • 0387 * privilege can be obtained, otherwise it will try to establish
  • 0388 * a TCP connection on port 7 (Echo) of the destination host.
  • 0389 * <p>
  • 0390 * The <code>network interface</code> and <code>ttl</code> parameters
  • 0391 * let the caller specify which network interface the test will go through
  • 0392 * and the maximum number of hops the packets should go through.
  • 0393 * A negative value for the <code>ttl</code> will result in an
  • 0394 * IllegalArgumentException being thrown.
  • 0395 * <p>
  • 0396 * The timeout value, in milliseconds, indicates the maximum amount of time
  • 0397 * the try should take. If the operation times out before getting an
  • 0398 * answer, the host is deemed unreachable. A negative value will result
  • 0399 * in an IllegalArgumentException being thrown.
  • 0400 *
  • 0401 * @param netif the NetworkInterface through which the
  • 0402 * test will be done, or null for any interface
  • 0403 * @param ttl the maximum numbers of hops to try or 0 for the
  • 0404 * default
  • 0405 * @param timeout the time, in milliseconds, before the call aborts
  • 0406 * @throws IllegalArgumentException if either <code>timeout</code>
  • 0407 * or <code>ttl</code> are negative.
  • 0408 * @return a <code>boolean</code>indicating if the address is reachable.
  • 0409 * @throws IOException if a network error occurs
  • 0410 * @since 1.5
  • 0411 */
  • 0412 public boolean isReachable(NetworkInterface netif, int ttl,
  • 0413 int timeout) throws IOException {
  • 0414 if (ttl < 0)
  • 0415 throw new IllegalArgumentException("ttl can't be negative");
  • 0416 if (timeout < 0)
  • 0417 throw new IllegalArgumentException("timeout can't be negative");
  • 0418
  • 0419 return impl.isReachable(this, timeout, netif, ttl);
  • 0420 }
  • 0421
  • 0422 /**
  • 0423 * Gets the host name for this IP address.
  • 0424 *
  • 0425 * <p>If this InetAddress was created with a host name,
  • 0426 * this host name will be remembered and returned;
  • 0427 * otherwise, a reverse name lookup will be performed
  • 0428 * and the result will be returned based on the system
  • 0429 * configured name lookup service. If a lookup of the name service
  • 0430 * is required, call
  • 0431 * {@link #getCanonicalHostName() getCanonicalHostName}.
  • 0432 *
  • 0433 * <p>If there is a security manager, its
  • 0434 * <code>checkConnect</code> method is first called
  • 0435 * with the hostname and <code>-1</code>
  • 0436 * as its arguments to see if the operation is allowed.
  • 0437 * If the operation is not allowed, it will return
  • 0438 * the textual representation of the IP address.
  • 0439 *
  • 0440 * @return the host name for this IP address, or if the operation
  • 0441 * is not allowed by the security check, the textual
  • 0442 * representation of the IP address.
  • 0443 *
  • 0444 * @see InetAddress#getCanonicalHostName
  • 0445 * @see SecurityManager#checkConnect
  • 0446 */
  • 0447 public String getHostName() {
  • 0448 return getHostName(true);
  • 0449 }
  • 0450
  • 0451 /**
  • 0452 * Returns the hostname for this address.
  • 0453 * If the host is equal to null, then this address refers to any
  • 0454 * of the local machine's available network addresses.
  • 0455 * this is package private so SocketPermission can make calls into
  • 0456 * here without a security check.
  • 0457 *
  • 0458 * <p>If there is a security manager, this method first
  • 0459 * calls its <code>checkConnect</code> method
  • 0460 * with the hostname and <code>-1</code>
  • 0461 * as its arguments to see if the calling code is allowed to know
  • 0462 * the hostname for this IP address, i.e., to connect to the host.
  • 0463 * If the operation is not allowed, it will return
  • 0464 * the textual representation of the IP address.
  • 0465 *
  • 0466 * @return the host name for this IP address, or if the operation
  • 0467 * is not allowed by the security check, the textual
  • 0468 * representation of the IP address.
  • 0469 *
  • 0470 * @param check make security check if true
  • 0471 *
  • 0472 * @see SecurityManager#checkConnect
  • 0473 */
  • 0474 String getHostName(boolean check) {
  • 0475 if (hostName == null) {
  • 0476 hostName = InetAddress.getHostFromNameService(this, check);
  • 0477 }
  • 0478 return hostName;
  • 0479 }
  • 0480
  • 0481 /**
  • 0482 * Gets the fully qualified domain name for this IP address.
  • 0483 * Best effort method, meaning we may not be able to return
  • 0484 * the FQDN depending on the underlying system configuration.
  • 0485 *
  • 0486 * <p>If there is a security manager, this method first
  • 0487 * calls its <code>checkConnect</code> method
  • 0488 * with the hostname and <code>-1</code>
  • 0489 * as its arguments to see if the calling code is allowed to know
  • 0490 * the hostname for this IP address, i.e., to connect to the host.
  • 0491 * If the operation is not allowed, it will return
  • 0492 * the textual representation of the IP address.
  • 0493 *
  • 0494 * @return the fully qualified domain name for this IP address,
  • 0495 * or if the operation is not allowed by the security check,
  • 0496 * the textual representation of the IP address.
  • 0497 *
  • 0498 * @see SecurityManager#checkConnect
  • 0499 *
  • 0500 * @since 1.4
  • 0501 */
  • 0502 public String getCanonicalHostName() {
  • 0503 if (canonicalHostName == null) {
  • 0504 canonicalHostName =
  • 0505 InetAddress.getHostFromNameService(this, true);
  • 0506 }
  • 0507 return canonicalHostName;
  • 0508 }
  • 0509
  • 0510 /**
  • 0511 * Returns the hostname for this address.
  • 0512 *
  • 0513 * <p>If there is a security manager, this method first
  • 0514 * calls its <code>checkConnect</code> method
  • 0515 * with the hostname and <code>-1</code>
  • 0516 * as its arguments to see if the calling code is allowed to know
  • 0517 * the hostname for this IP address, i.e., to connect to the host.
  • 0518 * If the operation is not allowed, it will return
  • 0519 * the textual representation of the IP address.
  • 0520 *
  • 0521 * @return the host name for this IP address, or if the operation
  • 0522 * is not allowed by the security check, the textual
  • 0523 * representation of the IP address.
  • 0524 *
  • 0525 * @param check make security check if true
  • 0526 *
  • 0527 * @see SecurityManager#checkConnect
  • 0528 */
  • 0529 private static String getHostFromNameService(InetAddress addr, boolean check) {
  • 0530 String host;
  • 0531 try {
  • 0532 // first lookup the hostname
  • 0533 host = nameService.getHostByAddr(addr.getAddress());
  • 0534
  • 0535 /* check to see if calling code is allowed to know
  • 0536 * the hostname for this IP address, ie, connect to the host
  • 0537 */
  • 0538 if (check) {
  • 0539 SecurityManager sec = System.getSecurityManager();
  • 0540 if (sec != null) {
  • 0541 sec.checkConnect(host, -1);
  • 0542 }
  • 0543 }
  • 0544
  • 0545 /* now get all the IP addresses for this hostname,
  • 0546 * and make sure one of them matches the original IP
  • 0547 * address. We do this to try and prevent spoofing.
  • 0548 */
  • 0549
  • 0550 InetAddress[] arr = InetAddress.getAllByName0(host, check);
  • 0551 boolean ok = false;
  • 0552
  • 0553 if(arr != null) {
  • 0554 for(int i = 0; !ok && i < arr.length; i++) {
  • 0555 ok = addr.equals(arr[i]);
  • 0556 }
  • 0557 }
  • 0558
  • 0559 //XXX: if it looks a spoof just return the address?
  • 0560 if (!ok) {
  • 0561 host = addr.getHostAddress();
  • 0562 return host;
  • 0563 }
  • 0564
  • 0565 } catch (SecurityException e) {
  • 0566 host = addr.getHostAddress();
  • 0567 } catch (UnknownHostException e) {
  • 0568 host = addr.getHostAddress();
  • 0569 }
  • 0570 return host;
  • 0571 }
  • 0572
  • 0573 /**
  • 0574 * Returns the raw IP address of this <code>InetAddress</code>
  • 0575 * object. The result is in network byte order: the highest order
  • 0576 * byte of the address is in <code>getAddress()[0]</code>.
  • 0577 *
  • 0578 * @return the raw IP address of this object.
  • 0579 */
  • 0580 public byte[] getAddress() {
  • 0581 return null;
  • 0582 }
  • 0583
  • 0584 /**
  • 0585 * Returns the IP address string in textual presentation.
  • 0586 *
  • 0587 * @return the raw IP address in a string format.
  • 0588 * @since JDK1.0.2
  • 0589 */
  • 0590 public String getHostAddress() {
  • 0591 return null;
  • 0592 }
  • 0593
  • 0594 /**
  • 0595 * Returns a hashcode for this IP address.
  • 0596 *
  • 0597 * @return a hash code value for this IP address.
  • 0598 */
  • 0599 public int hashCode() {
  • 0600 return -1;
  • 0601 }
  • 0602
  • 0603 /**
  • 0604 * Compares this object against the specified object.
  • 0605 * The result is <code>true</code> if and only if the argument is
  • 0606 * not <code>null</code> and it represents the same IP address as
  • 0607 * this object.
  • 0608 * <p>
  • 0609 * Two instances of <code>InetAddress</code> represent the same IP
  • 0610 * address if the length of the byte arrays returned by
  • 0611 * <code>getAddress</code> is the same for both, and each of the
  • 0612 * array components is the same for the byte arrays.
  • 0613 *
  • 0614 * @param obj the object to compare against.
  • 0615 * @return <code>true</code> if the objects are the same;
  • 0616 * <code>false</code> otherwise.
  • 0617 * @see java.net.InetAddress#getAddress()
  • 0618 */
  • 0619 public boolean equals(Object obj) {
  • 0620 return false;
  • 0621 }
  • 0622
  • 0623 /**
  • 0624 * Converts this IP address to a <code>String</code>. The
  • 0625 * string returned is of the form: hostname / literal IP
  • 0626 * address.
  • 0627 *
  • 0628 * If the host name is unresolved, no reverse name service loopup
  • 0629 * is performed. The hostname part will be represented by an empty string.
  • 0630 *
  • 0631 * @return a string representation of this IP address.
  • 0632 */
  • 0633 public String toString() {
  • 0634 return ((hostName != null) ? hostName : "")
  • 0635 + "/" + getHostAddress();
  • 0636 }
  • 0637
  • 0638 /*
  • 0639 * Cached addresses - our own litle nis, not!
  • 0640 */
  • 0641 private static Cache addressCache = new Cache(Cache.Type.Positive);
  • 0642
  • 0643 private static Cache negativeCache = new Cache(Cache.Type.Negative);
  • 0644
  • 0645 private static boolean addressCacheInit = false;
  • 0646
  • 0647 static InetAddress[] unknown_array; // put THIS in cache
  • 0648
  • 0649 static InetAddressImpl impl;
  • 0650
  • 0651 private static HashMap lookupTable = new HashMap();
  • 0652
  • 0653 /**
  • 0654 * Represents a cache entry
  • 0655 */
  • 0656 static final class CacheEntry {
  • 0657
  • 0658 CacheEntry(Object address, long expiration) {
  • 0659 this.address = address;
  • 0660 this.expiration = expiration;
  • 0661 }
  • 0662
  • 0663 Object address;
  • 0664 long expiration;
  • 0665 }
  • 0666
  • 0667 /**
  • 0668 * A cache that manages entries based on a policy specified
  • 0669 * at creation time.
  • 0670 */
  • 0671 static final class Cache {
  • 0672 private LinkedHashMap cache;
  • 0673 private Type type;
  • 0674
  • 0675 enum Type {Positive, Negative};
  • 0676
  • 0677 /**
  • 0678 * Create cache
  • 0679 */
  • 0680 public Cache(Type type) {
  • 0681 this.type = type;
  • 0682 cache = new LinkedHashMap();
  • 0683 }
  • 0684
  • 0685 private int getPolicy() {
  • 0686 if (type == Type.Positive) {
  • 0687 return InetAddressCachePolicy.get();
  • 0688 } else {
  • 0689 return InetAddressCachePolicy.getNegative();
  • 0690 }
  • 0691 }
  • 0692
  • 0693 /**
  • 0694 * Add an entry to the cache. If there's already an
  • 0695 * entry then for this host then the entry will be
  • 0696 * replaced.
  • 0697 */
  • 0698 public Cache put(String host, Object address) {
  • 0699 int policy = getPolicy();
  • 0700 if (policy == InetAddressCachePolicy.NEVER) {
  • 0701 return this;
  • 0702 }
  • 0703
  • 0704 // purge any expired entries
  • 0705
  • 0706 if (policy != InetAddressCachePolicy.FOREVER) {
  • 0707
  • 0708 // As we iterate in insertion order we can
  • 0709 // terminate when a non-expired entry is found.
  • 0710 LinkedList expired = new LinkedList();
  • 0711 Iterator i = cache.keySet().iterator();
  • 0712 long now = System.currentTimeMillis();
  • 0713 while (i.hasNext()) {
  • 0714 String key = (String)i.next();
  • 0715 CacheEntry entry = (CacheEntry)cache.get(key);
  • 0716
  • 0717 if (entry.expiration >= 0 && entry.expiration < now) {
  • 0718 expired.add(key);
  • 0719 } else {
  • 0720 break;
  • 0721 }
  • 0722 }
  • 0723
  • 0724 i = expired.iterator();
  • 0725 while (i.hasNext()) {
  • 0726 cache.remove(i.next());
  • 0727 }
  • 0728 }
  • 0729
  • 0730 // create new entry and add it to the cache
  • 0731 // -- as a HashMap replaces existing entries we
  • 0732 // don't need to explicitly check if there is
  • 0733 // already an entry for this host.
  • 0734 long expiration;
  • 0735 if (policy == InetAddressCachePolicy.FOREVER) {
  • 0736 expiration = -1;
  • 0737 } else {
  • 0738 expiration = System.currentTimeMillis() + (policy * 1000);
  • 0739 }
  • 0740 CacheEntry entry = new CacheEntry(address, expiration);
  • 0741 cache.put(host, entry);
  • 0742 return this;
  • 0743 }
  • 0744
  • 0745 /**
  • 0746 * Query the cache for the specific host. If found then
  • 0747 * return its CacheEntry, or null if not found.
  • 0748 */
  • 0749 public CacheEntry get(String host) {
  • 0750 int policy = getPolicy();
  • 0751 if (policy == InetAddressCachePolicy.NEVER) {
  • 0752 return null;
  • 0753 }
  • 0754 CacheEntry entry = (CacheEntry)cache.get(host);
  • 0755
  • 0756 // check if entry has expired
  • 0757 if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
  • 0758 if (entry.expiration >= 0 &&
  • 0759 entry.expiration < System.currentTimeMillis()) {
  • 0760 cache.remove(host);
  • 0761 entry = null;
  • 0762 }
  • 0763 }
  • 0764
  • 0765 return entry;
  • 0766 }
  • 0767 }
  • 0768
  • 0769 /*
  • 0770 * Initialize cache and insert anyLocalAddress into the
  • 0771 * unknown array with no expiry.
  • 0772 */
  • 0773 private static void cacheInitIfNeeded() {
  • 0774 assert Thread.holdsLock(addressCache);
  • 0775 if (addressCacheInit) {
  • 0776 return;
  • 0777 }
  • 0778 unknown_array = new InetAddress[1];
  • 0779 unknown_array[0] = impl.anyLocalAddress();
  • 0780
  • 0781 addressCache.put(impl.anyLocalAddress().getHostName(),
  • 0782 unknown_array);
  • 0783
  • 0784 addressCacheInit = true;
  • 0785 }
  • 0786
  • 0787 /*
  • 0788 * Cache the given hostname and address.
  • 0789 */
  • 0790 private static void cacheAddress(String hostname, Object address,
  • 0791 boolean success) {
  • 0792 hostname = hostname.toLowerCase();
  • 0793 synchronized (addressCache) {
  • 0794 cacheInitIfNeeded();
  • 0795 if (success) {
  • 0796 addressCache.put(hostname, address);
  • 0797 } else {
  • 0798 negativeCache.put(hostname, address);
  • 0799 }
  • 0800 }
  • 0801 }
  • 0802
  • 0803 /*
  • 0804 * Lookup hostname in cache (positive & negative cache). If
  • 0805 * found return address, null if not found.
  • 0806 */
  • 0807 private static Object getCachedAddress(String hostname) {
  • 0808 hostname = hostname.toLowerCase();
  • 0809
  • 0810 // search both positive & negative caches
  • 0811
  • 0812 synchronized (addressCache) {
  • 0813 CacheEntry entry;
  • 0814
  • 0815 cacheInitIfNeeded();
  • 0816
  • 0817 entry = (CacheEntry)addressCache.get(hostname);
  • 0818 if (entry == null) {
  • 0819 entry = (CacheEntry)negativeCache.get(hostname);
  • 0820 }
  • 0821
  • 0822 if (entry != null) {
  • 0823 return entry.address;
  • 0824 }
  • 0825 }
  • 0826
  • 0827 // not found
  • 0828 return null;
  • 0829 }
  • 0830
  • 0831 static {
  • 0832 // create the impl
  • 0833 impl = (new InetAddressImplFactory()).create();
  • 0834
  • 0835 // get name service if provided and requested
  • 0836 String provider = null;;
  • 0837 String propPrefix = "sun.net.spi.nameservice.provider.";
  • 0838 int n = 1;
  • 0839 while (nameService == null) {
  • 0840 provider
  • 0841 = (String)AccessController.doPrivileged(
  • 0842 new GetPropertyAction(propPrefix+n, "default"));
  • 0843 n++;
  • 0844 if (provider.equals("default")) {
  • 0845 // initialize the default name service
  • 0846 nameService = new NameService() {
  • 0847 public InetAddress[] lookupAllHostAddr(String host)
  • 0848 throws UnknownHostException {
  • 0849 return impl.lookupAllHostAddr(host);
  • 0850 }
  • 0851 public String getHostByAddr(byte[] addr)
  • 0852 throws UnknownHostException {
  • 0853 return impl.getHostByAddr(addr);
  • 0854 }
  • 0855 };
  • 0856 break;
  • 0857 }
  • 0858
  • 0859 final String providerName = provider;
  • 0860
  • 0861 try {
  • 0862 java.security.AccessController.doPrivileged(
  • 0863 new java.security.PrivilegedExceptionAction() {
  • 0864 public Object run() {
  • 0865 Iterator itr
  • 0866 = Service.providers(NameServiceDescriptor.class);
  • 0867 while (itr.hasNext()) {
  • 0868 NameServiceDescriptor nsd
  • 0869 = (NameServiceDescriptor)itr.next();
  • 0870 if (providerName.
  • 0871 equalsIgnoreCase(nsd.getType()+","
  • 0872 +nsd.getProviderName())) {
  • 0873 try {
  • 0874 nameService = nsd.createNameService();
  • 0875 break;
  • 0876 } catch (Exception e) {
  • 0877 e.printStackTrace();
  • 0878 System.err.println(
  • 0879 "Cannot create name service:"
  • 0880 +providerName+": " + e);
  • 0881 }
  • 0882 }
  • 0883 } /* while */
  • 0884 return null;
  • 0885 }
  • 0886 });
  • 0887 } catch (java.security.PrivilegedActionException e) {
  • 0888 }
  • 0889
  • 0890 }
  • 0891 }
  • 0892
  • 0893 /**
  • 0894 * Create an InetAddress based on the provided host name and IP address
  • 0895 * No name service is checked for the validity of the address.
  • 0896 *
  • 0897 * <p> The host name can either be a machine name, such as
  • 0898 * "<code>java.sun.com</code>", or a textual representation of its IP
  • 0899 * address.
  • 0900 * <p> No validity checking is done on the host name either.
  • 0901 *
  • 0902 * <p> If addr specifies an IPv4 address an instance of Inet4Address
  • 0903 * will be returned; otherwise, an instance of Inet6Address
  • 0904 * will be returned.
  • 0905 *
  • 0906 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
  • 0907 * must be 16 bytes long
  • 0908 *
  • 0909 * @param host the specified host
  • 0910 * @param addr the raw IP address in network byte order
  • 0911 * @return an InetAddress object created from the raw IP address.
  • 0912 * @exception UnknownHostException if IP address is of illegal length
  • 0913 * @since 1.4
  • 0914 */
  • 0915 public static InetAddress getByAddress(String host, byte[] addr)
  • 0916 throws UnknownHostException {
  • 0917 if (host != null && host.length() > 0 && host.charAt(0) == '[') {
  • 0918 if (host.charAt(host.length()-1) == ']') {
  • 0919 host = host.substring(1, host.length() -1);
  • 0920 }
  • 0921 }
  • 0922 if (addr != null) {
  • 0923 if (addr.length == Inet4Address.INADDRSZ) {
  • 0924 return new Inet4Address(host, addr);
  • 0925 } else if (addr.length == Inet6Address.INADDRSZ) {
  • 0926 byte[] newAddr
  • 0927 = IPAddressUtil.convertFromIPv4MappedAddress(addr);
  • 0928 if (newAddr != null) {
  • 0929 return new Inet4Address(host, newAddr);
  • 0930 } else {
  • 0931 return new Inet6Address(host, addr);
  • 0932 }
  • 0933 }
  • 0934 }
  • 0935 throw new UnknownHostException("addr is of illegal length");
  • 0936 }
  • 0937
  • 0938
  • 0939 /**
  • 0940 * Determines the IP address of a host, given the host's name.
  • 0941 *
  • 0942 * <p> The host name can either be a machine name, such as
  • 0943 * "<code>java.sun.com</code>", or a textual representation of its
  • 0944 * IP address. If a literal IP address is supplied, only the
  • 0945 * validity of the address format is checked.
  • 0946 *
  • 0947 * <p> For <code>host</code> specified in literal IPv6 address,
  • 0948 * either the form defined in RFC 2732 or the literal IPv6 address
  • 0949 * format defined in RFC 2373 is accepted. IPv6 scoped addresses are also
  • 0950 * supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
  • 0951 * scoped addresses.
  • 0952 *
  • 0953 * <p> If the host is <tt>null</tt> then an <tt>InetAddress</tt>
  • 0954 * representing an address of the loopback interface is returned.
  • 0955 * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
  • 0956 * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
  • 0957 * section 2.5.3. </p>
  • 0958 *
  • 0959 * @param host the specified host, or <code>null</code>.
  • 0960 * @return an IP address for the given host name.
  • 0961 * @exception UnknownHostException if no IP address for the
  • 0962 * <code>host</code> could be found, or if a scope_id was specified
  • 0963 * for a global IPv6 address.
  • 0964 * @exception SecurityException if a security manager exists
  • 0965 * and its checkConnect method doesn't allow the operation
  • 0966 */
  • 0967 public static InetAddress getByName(String host)
  • 0968 throws UnknownHostException {
  • 0969 return InetAddress.getAllByName(host)[0];
  • 0970 }
  • 0971
  • 0972 // called from deployment cache manager
  • 0973 private static InetAddress getByName(String host, InetAddress reqAddr)
  • 0974 throws UnknownHostException {
  • 0975 return InetAddress.getAllByName(host, reqAddr)[0];
  • 0976 }
  • 0977
  • 0978 /**
  • 0979 * Given the name of a host, returns an array of its IP addresses,
  • 0980 * based on the configured name service on the system.
  • 0981 *
  • 0982 * <p> The host name can either be a machine name, such as
  • 0983 * "<code>java.sun.com</code>", or a textual representation of its IP
  • 0984 * address. If a literal IP address is supplied, only the
  • 0985 * validity of the address format is checked.
  • 0986 *
  • 0987 * <p> For <code>host</code> specified in <i>literal IPv6 address</i>,
  • 0988 * either the form defined in RFC 2732 or the literal IPv6 address
  • 0989 * format defined in RFC 2373 is accepted. A literal IPv6 address may
  • 0990 * also be qualified by appending a scoped zone identifier or scope_id.
  • 0991 * The syntax and usage of scope_ids is described
  • 0992 * <a href="Inet6Address.html#scoped">here</a>.
  • 0993 * <p> If the host is <tt>null</tt> then an <tt>InetAddress</tt>
  • 0994 * representing an address of the loopback interface is returned.
  • 0995 * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
  • 0996 * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
  • 0997 * section 2.5.3. </p>
  • 0998 *
  • 0999 * <p> If there is a security manager and <code>host</code> is not
  • 1000 * null and <code>host.length() </code> is not equal to zero, the
  • 1001 * security manager's
  • 1002 * <code>checkConnect</code> method is called
  • 1003 * with the hostname and <code>-1</code>
  • 1004 * as its arguments to see if the operation is allowed.
  • 1005 *
  • 1006 * @param host the name of the host, or <code>null</code>.
  • 1007 * @return an array of all the IP addresses for a given host name.
  • 1008 *
  • 1009 * @exception UnknownHostException if no IP address for the
  • 1010 * <code>host</code> could be found, or if a scope_id was specified
  • 1011 * for a global IPv6 address.
  • 1012 * @exception SecurityException if a security manager exists and its
  • 1013 * <code>checkConnect</code> method doesn't allow the operation.
  • 1014 *
  • 1015 * @see SecurityManager#checkConnect
  • 1016 */
  • 1017 public static InetAddress[] getAllByName(String host)
  • 1018 throws UnknownHostException {
  • 1019 return getAllByName(host, null);
  • 1020 }
  • 1021
  • 1022 private static InetAddress[] getAllByName(String host, InetAddress reqAddr)
  • 1023 throws UnknownHostException {
  • 1024
  • 1025 if (host == null || host.length() == 0) {
  • 1026 InetAddress[] ret = new InetAddress[1];
  • 1027 ret[0] = impl.loopbackAddress();
  • 1028 return ret;
  • 1029 }
  • 1030
  • 1031 boolean ipv6Expected = false;
  • 1032 if (host.charAt(0) == '[') {
  • 1033 // This is supposed to be an IPv6 litteral
  • 1034 if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
  • 1035 host = host.substring(1, host.length() -1);
  • 1036 ipv6Expected = true;
  • 1037 } else {
  • 1038 // This was supposed to be a IPv6 address, but it's not!
  • 1039 throw new UnknownHostException(host);
  • 1040 }
  • 1041 }
  • 1042
  • 1043 // if host is an IP address, we won't do further lookup
  • 1044 if (Character.digit(host.charAt(0), 16) != -1
  • 1045 || (host.charAt(0) == ':')) {
  • 1046 byte[] addr = null;
  • 1047 int numericZone = -1;
  • 1048 String ifname = null;
  • 1049 // see if it is IPv4 address
  • 1050 addr = IPAddressUtil.textToNumericFormatV4(host);
  • 1051 if (addr == null) {
  • 1052 // see if it is IPv6 address
  • 1053 // Check if a numeric or string zone id is present
  • 1054 int pos;
  • 1055 if ((pos=host.indexOf ("%")) != -1) {
  • 1056 numericZone = checkNumericZone (host);
  • 1057 if (numericZone == -1) { /* remainder of string must be an ifname */
  • 1058 ifname = host.substring (pos+1);
  • 1059 }
  • 1060 }
  • 1061 addr = IPAddressUtil.textToNumericFormatV6(host);
  • 1062 } else if (ipv6Expected) {
  • 1063 // Means an IPv4 litteral between brackets!
  • 1064 throw new UnknownHostException("["+host+"]");
  • 1065 }
  • 1066 InetAddress[] ret = new InetAddress[1];
  • 1067 if(addr != null) {
  • 1068 if (addr.length == Inet4Address.INADDRSZ) {
  • 1069 ret[0] = new Inet4Address(null, addr);
  • 1070 } else {
  • 1071 if (ifname != null) {
  • 1072 ret[0] = new Inet6Address(null, addr, ifname);
  • 1073 } else {
  • 1074 ret[0] = new Inet6Address(null, addr, numericZone);
  • 1075 }
  • 1076 }
  • 1077 return ret;
  • 1078 }
  • 1079 } else if (ipv6Expected) {
  • 1080 // We were expecting an IPv6 Litteral, but got something else
  • 1081 throw new UnknownHostException("["+host+"]");
  • 1082 }
  • 1083 return getAllByName0(host, reqAddr, true);
  • 1084 }
  • 1085
  • 1086 /**
  • 1087 * check if the literal address string has %nn appended
  • 1088 * returns -1 if not, or the numeric value otherwise.
  • 1089 *
  • 1090 * %nn may also be a string that represents the displayName of
  • 1091 * a currently available NetworkInterface.
  • 1092 */
  • 1093 private static int checkNumericZone (String s) throws UnknownHostException {
  • 1094 int percent = s.indexOf ('%');
  • 1095 int slen = s.length();
  • 1096 int digit, zone=0;
  • 1097 if (percent == -1) {
  • 1098 return -1;
  • 1099 }
  • 1100 for (int i=percent+1; i<slen; i++) {
  • 1101 char c = s.charAt(i);
  • 1102 if (c == ']') {
  • 1103 if (i == percent+1) {
  • 1104 /* empty per-cent field */
  • 1105 return -1;
  • 1106 }
  • 1107 break;
  • 1108 }
  • 1109 if ((digit = Character.digit (c, 10)) < 0) {
  • 1110 return -1;
  • 1111 }
  • 1112 zone = (zone * 10) + digit;
  • 1113 }
  • 1114 return zone;
  • 1115 }
  • 1116
  • 1117 private static InetAddress[] getAllByName0 (String host)
  • 1118 throws UnknownHostException
  • 1119 {
  • 1120 return getAllByName0(host, true);
  • 1121 }
  • 1122
  • 1123 /**
  • 1124 * package private so SocketPermission can call it
  • 1125 */
  • 1126 static InetAddress[] getAllByName0 (String host, boolean check)
  • 1127 throws UnknownHostException {
  • 1128 return getAllByName0 (host, null, check);
  • 1129 }
  • 1130
  • 1131 private static InetAddress[] getAllByName0 (String host, InetAddress reqAddr, boolean check)
  • 1132 throws UnknownHostException {
  • 1133
  • 1134 /* If it gets here it is presumed to be a hostname */
  • 1135 /* Cache.get can return: null, unknownAddress, or InetAddress[] */
  • 1136 Object obj = null;
  • 1137 Object objcopy = null;
  • 1138
  • 1139 /* make sure the connection to the host is allowed, before we
  • 1140 * give out a hostname
  • 1141 */
  • 1142 if (check) {
  • 1143 SecurityManager security = System.getSecurityManager();
  • 1144 if (security != null) {
  • 1145 security.checkConnect(host, -1);
  • 1146 }
  • 1147 }
  • 1148
  • 1149 obj = getCachedAddress(host);
  • 1150
  • 1151 /* If no entry in cache, then do the host lookup */
  • 1152 if (obj == null) {
  • 1153 obj = getAddressFromNameService(host, reqAddr);
  • 1154 }
  • 1155
  • 1156 if (obj == unknown_array)
  • 1157 throw new UnknownHostException(host);
  • 1158
  • 1159 /* Make a copy of the InetAddress array */
  • 1160 objcopy = ((InetAddress [])obj).clone();
  • 1161
  • 1162 return (InetAddress [])objcopy;
  • 1163 }
  • 1164
  • 1165 private static Object getAddressFromNameService(String host, InetAddress reqAddr)
  • 1166 throws UnknownHostException
  • 1167 {
  • 1168 Object obj = null;
  • 1169 boolean success = false;
  • 1170
  • 1171 // Check whether the host is in the lookupTable.
  • 1172 // 1) If the host isn't in the lookupTable when
  • 1173 // checkLookupTable() is called, checkLookupTable()
  • 1174 // would add the host in the lookupTable and
  • 1175 // return null. So we will do the lookup.
  • 1176 // 2) If the host is in the lookupTable when
  • 1177 // checkLookupTable() is called, the current thread
  • 1178 // would be blocked until the host is removed
  • 1179 // from the lookupTable. Then this thread
  • 1180 // should try to look up the addressCache.
  • 1181 // i) if it found the address in the
  • 1182 // addressCache, checkLookupTable() would
  • 1183 // return the address.
  • 1184 // ii) if it didn't find the address in the
  • 1185 // addressCache for any reason,
  • 1186 // it should add the host in the
  • 1187 // lookupTable and return null so the
  • 1188 // following code would do a lookup itself.
  • 1189 if ((obj = checkLookupTable(host)) == null) {
  • 1190 // This is the first thread which looks up the address
  • 1191 // this host or the cache entry for this host has been
  • 1192 // expired so this thread should do the lookup.
  • 1193 try {
  • 1194 /*
  • 1195 * Do not put the call to lookup() inside the
  • 1196 * constructor. if you do you will still be
  • 1197 * allocating space when the lookup fails.
  • 1198 */
  • 1199
  • 1200 obj = nameService.lookupAllHostAddr(host);
  • 1201 success = true;
  • 1202 } catch (UnknownHostException uhe) {
  • 1203 if (host.equalsIgnoreCase("localhost")) {
  • 1204 InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
  • 1205 obj = local;
  • 1206 success = true;
  • 1207 }
  • 1208 else {
  • 1209 obj = unknown_array;
  • 1210 success = false;
  • 1211 throw uhe;
  • 1212 }
  • 1213 } finally {
  • 1214 // More to do?
  • 1215 InetAddress[] addrs = (InetAddress[])obj;
  • 1216 if (reqAddr != null && addrs.length > 1 && !addrs[0].equals(reqAddr)) {
  • 1217 // Find it?
  • 1218 int i = 1;
  • 1219 for (; i < addrs.length; i++) {
  • 1220 if (addrs[i].equals(reqAddr)) {
  • 1221 break;
  • 1222 }
  • 1223 }
  • 1224 // Rotate
  • 1225 if (i < addrs.length) {
  • 1226 InetAddress tmp, tmp2 = reqAddr;
  • 1227 for (int j = 0; j < i; j++) {
  • 1228 tmp = addrs[j];
  • 1229 addrs[j] = tmp2;
  • 1230 tmp2 = tmp;
  • 1231 }
  • 1232 addrs[i] = tmp2;
  • 1233 }
  • 1234 }
  • 1235 // Cache the address.
  • 1236 cacheAddress(host, obj, success);
  • 1237 // Delete the host from the lookupTable, and
  • 1238 // notify all threads waiting for the monitor
  • 1239 // for lookupTable.
  • 1240 updateLookupTable(host);
  • 1241 }
  • 1242 }
  • 1243
  • 1244 return obj;
  • 1245 }
  • 1246
  • 1247
  • 1248 private static Object checkLookupTable(String host) {
  • 1249 // make sure obj is null.
  • 1250 Object obj = null;
  • 1251
  • 1252 synchronized (lookupTable) {
  • 1253 // If the host isn't in the lookupTable, add it in the
  • 1254 // lookuptable and return null. The caller should do
  • 1255 // the lookup.
  • 1256 if (lookupTable.containsKey(host) == false) {
  • 1257 lookupTable.put(host, null);
  • 1258 return obj;
  • 1259 }
  • 1260
  • 1261 // If the host is in the lookupTable, it means that another
  • 1262 // thread is trying to look up the address of this host.
  • 1263 // This thread should wait.
  • 1264 while (lookupTable.containsKey(host)) {
  • 1265 try {
  • 1266 lookupTable.wait();
  • 1267 } catch (InterruptedException e) {
  • 1268 }
  • 1269 }
  • 1270 }
  • 1271
  • 1272 // The other thread has finished looking up the address of
  • 1273 // the host. This thread should retry to get the address
  • 1274 // from the addressCache. If it doesn't get the address from
  • 1275 // the cache, it will try to look up the address itself.
  • 1276 obj = getCachedAddress(host);
  • 1277 if (obj == null) {
  • 1278 synchronized (lookupTable) {
  • 1279 lookupTable.put(host, null);
  • 1280 }
  • 1281 }
  • 1282
  • 1283 return obj;
  • 1284 }
  • 1285
  • 1286 private static void updateLookupTable(String host) {
  • 1287 synchronized (lookupTable) {
  • 1288 lookupTable.remove(host);
  • 1289 lookupTable.notifyAll();
  • 1290 }
  • 1291 }
  • 1292
  • 1293 /**
  • 1294 * Returns an <code>InetAddress</code> object given the raw IP address .
  • 1295 * The argument is in network byte order: the highest order
  • 1296 * byte of the address is in <code>getAddress()[0]</code>.
  • 1297 *
  • 1298 * <p> This method doesn't block, i.e. no reverse name service lookup
  • 1299 * is performed.
  • 1300 *
  • 1301 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
  • 1302 * must be 16 bytes long
  • 1303 *
  • 1304 * @param addr the raw IP address in network byte order
  • 1305 * @return an InetAddress object created from the raw IP address.
  • 1306 * @exception UnknownHostException if IP address is of illegal length
  • 1307 * @since 1.4
  • 1308 */
  • 1309 public static InetAddress getByAddress(byte[] addr)
  • 1310 throws UnknownHostException {
  • 1311 return getByAddress(null, addr);
  • 1312 }
  • 1313
  • 1314 /**
  • 1315 * Returns the local host.
  • 1316 *
  • 1317 * <p>If there is a security manager, its
  • 1318 * <code>checkConnect</code> method is called
  • 1319 * with the local host name and <code>-1</code>
  • 1320 * as its arguments to see if the operation is allowed.
  • 1321 * If the operation is not allowed, an InetAddress representing
  • 1322 * the loopback address is returned.
  • 1323 *
  • 1324 * @return the IP address of the local host.
  • 1325 *
  • 1326 * @exception UnknownHostException if no IP address for the
  • 1327 * <code>host</code> could be found.
  • 1328 *
  • 1329 * @see SecurityManager#checkConnect
  • 1330 */
  • 1331 public static InetAddress getLocalHost() throws UnknownHostException {
  • 1332
  • 1333 SecurityManager security = System.getSecurityManager();
  • 1334 try {
  • 1335 String local = impl.getLocalHostName();
  • 1336
  • 1337 if (security != null) {
  • 1338 security.checkConnect(local, -1);
  • 1339 }
  • 1340
  • 1341 if (local.equals("localhost")) {
  • 1342 return impl.loopbackAddress();
  • 1343 }
  • 1344
  • 1345 // we are calling getAddressFromNameService directly
  • 1346 // to avoid getting localHost from cache
  • 1347
  • 1348 InetAddress[] localAddrs;
  • 1349 try {
  • 1350 localAddrs =
  • 1351 (InetAddress[]) InetAddress.getAddressFromNameService(local, null);
  • 1352 } catch (UnknownHostException uhe) {
  • 1353 throw new UnknownHostException(local + ": " + uhe.getMessage());
  • 1354 }
  • 1355 return localAddrs[0];
  • 1356 } catch (java.lang.SecurityException e) {
  • 1357 return impl.loopbackAddress();
  • 1358 }
  • 1359 }
  • 1360
  • 1361
  • 1362 /**
  • 1363 * Perform class load-time initializations.
  • 1364 */
  • 1365 private static native void init();
  • 1366
  • 1367
  • 1368 /*
  • 1369 * Returns the InetAddress representing anyLocalAddress
  • 1370 * (typically 0.0.0.0 or ::0)
  • 1371 */
  • 1372 static InetAddress anyLocalAddress() {
  • 1373 return impl.anyLocalAddress();
  • 1374 }
  • 1375
  • 1376 /*
  • 1377 * Load and instantiate an underlying impl class
  • 1378 */
  • 1379 static Object loadImpl(String implName) {
  • 1380 Object impl;
  • 1381
  • 1382 /*
  • 1383 * Property "impl.prefix" will be prepended to the classname
  • 1384 * of the implementation object we instantiate, to which we
  • 1385 * delegate the real work (like native methods). This
  • 1386 * property can vary across implementations of the java.
  • 1387 * classes. The default is an empty String "".
  • 1388 */
  • 1389 String prefix = (String)AccessController.doPrivileged(
  • 1390 new GetPropertyAction("impl.prefix", ""));
  • 1391 impl = null;
  • 1392 try {
  • 1393 impl = Class.forName("java.net." + prefix + implName).newInstance();
  • 1394 } catch (ClassNotFoundException e) {
  • 1395 System.err.println("Class not found: java.net." + prefix +
  • 1396 implName + ":\ncheck impl.prefix property " +
  • 1397 "in your properties file.");
  • 1398 } catch (InstantiationException e) {
  • 1399 System.err.println("Could not instantiate: java.net." + prefix +
  • 1400 implName + ":\ncheck impl.prefix property " +
  • 1401 "in your properties file.");
  • 1402 } catch (IllegalAccessException e) {
  • 1403 System.err.println("Cannot access class: java.net." + prefix +
  • 1404 implName + ":\ncheck impl.prefix property " +
  • 1405 "in your properties file.");
  • 1406 }
  • 1407
  • 1408 if (impl == null) {
  • 1409 try {
  • 1410 impl = Class.forName(implName).newInstance();
  • 1411 } catch (Exception e) {
  • 1412 throw new Error("System property impl.prefix incorrect");
  • 1413 }
  • 1414 }
  • 1415
  • 1416 return impl;
  • 1417 }
  • 1418}
  • 1419
  • 1420/*
  • 1421 * Simple factory to create the impl
  • 1422 */
  • 1423class InetAddressImplFactory {
  • 1424
  • 1425 static InetAddressImpl create() {
  • 1426 Object o;
  • 1427 if (isIPv6Supported()) {
  • 1428 o = InetAddress.loadImpl("Inet6AddressImpl");
  • 1429 } else {
  • 1430 o = InetAddress.loadImpl("Inet4AddressImpl");
  • 1431 }
  • 1432 return (InetAddressImpl)o;
  • 1433 }
  • 1434
  • 1435 static native boolean isIPv6Supported();
  • 1436}

文件:InetAddress.java
包名:java.net
类名:InetAddress
继承:
接口:[java.io.Serializable]