PageRenderTime 48ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/jre-1.6.0/src/java/net/InetAddress.java

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