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