1. /*
  2. * @(#)InetAddress.java 1.109 04/04/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.net;
  8. import java.util.HashMap;
  9. import java.util.LinkedHashMap;
  10. import java.util.Random;
  11. import java.util.Iterator;
  12. import java.util.LinkedList;
  13. import java.security.AccessController;
  14. import java.io.ObjectStreamException;
  15. import java.io.IOException;
  16. import sun.security.action.*;
  17. import sun.net.InetAddressCachePolicy;
  18. import sun.net.util.IPAddressUtil;
  19. import sun.misc.Service;
  20. import sun.net.spi.nameservice.*;
  21. /**
  22. * This class represents an Internet Protocol (IP) address.
  23. *
  24. * <p> An IP address is either a 32-bit or 128-bit unsigned number
  25. * used by IP, a lower-level protocol on which protocols like UDP and
  26. * TCP are built. The IP address architecture is defined by <a
  27. * href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC 790:
  28. * Assigned Numbers</i></a>, <a
  29. * href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC 1918:
  30. * Address Allocation for Private Internets</i></a>, <a
  31. * href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC 2365:
  32. * Administratively Scoped IP Multicast</i></a>, and <a
  33. * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP
  34. * Version 6 Addressing Architecture</i></a>. An instance of an
  35. * InetAddress consists of an IP address and possibly its
  36. * corresponding host name (depending on whether it is constructed
  37. * with a host name or whether it has already done reverse host name
  38. * resolution).
  39. *
  40. * <h4> Address types </h4>
  41. *
  42. * <blockquote><table cellspacing=2 summary="Description of unicast and multicast address types">
  43. * <tr><th valign=top><i>unicast</i></th>
  44. * <td>An identifier for a single interface. A packet sent to
  45. * a unicast address is delivered to the interface identified by
  46. * that address.
  47. *
  48. * <p> The Unspecified Address -- Also called anylocal or wildcard
  49. * address. It must never be assigned to any node. It indicates the
  50. * absence of an address. One example of its use is as the target of
  51. * bind, which allows a server to accept a client connection on any
  52. * interface, in case the server host has multiple interfaces.
  53. *
  54. * <p> The <i>unspecified</i> address must not be used as
  55. * the destination address of an IP packet.
  56. *
  57. * <p> The <i>Loopback</i> Addresses -- This is the address
  58. * assigned to the loopback interface. Anything sent to this
  59. * IP address loops around and becomes IP input on the local
  60. * host. This address is often used when testing a
  61. * client.</td></tr>
  62. * <tr><th valign=top><i>multicast</i></th>
  63. * <td>An identifier for a set of interfaces (typically belonging
  64. * to different nodes). A packet sent to a multicast address is
  65. * delivered to all interfaces identified by that address.</td></tr>
  66. * </table></blockquote>
  67. *
  68. * <h4> IP address scope </h4>
  69. *
  70. * <p> <i>Link-local</i> addresses are designed to be used for addressing
  71. * on a single link for purposes such as auto-address configuration,
  72. * neighbor discovery, or when no routers are present.
  73. *
  74. * <p> <i>Site-local</i> addresses are designed to be used for addressing
  75. * inside of a site without the need for a global prefix.
  76. *
  77. * <p> <i>Global</i> addresses are unique across the internet.
  78. *
  79. * <h4> Textual representation of IP addresses </h4>
  80. *
  81. * The textual representation of an IP address is address family specific.
  82. *
  83. * <p>
  84. *
  85. * For IPv4 address format, please refer to <A
  86. * HREF="Inet4Address.html#format">Inet4Address#format</A> For IPv6
  87. * address format, please refer to <A
  88. * HREF="Inet6Address.html#format">Inet6Address#format</A>.
  89. *
  90. * <h4> Host Name Resolution </h4>
  91. *
  92. * Host name-to-IP address <i>resolution</i> is accomplished through
  93. * the use of a combination of local machine configuration information
  94. * and network naming services such as the Domain Name System (DNS)
  95. * and Network Information Service(NIS). The particular naming
  96. * services(s) being used is by default the local machine configured
  97. * one. For any host name, its corresponding IP address is returned.
  98. *
  99. * <p> <i>Reverse name resolution</i> means that for any IP address,
  100. * the host associated with the IP address is returned.
  101. *
  102. * <p> The InetAddress class provides methods to resolve host names to
  103. * their IP addresses and vise versa.
  104. *
  105. * <h4> InetAddress Caching </h4>
  106. *
  107. * The InetAddress class has a cache to store successful as well as
  108. * unsuccessful host name resolutions. The positive caching is there
  109. * to guard against DNS spoofing attacks; while the negative caching
  110. * is used to improve performance.
  111. *
  112. * <p> By default, the result of positive host name resolutions are
  113. * cached forever, because there is no general rule to decide when it
  114. * is safe to remove cache entries. The result of unsuccessful host
  115. * name resolution is cached for a very short period of time (10
  116. * seconds) to improve performance.
  117. *
  118. * <p> Under certain circumstances where it can be determined that DNS
  119. * spoofing attacks are not possible, a Java security property can be
  120. * set to a different Time-to-live (TTL) value for positive
  121. * caching. Likewise, a system admin can configure a different
  122. * negative caching TTL value when needed.
  123. *
  124. * <p> Two Java security properties control the TTL values used for
  125. * positive and negative host name resolution caching:
  126. *
  127. * <blockquote>
  128. * <dl>
  129. * <dt><b>networkaddress.cache.ttl</b> (default: -1)</dt>
  130. * <dd>Indicates the caching policy for successful name lookups from
  131. * the name service. The value is specified as as integer to indicate
  132. * the number of seconds to cache the successful lookup.
  133. * <p>
  134. * A value of -1 indicates "cache forever".
  135. * </dd>
  136. * <p>
  137. * <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>
  138. * <dd>Indicates the caching policy for un-successful name lookups
  139. * from the name service. The value is specified as as integer to
  140. * indicate the number of seconds to cache the failure for
  141. * un-successful lookups.
  142. * <p>
  143. * A value of 0 indicates "never cache".
  144. * A value of -1 indicates "cache forever".
  145. * </dd>
  146. * </dl>
  147. * </blockquote>
  148. *
  149. * @author Chris Warth
  150. * @version 1.109, 04/19/04
  151. * @see java.net.InetAddress#getByAddress(byte[])
  152. * @see java.net.InetAddress#getByAddress(java.lang.String, byte[])
  153. * @see java.net.InetAddress#getAllByName(java.lang.String)
  154. * @see java.net.InetAddress#getByName(java.lang.String)
  155. * @see java.net.InetAddress#getLocalHost()
  156. * @since JDK1.0
  157. */
  158. public
  159. class InetAddress implements java.io.Serializable {
  160. /**
  161. * Specify the address family: Internet Protocol, Version 4
  162. * @since 1.4
  163. */
  164. static final int IPv4 = 1;
  165. /**
  166. * Specify the address family: Internet Protocol, Version 6
  167. * @since 1.4
  168. */
  169. static final int IPv6 = 2;
  170. /* Specify address family preference */
  171. static transient boolean preferIPv6Address = false;
  172. /**
  173. * @serial
  174. */
  175. String hostName;
  176. /**
  177. * Holds a 32-bit IPv4 address.
  178. *
  179. * @serial
  180. */
  181. int address;
  182. /**
  183. * Specifies the address family type, for instance, '1' for IPv4
  184. * addresses, and '2' for IPv6 addresses.
  185. *
  186. * @serial
  187. */
  188. int family;
  189. /* Used to store the name service provider */
  190. private static NameService nameService = null;
  191. /* Used to store the best available hostname */
  192. private transient String canonicalHostName = null;
  193. /** use serialVersionUID from JDK 1.0.2 for interoperability */
  194. private static final long serialVersionUID = 3286316764910316507L;
  195. /*
  196. * Load net library into runtime, and perform initializations.
  197. */
  198. static {
  199. preferIPv6Address =
  200. ((Boolean)java.security.AccessController.doPrivileged(
  201. new GetBooleanAction("java.net.preferIPv6Addresses"))).booleanValue();
  202. AccessController.doPrivileged(new LoadLibraryAction("net"));
  203. init();
  204. }
  205. /**
  206. * Constructor for the Socket.accept() method.
  207. * This creates an empty InetAddress, which is filled in by
  208. * the accept() method. This InetAddress, however, is not
  209. * put in the address cache, since it is not created by name.
  210. */
  211. InetAddress() {
  212. }
  213. /**
  214. * Replaces the de-serialized object with an Inet4Address object.
  215. *
  216. * @return the alternate object to the de-serialized object.
  217. *
  218. * @throws ObjectStreamException if a new object replacing this
  219. * object could not be created
  220. */
  221. private Object readResolve() throws ObjectStreamException {
  222. // will replace the deserialized 'this' object
  223. return new Inet4Address(this.hostName, this.address);
  224. }
  225. /**
  226. * Utility routine to check if the InetAddress is an
  227. * IP multicast address.
  228. * @return a <code>boolean</code> indicating if the InetAddress is
  229. * an IP multicast address
  230. * @since JDK1.1
  231. */
  232. public boolean isMulticastAddress() {
  233. return false;
  234. }
  235. /**
  236. * Utility routine to check if the InetAddress in a wildcard address.
  237. * @return a <code>boolean</code> indicating if the Inetaddress is
  238. * a wildcard address.
  239. * @since 1.4
  240. */
  241. public boolean isAnyLocalAddress() {
  242. return false;
  243. }
  244. /**
  245. * Utility routine to check if the InetAddress is a loopback address.
  246. *
  247. * @return a <code>boolean</code> indicating if the InetAddress is
  248. * a loopback address; or false otherwise.
  249. * @since 1.4
  250. */
  251. public boolean isLoopbackAddress() {
  252. return false;
  253. }
  254. /**
  255. * Utility routine to check if the InetAddress is an link local address.
  256. *
  257. * @return a <code>boolean</code> indicating if the InetAddress is
  258. * a link local address; or false if address is not a link local unicast address.
  259. * @since 1.4
  260. */
  261. public boolean isLinkLocalAddress() {
  262. return false;
  263. }
  264. /**
  265. * Utility routine to check if the InetAddress is a site local address.
  266. *
  267. * @return a <code>boolean</code> indicating if the InetAddress is
  268. * a site local address; or false if address is not a site local unicast address.
  269. * @since 1.4
  270. */
  271. public boolean isSiteLocalAddress() {
  272. return false;
  273. }
  274. /**
  275. * Utility routine to check if the multicast address has global scope.
  276. *
  277. * @return a <code>boolean</code> indicating if the address has
  278. * is a multicast address of global scope, false if it is not
  279. * of global scope or it is not a multicast address
  280. * @since 1.4
  281. */
  282. public boolean isMCGlobal() {
  283. return false;
  284. }
  285. /**
  286. * Utility routine to check if the multicast address has node scope.
  287. *
  288. * @return a <code>boolean</code> indicating if the address has
  289. * is a multicast address of node-local scope, false if it is not
  290. * of node-local scope or it is not a multicast address
  291. * @since 1.4
  292. */
  293. public boolean isMCNodeLocal() {
  294. return false;
  295. }
  296. /**
  297. * Utility routine to check if the multicast address has link scope.
  298. *
  299. * @return a <code>boolean</code> indicating if the address has
  300. * is a multicast address of link-local scope, false if it is not
  301. * of link-local scope or it is not a multicast address
  302. * @since 1.4
  303. */
  304. public boolean isMCLinkLocal() {
  305. return false;
  306. }
  307. /**
  308. * Utility routine to check if the multicast address has site scope.
  309. *
  310. * @return a <code>boolean</code> indicating if the address has
  311. * is a multicast address of site-local scope, false if it is not
  312. * of site-local scope or it is not a multicast address
  313. * @since 1.4
  314. */
  315. public boolean isMCSiteLocal() {
  316. return false;
  317. }
  318. /**
  319. * Utility routine to check if the multicast address has organization scope.
  320. *
  321. * @return a <code>boolean</code> indicating if the address has
  322. * is a multicast address of organization-local scope,
  323. * false if it is not of organization-local scope
  324. * or it is not a multicast address
  325. * @since 1.4
  326. */
  327. public boolean isMCOrgLocal() {
  328. return false;
  329. }
  330. /**
  331. * Test whether that address is reachable. Best effort is made by the
  332. * implementation to try to reach the host, but firewalls and server
  333. * configuration may block requests resulting in a unreachable status
  334. * while some specific ports may be accessible.
  335. * A typical implementation will use ICMP ECHO REQUESTs if the
  336. * privilege can be obtained, otherwise it will try to establish
  337. * a TCP connection on port 7 (Echo) of the destination host.
  338. * <p>
  339. * The timeout value, in milliseconds, indicates the maximum amount of time
  340. * the try should take. If the operation times out before getting an
  341. * answer, the host is deemed unreachable. A negative value will result
  342. * in an IllegalArgumentException being thrown.
  343. *
  344. * @param timeout the time, in milliseconds, before the call aborts
  345. * @return a <code>boolean</code> indicating if the address is reachable.
  346. * @throws IOException if a network error occurs
  347. * @throws IllegalArgumentException if <code>timeout</code> is negative.
  348. * @since 1.5
  349. */
  350. public boolean isReachable(int timeout) throws IOException {
  351. return isReachable(null, 0 , timeout);
  352. }
  353. /**
  354. * Test whether that address is reachable. Best effort is made by the
  355. * implementation to try to reach the host, but firewalls and server
  356. * configuration may block requests resulting in a unreachable status
  357. * while some specific ports may be accessible.
  358. * A typical implementation will use ICMP ECHO REQUESTs if the
  359. * privilege can be obtained, otherwise it will try to establish
  360. * a TCP connection on port 7 (Echo) of the destination host.
  361. * <p>
  362. * The <code>network interface</code> and <code>ttl</code> parameters
  363. * let the caller specify which network interface the test will go through
  364. * and the maximum number of hops the packets should go through.
  365. * A negative value for the <code>ttl</code> will result in an
  366. * IllegalArgumentException being thrown.
  367. * <p>
  368. * The timeout value, in milliseconds, indicates the maximum amount of time
  369. * the try should take. If the operation times out before getting an
  370. * answer, the host is deemed unreachable. A negative value will result
  371. * in an IllegalArgumentException being thrown.
  372. *
  373. * @param netif the NetworkInterface through which the
  374. * test will be done, or null for any interface
  375. * @param ttl the maximum numbers of hops to try or 0 for the
  376. * default
  377. * @param timeout the time, in milliseconds, before the call aborts
  378. * @throws IllegalArgumentException if either <code>timeout</code>
  379. * or <code>ttl</code> are negative.
  380. * @return a <code>boolean</code>indicating if the address is reachable.
  381. * @throws IOException if a network error occurs
  382. * @since 1.5
  383. */
  384. public boolean isReachable(NetworkInterface netif, int ttl,
  385. int timeout) throws IOException {
  386. if (ttl < 0)
  387. throw new IllegalArgumentException("ttl can't be negative");
  388. if (timeout < 0)
  389. throw new IllegalArgumentException("timeout can't be negative");
  390. return impl.isReachable(this, timeout, netif, ttl);
  391. }
  392. /**
  393. * Gets the host name for this IP address.
  394. *
  395. * <p>If this InetAddress was created with a host name,
  396. * this host name will be remembered and returned;
  397. * otherwise, a reverse name lookup will be performed
  398. * and the result will be returned based on the system
  399. * configured name lookup service. If a lookup of the name service
  400. * is required, call
  401. * {@link #getCanonicalHostName() getCanonicalHostName}.
  402. *
  403. * <p>If there is a security manager, its
  404. * <code>checkConnect</code> method is first called
  405. * with the hostname and <code>-1</code>
  406. * as its arguments to see if the operation is allowed.
  407. * If the operation is not allowed, it will return
  408. * the textual representation of the IP address.
  409. *
  410. * @return the host name for this IP address, or if the operation
  411. * is not allowed by the security check, the textual
  412. * representation of the IP address.
  413. *
  414. * @see InetAddress#getCanonicalHostName
  415. * @see SecurityManager#checkConnect
  416. */
  417. public String getHostName() {
  418. return getHostName(true);
  419. }
  420. /**
  421. * Returns the hostname for this address.
  422. * If the host is equal to null, then this address refers to any
  423. * of the local machine's available network addresses.
  424. * this is package private so SocketPermission can make calls into
  425. * here without a security check.
  426. *
  427. * <p>If there is a security manager, this method first
  428. * calls its <code>checkConnect</code> method
  429. * with the hostname and <code>-1</code>
  430. * as its arguments to see if the calling code is allowed to know
  431. * the hostname for this IP address, i.e., to connect to the host.
  432. * If the operation is not allowed, it will return
  433. * the textual representation of the IP address.
  434. *
  435. * @return the host name for this IP address, or if the operation
  436. * is not allowed by the security check, the textual
  437. * representation of the IP address.
  438. *
  439. * @param check make security check if true
  440. *
  441. * @see SecurityManager#checkConnect
  442. */
  443. String getHostName(boolean check) {
  444. if (hostName == null) {
  445. hostName = InetAddress.getHostFromNameService(this, check);
  446. }
  447. return hostName;
  448. }
  449. /**
  450. * Gets the fully qualified domain name for this IP address.
  451. * Best effort method, meaning we may not be able to return
  452. * the FQDN depending on the underlying system configuration.
  453. *
  454. * <p>If there is a security manager, this method first
  455. * calls its <code>checkConnect</code> method
  456. * with the hostname and <code>-1</code>
  457. * as its arguments to see if the calling code is allowed to know
  458. * the hostname for this IP address, i.e., to connect to the host.
  459. * If the operation is not allowed, it will return
  460. * the textual representation of the IP address.
  461. *
  462. * @return the fully qualified domain name for this IP address,
  463. * or if the operation is not allowed by the security check,
  464. * the textual representation of the IP address.
  465. *
  466. * @see SecurityManager#checkConnect
  467. *
  468. * @since 1.4
  469. */
  470. public String getCanonicalHostName() {
  471. if (canonicalHostName == null) {
  472. canonicalHostName =
  473. InetAddress.getHostFromNameService(this, true);
  474. }
  475. return canonicalHostName;
  476. }
  477. /**
  478. * Returns the hostname for this address.
  479. *
  480. * <p>If there is a security manager, this method first
  481. * calls its <code>checkConnect</code> method
  482. * with the hostname and <code>-1</code>
  483. * as its arguments to see if the calling code is allowed to know
  484. * the hostname for this IP address, i.e., to connect to the host.
  485. * If the operation is not allowed, it will return
  486. * the textual representation of the IP address.
  487. *
  488. * @return the host name for this IP address, or if the operation
  489. * is not allowed by the security check, the textual
  490. * representation of the IP address.
  491. *
  492. * @param check make security check if true
  493. *
  494. * @see SecurityManager#checkConnect
  495. */
  496. private static String getHostFromNameService(InetAddress addr, boolean check) {
  497. String host;
  498. try {
  499. // first lookup the hostname
  500. host = nameService.getHostByAddr(addr.getAddress());
  501. /* check to see if calling code is allowed to know
  502. * the hostname for this IP address, ie, connect to the host
  503. */
  504. if (check) {
  505. SecurityManager sec = System.getSecurityManager();
  506. if (sec != null) {
  507. sec.checkConnect(host, -1);
  508. }
  509. }
  510. /* now get all the IP addresses for this hostname,
  511. * and make sure one of them matches the original IP
  512. * address. We do this to try and prevent spoofing.
  513. */
  514. InetAddress[] arr = InetAddress.getAllByName0(host, check);
  515. boolean ok = false;
  516. if(arr != null) {
  517. for(int i = 0; !ok && i < arr.length; i++) {
  518. ok = addr.equals(arr[i]);
  519. }
  520. }
  521. //XXX: if it looks a spoof just return the address?
  522. if (!ok) {
  523. host = addr.getHostAddress();
  524. return host;
  525. }
  526. } catch (SecurityException e) {
  527. host = addr.getHostAddress();
  528. } catch (UnknownHostException e) {
  529. host = addr.getHostAddress();
  530. }
  531. return host;
  532. }
  533. /**
  534. * Returns the raw IP address of this <code>InetAddress</code>
  535. * object. The result is in network byte order: the highest order
  536. * byte of the address is in <code>getAddress()[0]</code>.
  537. *
  538. * @return the raw IP address of this object.
  539. */
  540. public byte[] getAddress() {
  541. return null;
  542. }
  543. /**
  544. * Returns the IP address string in textual presentation.
  545. *
  546. * @return the raw IP address in a string format.
  547. * @since JDK1.0.2
  548. */
  549. public String getHostAddress() {
  550. return null;
  551. }
  552. /**
  553. * Returns a hashcode for this IP address.
  554. *
  555. * @return a hash code value for this IP address.
  556. */
  557. public int hashCode() {
  558. return -1;
  559. }
  560. /**
  561. * Compares this object against the specified object.
  562. * The result is <code>true</code> if and only if the argument is
  563. * not <code>null</code> and it represents the same IP address as
  564. * this object.
  565. * <p>
  566. * Two instances of <code>InetAddress</code> represent the same IP
  567. * address if the length of the byte arrays returned by
  568. * <code>getAddress</code> is the same for both, and each of the
  569. * array components is the same for the byte arrays.
  570. *
  571. * @param obj the object to compare against.
  572. * @return <code>true</code> if the objects are the same;
  573. * <code>false</code> otherwise.
  574. * @see java.net.InetAddress#getAddress()
  575. */
  576. public boolean equals(Object obj) {
  577. return false;
  578. }
  579. /**
  580. * Converts this IP address to a <code>String</code>. The
  581. * string returned is of the form: hostname / literal IP
  582. * address.
  583. *
  584. * If the host name is unresolved, no reverse name service loopup
  585. * is performed. The hostname part will be represented by an empty string.
  586. *
  587. * @return a string representation of this IP address.
  588. */
  589. public String toString() {
  590. return ((hostName != null) ? hostName : "")
  591. + "/" + getHostAddress();
  592. }
  593. /*
  594. * Cached addresses - our own litle nis, not!
  595. */
  596. private static Cache addressCache =
  597. new Cache(InetAddressCachePolicy.get());
  598. private static Cache negativeCache =
  599. new Cache(InetAddressCachePolicy.getNegative());
  600. private static boolean addressCacheInit = false;
  601. static InetAddress[] unknown_array; // put THIS in cache
  602. static InetAddressImpl impl;
  603. private static HashMap lookupTable = new HashMap();
  604. /**
  605. * Represents a cache entry
  606. */
  607. static final class CacheEntry {
  608. CacheEntry(Object address, long expiration) {
  609. this.address = address;
  610. this.expiration = expiration;
  611. }
  612. Object address;
  613. long expiration;
  614. }
  615. /**
  616. * A cache that manages entries based on a policy specified
  617. * at creation time.
  618. */
  619. static final class Cache {
  620. private int policy;
  621. private LinkedHashMap cache;
  622. /**
  623. * Create cache with specific policy
  624. */
  625. public Cache(int policy) {
  626. this.policy = policy;
  627. cache = new LinkedHashMap();
  628. }
  629. /**
  630. * Add an entry to the cache. If there's already an
  631. * entry then for this host then the entry will be
  632. * replaced.
  633. */
  634. public Cache put(String host, Object address) {
  635. if (policy == InetAddressCachePolicy.NEVER) {
  636. return this;
  637. }
  638. // purge any expired entries
  639. if (policy != InetAddressCachePolicy.FOREVER) {
  640. // As we iterate in insertion order we can
  641. // terminate when a non-expired entry is found.
  642. LinkedList expired = new LinkedList();
  643. Iterator i = cache.keySet().iterator();
  644. long now = System.currentTimeMillis();
  645. while (i.hasNext()) {
  646. String key = (String)i.next();
  647. CacheEntry entry = (CacheEntry)cache.get(key);
  648. if (entry.expiration >= 0 && entry.expiration < now) {
  649. expired.add(key);
  650. } else {
  651. break;
  652. }
  653. }
  654. i = expired.iterator();
  655. while (i.hasNext()) {
  656. cache.remove(i.next());
  657. }
  658. }
  659. // create new entry and add it to the cache
  660. // -- as a HashMap replaces existing entries we
  661. // don't need to explicitly check if there is
  662. // already an entry for this host.
  663. long expiration;
  664. if (policy == InetAddressCachePolicy.FOREVER) {
  665. expiration = -1;
  666. } else {
  667. expiration = System.currentTimeMillis() + (policy * 1000);
  668. }
  669. CacheEntry entry = new CacheEntry(address, expiration);
  670. cache.put(host, entry);
  671. return this;
  672. }
  673. /**
  674. * Query the cache for the specific host. If found then
  675. * return its CacheEntry, or null if not found.
  676. */
  677. public CacheEntry get(String host) {
  678. if (policy == InetAddressCachePolicy.NEVER) {
  679. return null;
  680. }
  681. CacheEntry entry = (CacheEntry)cache.get(host);
  682. // check if entry has expired
  683. if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
  684. if (entry.expiration >= 0 &&
  685. entry.expiration < System.currentTimeMillis()) {
  686. cache.remove(host);
  687. entry = null;
  688. }
  689. }
  690. return entry;
  691. }
  692. }
  693. /*
  694. * Initialize cache and insert anyLocalAddress into the
  695. * unknown array with no expiry.
  696. */
  697. private static void cacheInitIfNeeded() {
  698. assert Thread.holdsLock(addressCache);
  699. if (addressCacheInit) {
  700. return;
  701. }
  702. unknown_array = new InetAddress[1];
  703. unknown_array[0] = impl.anyLocalAddress();
  704. addressCache.put(impl.anyLocalAddress().getHostName(),
  705. unknown_array);
  706. addressCacheInit = true;
  707. }
  708. /*
  709. * Cache the given hostname and address.
  710. */
  711. private static void cacheAddress(String hostname, Object address,
  712. boolean success) {
  713. hostname = hostname.toLowerCase();
  714. synchronized (addressCache) {
  715. cacheInitIfNeeded();
  716. if (success) {
  717. addressCache.put(hostname, address);
  718. } else {
  719. negativeCache.put(hostname, address);
  720. }
  721. }
  722. }
  723. /*
  724. * Lookup hostname in cache (positive & negative cache). If
  725. * found return address, null if not found.
  726. */
  727. private static Object getCachedAddress(String hostname) {
  728. hostname = hostname.toLowerCase();
  729. // search both positive & negative caches
  730. synchronized (addressCache) {
  731. CacheEntry entry;
  732. cacheInitIfNeeded();
  733. entry = (CacheEntry)addressCache.get(hostname);
  734. if (entry == null) {
  735. entry = (CacheEntry)negativeCache.get(hostname);
  736. }
  737. if (entry != null) {
  738. return entry.address;
  739. }
  740. }
  741. // not found
  742. return null;
  743. }
  744. static {
  745. // create the impl
  746. impl = (new InetAddressImplFactory()).create();
  747. // get name service if provided and requested
  748. String provider = null;;
  749. String propPrefix = "sun.net.spi.nameservice.provider.";
  750. int n = 1;
  751. while (nameService == null) {
  752. provider
  753. = (String)AccessController.doPrivileged(
  754. new GetPropertyAction(propPrefix+n, "default"));
  755. n++;
  756. if (provider.equals("default")) {
  757. // initialize the default name service
  758. nameService = new NameService() {
  759. public byte[][] lookupAllHostAddr(String host)
  760. throws UnknownHostException {
  761. return impl.lookupAllHostAddr(host);
  762. }
  763. public String getHostByAddr(byte[] addr)
  764. throws UnknownHostException {
  765. return impl.getHostByAddr(addr);
  766. }
  767. };
  768. break;
  769. }
  770. final String providerName = provider;
  771. try {
  772. java.security.AccessController.doPrivileged(
  773. new java.security.PrivilegedExceptionAction() {
  774. public Object run() {
  775. Iterator itr
  776. = Service.providers(NameServiceDescriptor.class);
  777. while (itr.hasNext()) {
  778. NameServiceDescriptor nsd
  779. = (NameServiceDescriptor)itr.next();
  780. if (providerName.
  781. equalsIgnoreCase(nsd.getType()+","
  782. +nsd.getProviderName())) {
  783. try {
  784. nameService = nsd.createNameService();
  785. break;
  786. } catch (Exception e) {
  787. e.printStackTrace();
  788. System.err.println(
  789. "Cannot create name service:"
  790. +providerName+": " + e);
  791. }
  792. }
  793. } /* while */
  794. return null;
  795. }
  796. });
  797. } catch (java.security.PrivilegedActionException e) {
  798. }
  799. }
  800. }
  801. /**
  802. * Create an InetAddress based on the provided host name and IP address
  803. * No name service is checked for the validity of the address.
  804. *
  805. * <p> The host name can either be a machine name, such as
  806. * "<code>java.sun.com</code>", or a textual representation of its IP
  807. * address.
  808. * <p> No validity checking is done on the host name either.
  809. *
  810. * <p> If addr specifies an IPv4 address an instance of Inet4Address
  811. * will be returned; otherwise, an instance of Inet6Address
  812. * will be returned.
  813. *
  814. * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
  815. * must be 16 bytes long
  816. *
  817. * @param host the specified host
  818. * @param addr the raw IP address in network byte order
  819. * @return an InetAddress object created from the raw IP address.
  820. * @exception UnknownHostException if IP address is of illegal length
  821. * @since 1.4
  822. */
  823. public static InetAddress getByAddress(String host, byte[] addr)
  824. throws UnknownHostException {
  825. if (host != null && host.length() > 0 && host.charAt(0) == '[') {
  826. if (host.charAt(host.length()-1) == ']') {
  827. host = host.substring(1, host.length() -1);
  828. }
  829. }
  830. if (addr != null) {
  831. if (addr.length == Inet4Address.INADDRSZ) {
  832. return new Inet4Address(host, addr);
  833. } else if (addr.length == Inet6Address.INADDRSZ) {
  834. byte[] newAddr
  835. = IPAddressUtil.convertFromIPv4MappedAddress(addr);
  836. if (newAddr != null) {
  837. return new Inet4Address(host, newAddr);
  838. } else {
  839. return new Inet6Address(host, addr);
  840. }
  841. }
  842. }
  843. throw new UnknownHostException("addr is of illegal length");
  844. }
  845. /**
  846. * Determines the IP address of a host, given the host's name.
  847. *
  848. * <p> The host name can either be a machine name, such as
  849. * "<code>java.sun.com</code>", or a textual representation of its
  850. * IP address. If a literal IP address is supplied, only the
  851. * validity of the address format is checked.
  852. *
  853. * <p> For <code>host</code> specified in literal IPv6 address,
  854. * either the form defined in RFC 2732 or the literal IPv6 address
  855. * format defined in RFC 2373 is accepted. IPv6 scoped addresses are also
  856. * supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
  857. * scoped addresses.
  858. *
  859. * <p> If the host is <tt>null</tt> then an <tt>InetAddress</tt>
  860. * representing an address of the loopback interface is returned.
  861. * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
  862. * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
  863. * section 2.5.3. </p>
  864. *
  865. * @param host the specified host, or <code>null</code>.
  866. * @return an IP address for the given host name.
  867. * @exception UnknownHostException if no IP address for the
  868. * <code>host</code> could be found, or if a scope_id was specified
  869. * for a global IPv6 address.
  870. * @exception SecurityException if a security manager exists
  871. * and its checkConnect method doesn't allow the operation
  872. */
  873. public static InetAddress getByName(String host)
  874. throws UnknownHostException {
  875. return InetAddress.getAllByName(host)[0];
  876. }
  877. /**
  878. * Given the name of a host, returns an array of its IP addresses,
  879. * based on the configured name service on the system.
  880. *
  881. * <p> The host name can either be a machine name, such as
  882. * "<code>java.sun.com</code>", or a textual representation of its IP
  883. * address. If a literal IP address is supplied, only the
  884. * validity of the address format is checked.
  885. *
  886. * <p> For <code>host</code> specified in <i>literal IPv6 address</i>,
  887. * either the form defined in RFC 2732 or the literal IPv6 address
  888. * format defined in RFC 2373 is accepted. A literal IPv6 address may
  889. * also be qualified by appending a scoped zone identifier or scope_id.
  890. * The syntax and usage of scope_ids is described
  891. * <a href="Inet6Address.html#scoped">here</a>.
  892. * <p> If the host is <tt>null</tt> then an <tt>InetAddress</tt>
  893. * representing an address of the loopback interface is returned.
  894. * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a>
  895. * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>
  896. * section 2.5.3. </p>
  897. *
  898. * <p> If there is a security manager and <code>host</code> is not
  899. * null and <code>host.length() </code> is not equal to zero, the
  900. * security manager's
  901. * <code>checkConnect</code> method is called
  902. * with the hostname and <code>-1</code>
  903. * as its arguments to see if the operation is allowed.
  904. *
  905. * @param host the name of the host, or <code>null</code>.
  906. * @return an array of all the IP addresses for a given host name.
  907. *
  908. * @exception UnknownHostException if no IP address for the
  909. * <code>host</code> could be found, or if a scope_id was specified
  910. * for a global IPv6 address.
  911. * @exception SecurityException if a security manager exists and its
  912. * <code>checkConnect</code> method doesn't allow the operation.
  913. *
  914. * @see SecurityManager#checkConnect
  915. */
  916. public static InetAddress[] getAllByName(String host)
  917. throws UnknownHostException {
  918. if (host == null || host.length() == 0) {
  919. InetAddress[] ret = new InetAddress[1];
  920. ret[0] = impl.loopbackAddress();
  921. return ret;
  922. }
  923. boolean ipv6Expected = false;
  924. if (host.charAt(0) == '[') {
  925. // This is supposed to be an IPv6 litteral
  926. if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
  927. host = host.substring(1, host.length() -1);
  928. ipv6Expected = true;
  929. } else {
  930. // This was supposed to be a IPv6 address, but it's not!
  931. throw new UnknownHostException(host);
  932. }
  933. }
  934. // if host is an IP address, we won't do further lookup
  935. if (Character.digit(host.charAt(0), 16) != -1
  936. || (host.charAt(0) == ':')) {
  937. byte[] addr = null;
  938. int numericZone = -1;
  939. String ifname = null;
  940. // see if it is IPv4 address
  941. addr = IPAddressUtil.textToNumericFormatV4(host);
  942. if (addr == null) {
  943. // see if it is IPv6 address
  944. // Check if a numeric or string zone id is present
  945. int pos;
  946. if ((pos=host.indexOf ("%")) != -1) {
  947. numericZone = checkNumericZone (host);
  948. if (numericZone == -1) { /* remainder of string must be an ifname */
  949. ifname = host.substring (pos+1);
  950. }
  951. }
  952. addr = IPAddressUtil.textToNumericFormatV6(host);
  953. } else if (ipv6Expected) {
  954. // Means an IPv4 litteral between brackets!
  955. throw new UnknownHostException("["+host+"]");
  956. }
  957. InetAddress[] ret = new InetAddress[1];
  958. if(addr != null) {
  959. if (addr.length == Inet4Address.INADDRSZ) {
  960. ret[0] = new Inet4Address(null, addr);
  961. } else {
  962. if (ifname != null) {
  963. ret[0] = new Inet6Address(null, addr, ifname);
  964. } else {
  965. ret[0] = new Inet6Address(null, addr, numericZone);
  966. }
  967. }
  968. return ret;
  969. }
  970. } else if (ipv6Expected) {
  971. // We were expecting an IPv6 Litteral, but got something else
  972. throw new UnknownHostException("["+host+"]");
  973. }
  974. return getAllByName0(host);
  975. }
  976. /**
  977. * check if the literal address string has %nn appended
  978. * returns -1 if not, or the numeric value otherwise.
  979. *
  980. * %nn may also be a string that represents the displayName of
  981. * a currently available NetworkInterface.
  982. */
  983. private static int checkNumericZone (String s) throws UnknownHostException {
  984. int percent = s.indexOf ('%');
  985. int slen = s.length();
  986. int digit, zone=0;
  987. if (percent == -1) {
  988. return -1;
  989. }
  990. for (int i=percent+1; i<slen; i++) {
  991. char c = s.charAt(i);
  992. if (c == ']') {
  993. if (i == percent+1) {
  994. /* empty per-cent field */
  995. return -1;
  996. }
  997. break;
  998. }
  999. if ((digit = Character.digit (c, 10)) < 0) {
  1000. return -1;
  1001. }
  1002. zone = (zone * 10) + digit;
  1003. }
  1004. return zone;
  1005. }
  1006. private static InetAddress[] getAllByName0 (String host)
  1007. throws UnknownHostException
  1008. {
  1009. return getAllByName0(host, true);
  1010. }
  1011. /**
  1012. * package private so SocketPermission can call it
  1013. */
  1014. static InetAddress[] getAllByName0 (String host, boolean check)
  1015. throws UnknownHostException {
  1016. /* If it gets here it is presumed to be a hostname */
  1017. /* Cache.get can return: null, unknownAddress, or InetAddress[] */
  1018. Object obj = null;
  1019. Object objcopy = null;
  1020. /* make sure the connection to the host is allowed, before we
  1021. * give out a hostname
  1022. */
  1023. if (check) {
  1024. SecurityManager security = System.getSecurityManager();
  1025. if (security != null) {
  1026. security.checkConnect(host, -1);
  1027. }
  1028. }
  1029. obj = getCachedAddress(host);
  1030. /* If no entry in cache, then do the host lookup */
  1031. if (obj == null) {
  1032. try {
  1033. obj = getAddressFromNameService(host);
  1034. } catch (UnknownHostException uhe) {
  1035. throw new UnknownHostException(host + ": " + uhe.getMessage());
  1036. }
  1037. }
  1038. if (obj == unknown_array)
  1039. throw new UnknownHostException(host);
  1040. /* Make a copy of the InetAddress array */
  1041. objcopy = ((InetAddress [])obj).clone();
  1042. return (InetAddress [])objcopy;
  1043. }
  1044. private static Object getAddressFromNameService(String host)
  1045. throws UnknownHostException
  1046. {
  1047. Object obj = null;
  1048. boolean success = false;
  1049. // Check whether the host is in the lookupTable.
  1050. // 1) If the host isn't in the lookupTable when
  1051. // checkLookupTable() is called, checkLookupTable()
  1052. // would add the host in the lookupTable and
  1053. // return null. So we will do the lookup.
  1054. // 2) If the host is in the lookupTable when
  1055. // checkLookupTable() is called, the current thread
  1056. // would be blocked until the host is removed
  1057. // from the lookupTable. Then this thread
  1058. // should try to look up the addressCache.
  1059. // i) if it found the address in the
  1060. // addressCache, checkLookupTable() would
  1061. // return the address.
  1062. // ii) if it didn't find the address in the
  1063. // addressCache for any reason,
  1064. // it should add the host in the
  1065. // lookupTable and return null so the
  1066. // following code would do a lookup itself.
  1067. if ((obj = checkLookupTable(host)) == null) {
  1068. // This is the first thread which looks up the address
  1069. // this host or the cache entry for this host has been
  1070. // expired so this thread should do the lookup.
  1071. try {
  1072. /*
  1073. * Do not put the call to lookup() inside the
  1074. * constructor. if you do you will still be
  1075. * allocating space when the lookup fails.
  1076. */
  1077. byte[][] byte_array;
  1078. byte_array = nameService.lookupAllHostAddr(host);
  1079. InetAddress[] addr_array =
  1080. new InetAddress[byte_array.length];
  1081. for (int i = 0; i < byte_array.length; i++) {
  1082. byte addr[] = byte_array[i];
  1083. if (addr.length == Inet4Address.INADDRSZ) {
  1084. addr_array[i] = new Inet4Address(host, addr);
  1085. } else {
  1086. addr_array[i] = new Inet6Address(host, addr, -1);
  1087. }
  1088. }
  1089. obj = addr_array;
  1090. success = true;
  1091. } catch (UnknownHostException uhe) {
  1092. obj = unknown_array;
  1093. success = false;
  1094. throw uhe;
  1095. } finally {
  1096. // Cache the address.
  1097. cacheAddress(host, obj, success);
  1098. // Delete the host from the lookupTable, and
  1099. // notify all threads waiting for the monitor
  1100. // for lookupTable.
  1101. updateLookupTable(host);
  1102. }
  1103. }
  1104. return obj;
  1105. }
  1106. private static Object checkLookupTable(String host) {
  1107. // make sure obj is null.
  1108. Object obj = null;
  1109. synchronized (lookupTable) {
  1110. // If the host isn't in the lookupTable, add it in the
  1111. // lookuptable and return null. The caller should do
  1112. // the lookup.
  1113. if (lookupTable.containsKey(host) == false) {
  1114. lookupTable.put(host, null);
  1115. return obj;
  1116. }
  1117. // If the host is in the lookupTable, it means that another
  1118. // thread is trying to look up the address of this host.
  1119. // This thread should wait.
  1120. while (lookupTable.containsKey(host)) {
  1121. try {
  1122. lookupTable.wait();
  1123. } catch (InterruptedException e) {
  1124. }
  1125. }
  1126. }
  1127. // The other thread has finished looking up the address of
  1128. // the host. This thread should retry to get the address
  1129. // from the addressCache. If it doesn't get the address from
  1130. // the cache, it will try to look up the address itself.
  1131. obj = getCachedAddress(host);
  1132. if (obj == null) {
  1133. synchronized (lookupTable) {
  1134. lookupTable.put(host, null);
  1135. }
  1136. }
  1137. return obj;
  1138. }
  1139. private static void updateLookupTable(String host) {
  1140. synchronized (lookupTable) {
  1141. lookupTable.remove(host);
  1142. lookupTable.notifyAll();
  1143. }
  1144. }
  1145. /**
  1146. * Returns an <code>InetAddress</code> object given the raw IP address .
  1147. * The argument is in network byte order: the highest order
  1148. * byte of the address is in <code>getAddress()[0]</code>.
  1149. *
  1150. * <p> This method doesn't block, i.e. no reverse name service lookup
  1151. * is performed.
  1152. *
  1153. * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
  1154. * must be 16 bytes long
  1155. *
  1156. * @param addr the raw IP address in network byte order
  1157. * @return an InetAddress object created from the raw IP address.
  1158. * @exception UnknownHostException if IP address is of illegal length
  1159. * @since 1.4
  1160. */
  1161. public static InetAddress getByAddress(byte[] addr)
  1162. throws UnknownHostException {
  1163. return getByAddress(null, addr);
  1164. }
  1165. /**
  1166. * Returns the local host.
  1167. *
  1168. * <p>If there is a security manager, its
  1169. * <code>checkConnect</code> method is called
  1170. * with the local host name and <code>-1</code>
  1171. * as its arguments to see if the operation is allowed.
  1172. * If the operation is not allowed, an InetAddress representing
  1173. * the loopback address is returned.
  1174. *
  1175. * @return the IP address of the local host.
  1176. *
  1177. * @exception UnknownHostException if no IP address for the
  1178. * <code>host</code> could be found.
  1179. *
  1180. * @see SecurityManager#checkConnect
  1181. */
  1182. public static InetAddress getLocalHost() throws UnknownHostException {
  1183. SecurityManager security = System.getSecurityManager();
  1184. try {
  1185. String local = impl.getLocalHostName();
  1186. if (security != null) {
  1187. security.checkConnect(local, -1);
  1188. }
  1189. // we are calling getAddressFromNameService directly
  1190. // to avoid getting localHost from cache
  1191. InetAddress[] localAddrs;
  1192. try {
  1193. localAddrs =
  1194. (InetAddress[]) InetAddress.getAddressFromNameService(local);
  1195. } catch (UnknownHostException uhe) {
  1196. throw new UnknownHostException(local + ": " + uhe.getMessage());
  1197. }
  1198. return localAddrs[0];
  1199. } catch (java.lang.SecurityException e) {
  1200. return impl.loopbackAddress();
  1201. }
  1202. }
  1203. /**
  1204. * Perform class load-time initializations.
  1205. */
  1206. private static native void init();
  1207. /*
  1208. * Returns the InetAddress representing anyLocalAddress
  1209. * (typically 0.0.0.0 or ::0)
  1210. */
  1211. static InetAddress anyLocalAddress() {
  1212. return impl.anyLocalAddress();
  1213. }
  1214. /*
  1215. * Load and instantiate an underlying impl class
  1216. */
  1217. static Object loadImpl(String implName) {
  1218. Object impl;
  1219. /*
  1220. * Property "impl.prefix" will be prepended to the classname
  1221. * of the implementation object we instantiate, to which we
  1222. * delegate the real work (like native methods). This
  1223. * property can vary across implementations of the java.
  1224. * classes. The default is an empty String "".
  1225. */
  1226. String prefix = (String)AccessController.doPrivileged(
  1227. new GetPropertyAction("impl.prefix", ""));
  1228. impl = null;
  1229. try {
  1230. impl = Class.forName("java.net." + prefix + implName).newInstance();
  1231. } catch (ClassNotFoundException e) {
  1232. System.err.println("Class not found: java.net." + prefix +
  1233. implName + ":\ncheck impl.prefix property " +
  1234. "in your properties file.");
  1235. } catch (InstantiationException e) {
  1236. System.err.println("Could not instantiate: java.net." + prefix +
  1237. implName + ":\ncheck impl.prefix property " +
  1238. "in your properties file.");
  1239. } catch (IllegalAccessException e) {
  1240. System.err.println("Cannot access class: java.net." + prefix +
  1241. implName + ":\ncheck impl.prefix property " +
  1242. "in your properties file.");
  1243. }
  1244. if (impl == null) {
  1245. try {
  1246. impl = Class.forName(implName).newInstance();
  1247. } catch (Exception e) {
  1248. throw new Error("System property impl.prefix incorrect");
  1249. }
  1250. }
  1251. return impl;
  1252. }
  1253. }
  1254. /*
  1255. * Simple factory to create the impl
  1256. */
  1257. class InetAddressImplFactory {
  1258. static InetAddressImpl create() {
  1259. Object o;
  1260. if (isIPv6Supported()) {
  1261. o = InetAddress.loadImpl("Inet6AddressImpl");
  1262. } else {
  1263. o = InetAddress.loadImpl("Inet4AddressImpl");
  1264. }
  1265. return (InetAddressImpl)o;
  1266. }
  1267. static native boolean isIPv6Supported();
  1268. }