Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/net/InetAddress.java
41152 views
1
/*
2
* Copyright (c) 1995, 2021, Oracle and/or its affiliates. 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.net;
27
28
import java.util.List;
29
import java.util.NavigableSet;
30
import java.util.ArrayList;
31
import java.util.Objects;
32
import java.util.Scanner;
33
import java.io.File;
34
import java.io.ObjectStreamException;
35
import java.io.ObjectStreamField;
36
import java.io.IOException;
37
import java.io.InvalidObjectException;
38
import java.io.ObjectInputStream;
39
import java.io.ObjectInputStream.GetField;
40
import java.io.ObjectOutputStream;
41
import java.io.ObjectOutputStream.PutField;
42
import java.lang.annotation.Native;
43
import java.util.concurrent.ConcurrentHashMap;
44
import java.util.concurrent.ConcurrentMap;
45
import java.util.concurrent.ConcurrentSkipListSet;
46
import java.util.concurrent.atomic.AtomicLong;
47
import java.util.Arrays;
48
49
import jdk.internal.access.JavaNetInetAddressAccess;
50
import jdk.internal.access.SharedSecrets;
51
import sun.security.action.*;
52
import sun.net.InetAddressCachePolicy;
53
import sun.net.util.IPAddressUtil;
54
import sun.nio.cs.UTF_8;
55
56
/**
57
* This class represents an Internet Protocol (IP) address.
58
*
59
* <p> An IP address is either a 32-bit or 128-bit unsigned number
60
* used by IP, a lower-level protocol on which protocols like UDP and
61
* TCP are built. The IP address architecture is defined by <a
62
* href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC&nbsp;790:
63
* Assigned Numbers</i></a>, <a
64
* href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC&nbsp;1918:
65
* Address Allocation for Private Internets</i></a>, <a
66
* href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC&nbsp;2365:
67
* Administratively Scoped IP Multicast</i></a>, and <a
68
* href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IP
69
* Version 6 Addressing Architecture</i></a>. An instance of an
70
* InetAddress consists of an IP address and possibly its
71
* corresponding host name (depending on whether it is constructed
72
* with a host name or whether it has already done reverse host name
73
* resolution).
74
*
75
* <h2> Address types </h2>
76
*
77
* <table class="striped" style="margin-left:2em">
78
* <caption style="display:none">Description of unicast and multicast address types</caption>
79
* <thead>
80
* <tr><th scope="col">Address Type</th><th scope="col">Description</th></tr>
81
* </thead>
82
* <tbody>
83
* <tr><th scope="row" style="vertical-align:top">unicast</th>
84
* <td>An identifier for a single interface. A packet sent to
85
* a unicast address is delivered to the interface identified by
86
* that address.
87
*
88
* <p> The Unspecified Address -- Also called anylocal or wildcard
89
* address. It must never be assigned to any node. It indicates the
90
* absence of an address. One example of its use is as the target of
91
* bind, which allows a server to accept a client connection on any
92
* interface, in case the server host has multiple interfaces.
93
*
94
* <p> The <i>unspecified</i> address must not be used as
95
* the destination address of an IP packet.
96
*
97
* <p> The <i>Loopback</i> Addresses -- This is the address
98
* assigned to the loopback interface. Anything sent to this
99
* IP address loops around and becomes IP input on the local
100
* host. This address is often used when testing a
101
* client.</td></tr>
102
* <tr><th scope="row" style="vertical-align:top">multicast</th>
103
* <td>An identifier for a set of interfaces (typically belonging
104
* to different nodes). A packet sent to a multicast address is
105
* delivered to all interfaces identified by that address.</td></tr>
106
* </tbody>
107
* </table>
108
*
109
* <h3> IP address scope </h3>
110
*
111
* <p> <i>Link-local</i> addresses are designed to be used for addressing
112
* on a single link for purposes such as auto-address configuration,
113
* neighbor discovery, or when no routers are present.
114
*
115
* <p> <i>Site-local</i> addresses are designed to be used for addressing
116
* inside of a site without the need for a global prefix.
117
*
118
* <p> <i>Global</i> addresses are unique across the internet.
119
*
120
* <h3> Textual representation of IP addresses </h3>
121
*
122
* The textual representation of an IP address is address family specific.
123
*
124
* <p>
125
*
126
* For IPv4 address format, please refer to <A
127
* HREF="Inet4Address.html#format">Inet4Address#format</A>; For IPv6
128
* address format, please refer to <A
129
* HREF="Inet6Address.html#format">Inet6Address#format</A>.
130
*
131
* <P>There is a <a href="doc-files/net-properties.html#Ipv4IPv6">couple of
132
* System Properties</a> affecting how IPv4 and IPv6 addresses are used.</P>
133
*
134
* <h3> Host Name Resolution </h3>
135
*
136
* Host name-to-IP address <i>resolution</i> is accomplished through
137
* the use of a combination of local machine configuration information
138
* and network naming services such as the Domain Name System (DNS)
139
* and Network Information Service(NIS). The particular naming
140
* services(s) being used is by default the local machine configured
141
* one. For any host name, its corresponding IP address is returned.
142
*
143
* <p> <i>Reverse name resolution</i> means that for any IP address,
144
* the host associated with the IP address is returned.
145
*
146
* <p> The InetAddress class provides methods to resolve host names to
147
* their IP addresses and vice versa.
148
*
149
* <h3> InetAddress Caching </h3>
150
*
151
* The InetAddress class has a cache to store successful as well as
152
* unsuccessful host name resolutions.
153
*
154
* <p> By default, when a security manager is installed, in order to
155
* protect against DNS spoofing attacks,
156
* the result of positive host name resolutions are
157
* cached forever. When a security manager is not installed, the default
158
* behavior is to cache entries for a finite (implementation dependent)
159
* period of time. The result of unsuccessful host
160
* name resolution is cached for a very short period of time (10
161
* seconds) to improve performance.
162
*
163
* <p> If the default behavior is not desired, then a Java security property
164
* can be set to a different Time-to-live (TTL) value for positive
165
* caching. Likewise, a system admin can configure a different
166
* negative caching TTL value when needed.
167
*
168
* <p> Two Java security properties control the TTL values used for
169
* positive and negative host name resolution caching:
170
*
171
* <dl style="margin-left:2em">
172
* <dt><b>networkaddress.cache.ttl</b></dt>
173
* <dd>Indicates the caching policy for successful name lookups from
174
* the name service. The value is specified as an integer to indicate
175
* the number of seconds to cache the successful lookup. The default
176
* setting is to cache for an implementation specific period of time.
177
* <p>
178
* A value of -1 indicates "cache forever".
179
* </dd>
180
* <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>
181
* <dd>Indicates the caching policy for un-successful name lookups
182
* from the name service. The value is specified as an integer to
183
* indicate the number of seconds to cache the failure for
184
* un-successful lookups.
185
* <p>
186
* A value of 0 indicates "never cache".
187
* A value of -1 indicates "cache forever".
188
* </dd>
189
* </dl>
190
*
191
* @author Chris Warth
192
* @see java.net.InetAddress#getByAddress(byte[])
193
* @see java.net.InetAddress#getByAddress(java.lang.String, byte[])
194
* @see java.net.InetAddress#getAllByName(java.lang.String)
195
* @see java.net.InetAddress#getByName(java.lang.String)
196
* @see java.net.InetAddress#getLocalHost()
197
* @since 1.0
198
*/
199
public class InetAddress implements java.io.Serializable {
200
201
@Native static final int PREFER_IPV4_VALUE = 0;
202
@Native static final int PREFER_IPV6_VALUE = 1;
203
@Native static final int PREFER_SYSTEM_VALUE = 2;
204
205
/**
206
* Specify the address family: Internet Protocol, Version 4
207
* @since 1.4
208
*/
209
@Native static final int IPv4 = 1;
210
211
/**
212
* Specify the address family: Internet Protocol, Version 6
213
* @since 1.4
214
*/
215
@Native static final int IPv6 = 2;
216
217
/* Specify address family preference */
218
static transient final int preferIPv6Address;
219
220
static class InetAddressHolder {
221
/**
222
* Reserve the original application specified hostname.
223
*
224
* The original hostname is useful for domain-based endpoint
225
* identification (see RFC 2818 and RFC 6125). If an address
226
* was created with a raw IP address, a reverse name lookup
227
* may introduce endpoint identification security issue via
228
* DNS forging.
229
*
230
* Oracle JSSE provider is using this original hostname, via
231
* jdk.internal.misc.JavaNetAccess, for SSL/TLS endpoint identification.
232
*
233
* Note: May define a new public method in the future if necessary.
234
*/
235
String originalHostName;
236
237
InetAddressHolder() {}
238
239
InetAddressHolder(String hostName, int address, int family) {
240
this.originalHostName = hostName;
241
this.hostName = hostName;
242
this.address = address;
243
this.family = family;
244
}
245
246
void init(String hostName, int family) {
247
this.originalHostName = hostName;
248
this.hostName = hostName;
249
if (family != -1) {
250
this.family = family;
251
}
252
}
253
254
String hostName;
255
256
String getHostName() {
257
return hostName;
258
}
259
260
String getOriginalHostName() {
261
return originalHostName;
262
}
263
264
/**
265
* Holds a 32-bit IPv4 address.
266
*/
267
int address;
268
269
int getAddress() {
270
return address;
271
}
272
273
/**
274
* Specifies the address family type, for instance, '1' for IPv4
275
* addresses, and '2' for IPv6 addresses.
276
*/
277
int family;
278
279
int getFamily() {
280
return family;
281
}
282
}
283
284
/* Used to store the serializable fields of InetAddress */
285
final transient InetAddressHolder holder;
286
287
InetAddressHolder holder() {
288
return holder;
289
}
290
291
/* Used to store the name service provider */
292
private static transient NameService nameService;
293
294
/**
295
* Used to store the best available hostname.
296
* Lazily initialized via a data race; safe because Strings are immutable.
297
*/
298
private transient String canonicalHostName = null;
299
300
/** use serialVersionUID from JDK 1.0.2 for interoperability */
301
@java.io.Serial
302
private static final long serialVersionUID = 3286316764910316507L;
303
304
/*
305
* Load net library into runtime, and perform initializations.
306
*/
307
static {
308
String str = GetPropertyAction.privilegedGetProperty("java.net.preferIPv6Addresses");
309
if (str == null) {
310
preferIPv6Address = PREFER_IPV4_VALUE;
311
} else if (str.equalsIgnoreCase("true")) {
312
preferIPv6Address = PREFER_IPV6_VALUE;
313
} else if (str.equalsIgnoreCase("false")) {
314
preferIPv6Address = PREFER_IPV4_VALUE;
315
} else if (str.equalsIgnoreCase("system")) {
316
preferIPv6Address = PREFER_SYSTEM_VALUE;
317
} else {
318
preferIPv6Address = PREFER_IPV4_VALUE;
319
}
320
jdk.internal.loader.BootLoader.loadLibrary("net");
321
SharedSecrets.setJavaNetInetAddressAccess(
322
new JavaNetInetAddressAccess() {
323
public String getOriginalHostName(InetAddress ia) {
324
return ia.holder.getOriginalHostName();
325
}
326
327
public InetAddress getByName(String hostName,
328
InetAddress hostAddress)
329
throws UnknownHostException
330
{
331
return InetAddress.getByName(hostName, hostAddress);
332
}
333
334
public int addressValue(Inet4Address inet4Address) {
335
return inet4Address.addressValue();
336
}
337
338
public byte[] addressBytes(Inet6Address inet6Address) {
339
return inet6Address.addressBytes();
340
}
341
}
342
);
343
init();
344
}
345
346
/**
347
* Constructor for the Socket.accept() method.
348
* This creates an empty InetAddress, which is filled in by
349
* the accept() method. This InetAddress, however, is not
350
* put in the address cache, since it is not created by name.
351
*/
352
InetAddress() {
353
holder = new InetAddressHolder();
354
}
355
356
/**
357
* Replaces the de-serialized object with an Inet4Address object.
358
*
359
* @return the alternate object to the de-serialized object.
360
*
361
* @throws ObjectStreamException if a new object replacing this
362
* object could not be created
363
*/
364
@java.io.Serial
365
private Object readResolve() throws ObjectStreamException {
366
// will replace the deserialized 'this' object
367
return new Inet4Address(holder().getHostName(), holder().getAddress());
368
}
369
370
/**
371
* Utility routine to check if the InetAddress is an
372
* IP multicast address.
373
* @return a {@code boolean} indicating if the InetAddress is
374
* an IP multicast address
375
* @since 1.1
376
*/
377
public boolean isMulticastAddress() {
378
return false;
379
}
380
381
/**
382
* Utility routine to check if the InetAddress is a wildcard address.
383
* @return a {@code boolean} indicating if the InetAddress is
384
* a wildcard address.
385
* @since 1.4
386
*/
387
public boolean isAnyLocalAddress() {
388
return false;
389
}
390
391
/**
392
* Utility routine to check if the InetAddress is a loopback address.
393
*
394
* @return a {@code boolean} indicating if the InetAddress is
395
* a loopback address; or false otherwise.
396
* @since 1.4
397
*/
398
public boolean isLoopbackAddress() {
399
return false;
400
}
401
402
/**
403
* Utility routine to check if the InetAddress is an link local address.
404
*
405
* @return a {@code boolean} indicating if the InetAddress is
406
* a link local address; or false if address is not a link local unicast address.
407
* @since 1.4
408
*/
409
public boolean isLinkLocalAddress() {
410
return false;
411
}
412
413
/**
414
* Utility routine to check if the InetAddress is a site local address.
415
*
416
* @return a {@code boolean} indicating if the InetAddress is
417
* a site local address; or false if address is not a site local unicast address.
418
* @since 1.4
419
*/
420
public boolean isSiteLocalAddress() {
421
return false;
422
}
423
424
/**
425
* Utility routine to check if the multicast address has global scope.
426
*
427
* @return a {@code boolean} indicating if the address has
428
* is a multicast address of global scope, false if it is not
429
* of global scope or it is not a multicast address
430
* @since 1.4
431
*/
432
public boolean isMCGlobal() {
433
return false;
434
}
435
436
/**
437
* Utility routine to check if the multicast address has node scope.
438
*
439
* @return a {@code boolean} indicating if the address has
440
* is a multicast address of node-local scope, false if it is not
441
* of node-local scope or it is not a multicast address
442
* @since 1.4
443
*/
444
public boolean isMCNodeLocal() {
445
return false;
446
}
447
448
/**
449
* Utility routine to check if the multicast address has link scope.
450
*
451
* @return a {@code boolean} indicating if the address has
452
* is a multicast address of link-local scope, false if it is not
453
* of link-local scope or it is not a multicast address
454
* @since 1.4
455
*/
456
public boolean isMCLinkLocal() {
457
return false;
458
}
459
460
/**
461
* Utility routine to check if the multicast address has site scope.
462
*
463
* @return a {@code boolean} indicating if the address has
464
* is a multicast address of site-local scope, false if it is not
465
* of site-local scope or it is not a multicast address
466
* @since 1.4
467
*/
468
public boolean isMCSiteLocal() {
469
return false;
470
}
471
472
/**
473
* Utility routine to check if the multicast address has organization scope.
474
*
475
* @return a {@code boolean} indicating if the address has
476
* is a multicast address of organization-local scope,
477
* false if it is not of organization-local scope
478
* or it is not a multicast address
479
* @since 1.4
480
*/
481
public boolean isMCOrgLocal() {
482
return false;
483
}
484
485
486
/**
487
* Test whether that address is reachable. Best effort is made by the
488
* implementation to try to reach the host, but firewalls and server
489
* configuration may block requests resulting in a unreachable status
490
* while some specific ports may be accessible.
491
* A typical implementation will use ICMP ECHO REQUESTs if the
492
* privilege can be obtained, otherwise it will try to establish
493
* a TCP connection on port 7 (Echo) of the destination host.
494
* <p>
495
* The timeout value, in milliseconds, indicates the maximum amount of time
496
* the try should take. If the operation times out before getting an
497
* answer, the host is deemed unreachable. A negative value will result
498
* in an IllegalArgumentException being thrown.
499
*
500
* @param timeout the time, in milliseconds, before the call aborts
501
* @return a {@code boolean} indicating if the address is reachable.
502
* @throws IOException if a network error occurs
503
* @throws IllegalArgumentException if {@code timeout} is negative.
504
* @since 1.5
505
*/
506
public boolean isReachable(int timeout) throws IOException {
507
return isReachable(null, 0 , timeout);
508
}
509
510
/**
511
* Test whether that address is reachable. Best effort is made by the
512
* implementation to try to reach the host, but firewalls and server
513
* configuration may block requests resulting in a unreachable status
514
* while some specific ports may be accessible.
515
* A typical implementation will use ICMP ECHO REQUESTs if the
516
* privilege can be obtained, otherwise it will try to establish
517
* a TCP connection on port 7 (Echo) of the destination host.
518
* <p>
519
* The {@code network interface} and {@code ttl} parameters
520
* let the caller specify which network interface the test will go through
521
* and the maximum number of hops the packets should go through.
522
* A negative value for the {@code ttl} will result in an
523
* IllegalArgumentException being thrown.
524
* <p>
525
* The timeout value, in milliseconds, indicates the maximum amount of time
526
* the try should take. If the operation times out before getting an
527
* answer, the host is deemed unreachable. A negative value will result
528
* in an IllegalArgumentException being thrown.
529
*
530
* @param netif the NetworkInterface through which the
531
* test will be done, or null for any interface
532
* @param ttl the maximum numbers of hops to try or 0 for the
533
* default
534
* @param timeout the time, in milliseconds, before the call aborts
535
* @throws IllegalArgumentException if either {@code timeout}
536
* or {@code ttl} are negative.
537
* @return a {@code boolean} indicating if the address is reachable.
538
* @throws IOException if a network error occurs
539
* @since 1.5
540
*/
541
public boolean isReachable(NetworkInterface netif, int ttl,
542
int timeout) throws IOException {
543
if (ttl < 0)
544
throw new IllegalArgumentException("ttl can't be negative");
545
if (timeout < 0)
546
throw new IllegalArgumentException("timeout can't be negative");
547
548
return impl.isReachable(this, timeout, netif, ttl);
549
}
550
551
/**
552
* Gets the host name for this IP address.
553
*
554
* <p>If this InetAddress was created with a host name,
555
* this host name will be remembered and returned;
556
* otherwise, a reverse name lookup will be performed
557
* and the result will be returned based on the system
558
* configured name lookup service. If a lookup of the name service
559
* is required, call
560
* {@link #getCanonicalHostName() getCanonicalHostName}.
561
*
562
* <p>If there is a security manager, its
563
* {@code checkConnect} method is first called
564
* with the hostname and {@code -1}
565
* as its arguments to see if the operation is allowed.
566
* If the operation is not allowed, it will return
567
* the textual representation of the IP address.
568
*
569
* @return the host name for this IP address, or if the operation
570
* is not allowed by the security check, the textual
571
* representation of the IP address.
572
*
573
* @see InetAddress#getCanonicalHostName
574
* @see SecurityManager#checkConnect
575
*/
576
public String getHostName() {
577
return getHostName(true);
578
}
579
580
/**
581
* Returns the hostname for this address.
582
* If the host is equal to null, then this address refers to any
583
* of the local machine's available network addresses.
584
* this is package private so SocketPermission can make calls into
585
* here without a security check.
586
*
587
* <p>If there is a security manager, this method first
588
* calls its {@code checkConnect} method
589
* with the hostname and {@code -1}
590
* as its arguments to see if the calling code is allowed to know
591
* the hostname for this IP address, i.e., to connect to the host.
592
* If the operation is not allowed, it will return
593
* the textual representation of the IP address.
594
*
595
* @return the host name for this IP address, or if the operation
596
* is not allowed by the security check, the textual
597
* representation of the IP address.
598
*
599
* @param check make security check if true
600
*
601
* @see SecurityManager#checkConnect
602
*/
603
String getHostName(boolean check) {
604
if (holder().getHostName() == null) {
605
holder().hostName = InetAddress.getHostFromNameService(this, check);
606
}
607
return holder().getHostName();
608
}
609
610
/**
611
* Gets the fully qualified domain name for this IP address.
612
* Best effort method, meaning we may not be able to return
613
* the FQDN depending on the underlying system configuration.
614
*
615
* <p>If there is a security manager, this method first
616
* calls its {@code checkConnect} method
617
* with the hostname and {@code -1}
618
* as its arguments to see if the calling code is allowed to know
619
* the hostname for this IP address, i.e., to connect to the host.
620
* If the operation is not allowed, it will return
621
* the textual representation of the IP address.
622
*
623
* @return the fully qualified domain name for this IP address,
624
* or if the operation is not allowed by the security check,
625
* the textual representation of the IP address.
626
*
627
* @see SecurityManager#checkConnect
628
*
629
* @since 1.4
630
*/
631
public String getCanonicalHostName() {
632
String value = canonicalHostName;
633
if (value == null)
634
canonicalHostName = value =
635
InetAddress.getHostFromNameService(this, true);
636
return value;
637
}
638
639
/**
640
* Returns the hostname for this address.
641
*
642
* <p>If there is a security manager, this method first
643
* calls its {@code checkConnect} method
644
* with the hostname and {@code -1}
645
* as its arguments to see if the calling code is allowed to know
646
* the hostname for this IP address, i.e., to connect to the host.
647
* If the operation is not allowed, it will return
648
* the textual representation of the IP address.
649
*
650
* @return the host name for this IP address, or if the operation
651
* is not allowed by the security check, the textual
652
* representation of the IP address.
653
*
654
* @param check make security check if true
655
*
656
* @see SecurityManager#checkConnect
657
*/
658
private static String getHostFromNameService(InetAddress addr, boolean check) {
659
String host = null;
660
try {
661
// first lookup the hostname
662
host = nameService.getHostByAddr(addr.getAddress());
663
664
/* check to see if calling code is allowed to know
665
* the hostname for this IP address, ie, connect to the host
666
*/
667
if (check) {
668
@SuppressWarnings("removal")
669
SecurityManager sec = System.getSecurityManager();
670
if (sec != null) {
671
sec.checkConnect(host, -1);
672
}
673
}
674
675
/* now get all the IP addresses for this hostname,
676
* and make sure one of them matches the original IP
677
* address. We do this to try and prevent spoofing.
678
*/
679
680
InetAddress[] arr = InetAddress.getAllByName0(host, check);
681
boolean ok = false;
682
683
if(arr != null) {
684
for(int i = 0; !ok && i < arr.length; i++) {
685
ok = addr.equals(arr[i]);
686
}
687
}
688
689
//XXX: if it looks a spoof just return the address?
690
if (!ok) {
691
host = addr.getHostAddress();
692
return host;
693
}
694
} catch (SecurityException e) {
695
host = addr.getHostAddress();
696
} catch (UnknownHostException e) {
697
host = addr.getHostAddress();
698
// let next provider resolve the hostname
699
}
700
return host;
701
}
702
703
/**
704
* Returns the raw IP address of this {@code InetAddress}
705
* object. The result is in network byte order: the highest order
706
* byte of the address is in {@code getAddress()[0]}.
707
*
708
* @return the raw IP address of this object.
709
*/
710
public byte[] getAddress() {
711
return null;
712
}
713
714
/**
715
* Returns the IP address string in textual presentation.
716
*
717
* @return the raw IP address in a string format.
718
* @since 1.0.2
719
*/
720
public String getHostAddress() {
721
return null;
722
}
723
724
/**
725
* Returns a hashcode for this IP address.
726
*
727
* @return a hash code value for this IP address.
728
*/
729
public int hashCode() {
730
return -1;
731
}
732
733
/**
734
* Compares this object against the specified object.
735
* The result is {@code true} if and only if the argument is
736
* not {@code null} and it represents the same IP address as
737
* this object.
738
* <p>
739
* Two instances of {@code InetAddress} represent the same IP
740
* address if the length of the byte arrays returned by
741
* {@code getAddress} is the same for both, and each of the
742
* array components is the same for the byte arrays.
743
*
744
* @param obj the object to compare against.
745
* @return {@code true} if the objects are the same;
746
* {@code false} otherwise.
747
* @see java.net.InetAddress#getAddress()
748
*/
749
public boolean equals(Object obj) {
750
return false;
751
}
752
753
/**
754
* Converts this IP address to a {@code String}. The
755
* string returned is of the form: hostname / literal IP
756
* address.
757
*
758
* If the host name is unresolved, no reverse name service lookup
759
* is performed. The hostname part will be represented by an empty string.
760
*
761
* @return a string representation of this IP address.
762
*/
763
public String toString() {
764
String hostName = holder().getHostName();
765
return Objects.toString(hostName, "")
766
+ "/" + getHostAddress();
767
}
768
769
// mapping from host name to Addresses - either NameServiceAddresses (while
770
// still being looked-up by NameService(s)) or CachedAddresses when cached
771
private static final ConcurrentMap<String, Addresses> cache =
772
new ConcurrentHashMap<>();
773
774
// CachedAddresses that have to expire are kept ordered in this NavigableSet
775
// which is scanned on each access
776
private static final NavigableSet<CachedAddresses> expirySet =
777
new ConcurrentSkipListSet<>();
778
779
// common interface
780
private interface Addresses {
781
InetAddress[] get() throws UnknownHostException;
782
}
783
784
// a holder for cached addresses with required metadata
785
private static final class CachedAddresses implements Addresses, Comparable<CachedAddresses> {
786
private static final AtomicLong seq = new AtomicLong();
787
final String host;
788
final InetAddress[] inetAddresses;
789
final long expiryTime; // time of expiry (in terms of System.nanoTime())
790
final long id = seq.incrementAndGet(); // each instance is unique
791
792
CachedAddresses(String host, InetAddress[] inetAddresses, long expiryTime) {
793
this.host = host;
794
this.inetAddresses = inetAddresses;
795
this.expiryTime = expiryTime;
796
}
797
798
@Override
799
public InetAddress[] get() throws UnknownHostException {
800
if (inetAddresses == null) {
801
throw new UnknownHostException(host);
802
}
803
return inetAddresses;
804
}
805
806
@Override
807
public int compareTo(CachedAddresses other) {
808
// natural order is expiry time -
809
// compare difference of expiry times rather than
810
// expiry times directly, to avoid possible overflow.
811
// (see System.nanoTime() recommendations...)
812
long diff = this.expiryTime - other.expiryTime;
813
if (diff < 0L) return -1;
814
if (diff > 0L) return 1;
815
// ties are broken using unique id
816
return Long.compare(this.id, other.id);
817
}
818
}
819
820
// a name service lookup based Addresses implementation which replaces itself
821
// in cache when the result is obtained
822
private static final class NameServiceAddresses implements Addresses {
823
private final String host;
824
private final InetAddress reqAddr;
825
826
NameServiceAddresses(String host, InetAddress reqAddr) {
827
this.host = host;
828
this.reqAddr = reqAddr;
829
}
830
831
@Override
832
public InetAddress[] get() throws UnknownHostException {
833
Addresses addresses;
834
// only one thread is doing lookup to name service
835
// for particular host at any time.
836
synchronized (this) {
837
// re-check that we are still us + re-install us if slot empty
838
addresses = cache.putIfAbsent(host, this);
839
if (addresses == null) {
840
// this can happen when we were replaced by CachedAddresses in
841
// some other thread, then CachedAddresses expired and were
842
// removed from cache while we were waiting for lock...
843
addresses = this;
844
}
845
// still us ?
846
if (addresses == this) {
847
// lookup name services
848
InetAddress[] inetAddresses;
849
UnknownHostException ex;
850
int cachePolicy;
851
try {
852
inetAddresses = getAddressesFromNameService(host, reqAddr);
853
ex = null;
854
cachePolicy = InetAddressCachePolicy.get();
855
} catch (UnknownHostException uhe) {
856
inetAddresses = null;
857
ex = uhe;
858
cachePolicy = InetAddressCachePolicy.getNegative();
859
}
860
// remove or replace us with cached addresses according to cachePolicy
861
if (cachePolicy == InetAddressCachePolicy.NEVER) {
862
cache.remove(host, this);
863
} else {
864
CachedAddresses cachedAddresses = new CachedAddresses(
865
host,
866
inetAddresses,
867
cachePolicy == InetAddressCachePolicy.FOREVER
868
? 0L
869
// cachePolicy is in [s] - we need [ns]
870
: System.nanoTime() + 1000_000_000L * cachePolicy
871
);
872
if (cache.replace(host, this, cachedAddresses) &&
873
cachePolicy != InetAddressCachePolicy.FOREVER) {
874
// schedule expiry
875
expirySet.add(cachedAddresses);
876
}
877
}
878
if (inetAddresses == null) {
879
throw ex == null ? new UnknownHostException(host) : ex;
880
}
881
return inetAddresses;
882
}
883
// else addresses != this
884
}
885
// delegate to different addresses when we are already replaced
886
// but outside of synchronized block to avoid any chance of dead-locking
887
return addresses.get();
888
}
889
}
890
891
/**
892
* NameService provides host and address lookup service
893
*
894
* @since 9
895
*/
896
private interface NameService {
897
898
/**
899
* Lookup a host mapping by name. Retrieve the IP addresses
900
* associated with a host
901
*
902
* @param host the specified hostname
903
* @return array of IP addresses for the requested host
904
* @throws UnknownHostException
905
* if no IP address for the {@code host} could be found
906
*/
907
InetAddress[] lookupAllHostAddr(String host)
908
throws UnknownHostException;
909
910
/**
911
* Lookup the host corresponding to the IP address provided
912
*
913
* @param addr byte array representing an IP address
914
* @return {@code String} representing the host name mapping
915
* @throws UnknownHostException
916
* if no host found for the specified IP address
917
*/
918
String getHostByAddr(byte[] addr) throws UnknownHostException;
919
920
}
921
922
/**
923
* The default NameService implementation, which delegates to the underlying
924
* OS network libraries to resolve host address mappings.
925
*
926
* @since 9
927
*/
928
private static final class PlatformNameService implements NameService {
929
930
public InetAddress[] lookupAllHostAddr(String host)
931
throws UnknownHostException
932
{
933
return impl.lookupAllHostAddr(host);
934
}
935
936
public String getHostByAddr(byte[] addr)
937
throws UnknownHostException
938
{
939
return impl.getHostByAddr(addr);
940
}
941
}
942
943
/**
944
* The HostsFileNameService provides host address mapping
945
* by reading the entries in a hosts file, which is specified by
946
* {@code jdk.net.hosts.file} system property
947
*
948
* <p>The file format is that which corresponds with the /etc/hosts file
949
* IP Address host alias list.
950
*
951
* <p>When the file lookup is enabled it replaces the default NameService
952
* implementation
953
*
954
* @since 9
955
*/
956
private static final class HostsFileNameService implements NameService {
957
958
private static final InetAddress[] EMPTY_ARRAY = new InetAddress[0];
959
960
// Specify if only IPv4 addresses should be returned by HostsFileService implementation
961
private static final boolean preferIPv4Stack = Boolean.parseBoolean(
962
GetPropertyAction.privilegedGetProperty("java.net.preferIPv4Stack"));
963
964
private final String hostsFile;
965
966
public HostsFileNameService(String hostsFileName) {
967
this.hostsFile = hostsFileName;
968
}
969
970
/**
971
* Lookup the host name corresponding to the IP address provided.
972
* Search the configured host file a host name corresponding to
973
* the specified IP address.
974
*
975
* @param addr byte array representing an IP address
976
* @return {@code String} representing the host name mapping
977
* @throws UnknownHostException
978
* if no host found for the specified IP address
979
*/
980
@Override
981
public String getHostByAddr(byte[] addr) throws UnknownHostException {
982
String hostEntry;
983
String host = null;
984
985
try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
986
UTF_8.INSTANCE))
987
{
988
while (hostsFileScanner.hasNextLine()) {
989
hostEntry = hostsFileScanner.nextLine();
990
if (!hostEntry.startsWith("#")) {
991
hostEntry = removeComments(hostEntry);
992
String[] mapping = hostEntry.split("\\s+");
993
if (mapping.length >= 2 &&
994
Arrays.equals(addr, createAddressByteArray(mapping[0]))) {
995
host = mapping[1];
996
break;
997
}
998
}
999
}
1000
} catch (IOException e) {
1001
throw new UnknownHostException("Unable to resolve address "
1002
+ Arrays.toString(addr) + " as hosts file " + hostsFile
1003
+ " not found ");
1004
}
1005
1006
if ((host == null) || (host.isEmpty()) || (host.equals(" "))) {
1007
throw new UnknownHostException("Requested address "
1008
+ Arrays.toString(addr)
1009
+ " resolves to an invalid entry in hosts file "
1010
+ hostsFile);
1011
}
1012
return host;
1013
}
1014
1015
/**
1016
* <p>Lookup a host mapping by name. Retrieve the IP addresses
1017
* associated with a host.
1018
*
1019
* <p>Search the configured hosts file for the addresses associated
1020
* with the specified host name.
1021
*
1022
* @param host the specified hostname
1023
* @return array of IP addresses for the requested host
1024
* @throws UnknownHostException
1025
* if no IP address for the {@code host} could be found
1026
*/
1027
public InetAddress[] lookupAllHostAddr(String host)
1028
throws UnknownHostException {
1029
String hostEntry;
1030
String addrStr;
1031
byte addr[];
1032
List<InetAddress> inetAddresses = new ArrayList<>();
1033
List<InetAddress> inet4Addresses = new ArrayList<>();
1034
List<InetAddress> inet6Addresses = new ArrayList<>();
1035
1036
// lookup the file and create a list InetAddress for the specified host
1037
try (Scanner hostsFileScanner = new Scanner(new File(hostsFile),
1038
UTF_8.INSTANCE)) {
1039
while (hostsFileScanner.hasNextLine()) {
1040
hostEntry = hostsFileScanner.nextLine();
1041
if (!hostEntry.startsWith("#")) {
1042
hostEntry = removeComments(hostEntry);
1043
if (hostEntry.contains(host)) {
1044
addrStr = extractHostAddr(hostEntry, host);
1045
if ((addrStr != null) && (!addrStr.isEmpty())) {
1046
addr = createAddressByteArray(addrStr);
1047
if (addr != null) {
1048
InetAddress address = InetAddress.getByAddress(host, addr);
1049
inetAddresses.add(address);
1050
if (address instanceof Inet4Address) {
1051
inet4Addresses.add(address);
1052
}
1053
if (address instanceof Inet6Address) {
1054
inet6Addresses.add(address);
1055
}
1056
}
1057
}
1058
}
1059
}
1060
}
1061
} catch (IOException e) {
1062
throw new UnknownHostException("Unable to resolve host " + host
1063
+ " as hosts file " + hostsFile + " not found ");
1064
}
1065
1066
List<InetAddress> res;
1067
// If "preferIPv4Stack" system property is set to "true" then return
1068
// only IPv4 addresses
1069
if (preferIPv4Stack) {
1070
res = inet4Addresses;
1071
} else {
1072
// Otherwise, analyse "preferIPv6Addresses" value
1073
res = switch (preferIPv6Address) {
1074
case PREFER_IPV4_VALUE -> concatAddresses(inet4Addresses, inet6Addresses);
1075
case PREFER_IPV6_VALUE -> concatAddresses(inet6Addresses, inet4Addresses);
1076
default -> inetAddresses;
1077
};
1078
}
1079
1080
if (res.isEmpty()) {
1081
throw new UnknownHostException("Unable to resolve host " + host
1082
+ " in hosts file " + hostsFile);
1083
}
1084
return res.toArray(EMPTY_ARRAY);
1085
}
1086
1087
private static List<InetAddress> concatAddresses(List<InetAddress> firstPart,
1088
List<InetAddress> secondPart) {
1089
List<InetAddress> result = new ArrayList<>(firstPart);
1090
result.addAll(secondPart);
1091
return result;
1092
}
1093
1094
private String removeComments(String hostsEntry) {
1095
String filteredEntry = hostsEntry;
1096
int hashIndex;
1097
1098
if ((hashIndex = hostsEntry.indexOf("#")) != -1) {
1099
filteredEntry = hostsEntry.substring(0, hashIndex);
1100
}
1101
return filteredEntry;
1102
}
1103
1104
private byte [] createAddressByteArray(String addrStr) {
1105
byte[] addrArray;
1106
// check if IPV4 address - most likely
1107
addrArray = IPAddressUtil.textToNumericFormatV4(addrStr);
1108
if (addrArray == null) {
1109
addrArray = IPAddressUtil.textToNumericFormatV6(addrStr);
1110
}
1111
return addrArray;
1112
}
1113
1114
/** host to ip address mapping */
1115
private String extractHostAddr(String hostEntry, String host) {
1116
String[] mapping = hostEntry.split("\\s+");
1117
String hostAddr = null;
1118
1119
if (mapping.length >= 2) {
1120
// look at the host aliases
1121
for (int i = 1; i < mapping.length; i++) {
1122
if (mapping[i].equalsIgnoreCase(host)) {
1123
hostAddr = mapping[0];
1124
}
1125
}
1126
}
1127
return hostAddr;
1128
}
1129
}
1130
1131
static final InetAddressImpl impl;
1132
1133
static {
1134
// create the impl
1135
impl = InetAddressImplFactory.create();
1136
1137
// create name service
1138
nameService = createNameService();
1139
}
1140
1141
/**
1142
* Create an instance of the NameService interface based on
1143
* the setting of the {@code jdk.net.hosts.file} system property.
1144
*
1145
* <p>The default NameService is the PlatformNameService, which typically
1146
* delegates name and address resolution calls to the underlying
1147
* OS network libraries.
1148
*
1149
* <p> A HostsFileNameService is created if the {@code jdk.net.hosts.file}
1150
* system property is set. If the specified file doesn't exist, the name or
1151
* address lookup will result in an UnknownHostException. Thus, non existent
1152
* hosts file is handled as if the file is empty.
1153
*
1154
* @return a NameService
1155
*/
1156
private static NameService createNameService() {
1157
1158
String hostsFileName =
1159
GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file");
1160
NameService theNameService;
1161
if (hostsFileName != null) {
1162
theNameService = new HostsFileNameService(hostsFileName);
1163
} else {
1164
theNameService = new PlatformNameService();
1165
}
1166
return theNameService;
1167
}
1168
1169
/**
1170
* Creates an InetAddress based on the provided host name and IP address.
1171
* No name service is checked for the validity of the address.
1172
*
1173
* <p> The host name can either be a machine name, such as
1174
* "{@code www.example.com}", or a textual representation of its IP
1175
* address.
1176
* <p> No validity checking is done on the host name either.
1177
*
1178
* <p> If addr specifies an IPv4 address an instance of Inet4Address
1179
* will be returned; otherwise, an instance of Inet6Address
1180
* will be returned.
1181
*
1182
* <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1183
* must be 16 bytes long
1184
*
1185
* @param host the specified host
1186
* @param addr the raw IP address in network byte order
1187
* @return an InetAddress object created from the raw IP address.
1188
* @throws UnknownHostException if IP address is of illegal length
1189
* @since 1.4
1190
*/
1191
public static InetAddress getByAddress(String host, byte[] addr)
1192
throws UnknownHostException {
1193
if (host != null && !host.isEmpty() && host.charAt(0) == '[') {
1194
if (host.charAt(host.length()-1) == ']') {
1195
host = host.substring(1, host.length() -1);
1196
}
1197
}
1198
if (addr != null) {
1199
if (addr.length == Inet4Address.INADDRSZ) {
1200
return new Inet4Address(host, addr);
1201
} else if (addr.length == Inet6Address.INADDRSZ) {
1202
byte[] newAddr
1203
= IPAddressUtil.convertFromIPv4MappedAddress(addr);
1204
if (newAddr != null) {
1205
return new Inet4Address(host, newAddr);
1206
} else {
1207
return new Inet6Address(host, addr);
1208
}
1209
}
1210
}
1211
throw new UnknownHostException("addr is of illegal length");
1212
}
1213
1214
1215
/**
1216
* Determines the IP address of a host, given the host's name.
1217
*
1218
* <p> The host name can either be a machine name, such as
1219
* "{@code www.example.com}", or a textual representation of its
1220
* IP address. If a literal IP address is supplied, only the
1221
* validity of the address format is checked.
1222
*
1223
* <p> For {@code host} specified in literal IPv6 address,
1224
* either the form defined in RFC 2732 or the literal IPv6 address
1225
* format defined in RFC 2373 is accepted. IPv6 scoped addresses are also
1226
* supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
1227
* scoped addresses.
1228
*
1229
* <p> If the host is {@code null} or {@code host.length()} is equal
1230
* to zero, then an {@code InetAddress} representing an address of the
1231
* loopback interface is returned.
1232
* See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC&nbsp;3330</a>
1233
* section&nbsp;2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>
1234
* section&nbsp;2.5.3.
1235
*
1236
* <p> If there is a security manager, and {@code host} is not {@code null}
1237
* or {@code host.length() } is not equal to zero, the security manager's
1238
* {@code checkConnect} method is called with the hostname and {@code -1}
1239
* as its arguments to determine if the operation is allowed.
1240
*
1241
* @param host the specified host, or {@code null}.
1242
* @return an IP address for the given host name.
1243
* @throws UnknownHostException if no IP address for the
1244
* {@code host} could be found, or if a scope_id was specified
1245
* for a global IPv6 address.
1246
* @throws SecurityException if a security manager exists
1247
* and its checkConnect method doesn't allow the operation
1248
*/
1249
public static InetAddress getByName(String host)
1250
throws UnknownHostException {
1251
return InetAddress.getAllByName(host)[0];
1252
}
1253
1254
// called from deployment cache manager
1255
private static InetAddress getByName(String host, InetAddress reqAddr)
1256
throws UnknownHostException {
1257
return InetAddress.getAllByName(host, reqAddr)[0];
1258
}
1259
1260
/**
1261
* Given the name of a host, returns an array of its IP addresses,
1262
* based on the configured name service on the system.
1263
*
1264
* <p> The host name can either be a machine name, such as
1265
* "{@code www.example.com}", or a textual representation of its IP
1266
* address. If a literal IP address is supplied, only the
1267
* validity of the address format is checked.
1268
*
1269
* <p> For {@code host} specified in <i>literal IPv6 address</i>,
1270
* either the form defined in RFC 2732 or the literal IPv6 address
1271
* format defined in RFC 2373 is accepted. A literal IPv6 address may
1272
* also be qualified by appending a scoped zone identifier or scope_id.
1273
* The syntax and usage of scope_ids is described
1274
* <a href="Inet6Address.html#scoped">here</a>.
1275
*
1276
* <p> If the host is {@code null} or {@code host.length()} is equal
1277
* to zero, then an {@code InetAddress} representing an address of the
1278
* loopback interface is returned.
1279
* See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC&nbsp;3330</a>
1280
* section&nbsp;2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>
1281
* section&nbsp;2.5.3. </p>
1282
*
1283
* <p> If there is a security manager, and {@code host} is not {@code null}
1284
* or {@code host.length() } is not equal to zero, the security manager's
1285
* {@code checkConnect} method is called with the hostname and {@code -1}
1286
* as its arguments to determine if the operation is allowed.
1287
*
1288
* @param host the name of the host, or {@code null}.
1289
* @return an array of all the IP addresses for a given host name.
1290
*
1291
* @throws UnknownHostException if no IP address for the
1292
* {@code host} could be found, or if a scope_id was specified
1293
* for a global IPv6 address.
1294
* @throws SecurityException if a security manager exists and its
1295
* {@code checkConnect} method doesn't allow the operation.
1296
*
1297
* @see SecurityManager#checkConnect
1298
*/
1299
public static InetAddress[] getAllByName(String host)
1300
throws UnknownHostException {
1301
return getAllByName(host, null);
1302
}
1303
1304
private static InetAddress[] getAllByName(String host, InetAddress reqAddr)
1305
throws UnknownHostException {
1306
1307
if (host == null || host.isEmpty()) {
1308
InetAddress[] ret = new InetAddress[1];
1309
ret[0] = impl.loopbackAddress();
1310
return ret;
1311
}
1312
1313
boolean ipv6Expected = false;
1314
if (host.charAt(0) == '[') {
1315
// This is supposed to be an IPv6 literal
1316
if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
1317
host = host.substring(1, host.length() -1);
1318
ipv6Expected = true;
1319
} else {
1320
// This was supposed to be a IPv6 address, but it's not!
1321
throw new UnknownHostException(host + ": invalid IPv6 address");
1322
}
1323
}
1324
1325
// if host is an IP address, we won't do further lookup
1326
if (Character.digit(host.charAt(0), 16) != -1
1327
|| (host.charAt(0) == ':')) {
1328
byte[] addr = null;
1329
int numericZone = -1;
1330
String ifname = null;
1331
// see if it is IPv4 address
1332
addr = IPAddressUtil.textToNumericFormatV4(host);
1333
if (addr == null) {
1334
// This is supposed to be an IPv6 literal
1335
// Check if a numeric or string zone id is present
1336
int pos;
1337
if ((pos=host.indexOf ('%')) != -1) {
1338
numericZone = checkNumericZone (host);
1339
if (numericZone == -1) { /* remainder of string must be an ifname */
1340
ifname = host.substring (pos+1);
1341
}
1342
}
1343
if ((addr = IPAddressUtil.textToNumericFormatV6(host)) == null && host.contains(":")) {
1344
throw new UnknownHostException(host + ": invalid IPv6 address");
1345
}
1346
} else if (ipv6Expected) {
1347
// Means an IPv4 literal between brackets!
1348
throw new UnknownHostException("["+host+"]");
1349
}
1350
InetAddress[] ret = new InetAddress[1];
1351
if(addr != null) {
1352
if (addr.length == Inet4Address.INADDRSZ) {
1353
ret[0] = new Inet4Address(null, addr);
1354
} else {
1355
if (ifname != null) {
1356
ret[0] = new Inet6Address(null, addr, ifname);
1357
} else {
1358
ret[0] = new Inet6Address(null, addr, numericZone);
1359
}
1360
}
1361
return ret;
1362
}
1363
} else if (ipv6Expected) {
1364
// We were expecting an IPv6 Literal, but got something else
1365
throw new UnknownHostException("["+host+"]");
1366
}
1367
return getAllByName0(host, reqAddr, true, true);
1368
}
1369
1370
/**
1371
* Returns the loopback address.
1372
* <p>
1373
* The InetAddress returned will represent the IPv4
1374
* loopback address, 127.0.0.1, or the IPv6 loopback
1375
* address, ::1. The IPv4 loopback address returned
1376
* is only one of many in the form 127.*.*.*
1377
*
1378
* @return the InetAddress loopback instance.
1379
* @since 1.7
1380
*/
1381
public static InetAddress getLoopbackAddress() {
1382
return impl.loopbackAddress();
1383
}
1384
1385
1386
/**
1387
* check if the literal address string has %nn appended
1388
* returns -1 if not, or the numeric value otherwise.
1389
*
1390
* %nn may also be a string that represents the displayName of
1391
* a currently available NetworkInterface.
1392
*/
1393
private static int checkNumericZone (String s) throws UnknownHostException {
1394
int percent = s.indexOf ('%');
1395
int slen = s.length();
1396
int digit, zone=0;
1397
if (percent == -1) {
1398
return -1;
1399
}
1400
for (int i=percent+1; i<slen; i++) {
1401
char c = s.charAt(i);
1402
if (c == ']') {
1403
if (i == percent+1) {
1404
/* empty per-cent field */
1405
return -1;
1406
}
1407
break;
1408
}
1409
if ((digit = Character.digit (c, 10)) < 0) {
1410
return -1;
1411
}
1412
zone = (zone * 10) + digit;
1413
}
1414
return zone;
1415
}
1416
1417
private static InetAddress[] getAllByName0 (String host)
1418
throws UnknownHostException
1419
{
1420
return getAllByName0(host, true);
1421
}
1422
1423
/**
1424
* package private so SocketPermission can call it
1425
*/
1426
static InetAddress[] getAllByName0 (String host, boolean check)
1427
throws UnknownHostException {
1428
return getAllByName0 (host, null, check, true);
1429
}
1430
1431
/**
1432
* Designated lookup method.
1433
*
1434
* @param host host name to look up
1435
* @param reqAddr requested address to be the 1st in returned array
1436
* @param check perform security check
1437
* @param useCache use cached value if not expired else always
1438
* perform name service lookup (and cache the result)
1439
* @return array of InetAddress(es)
1440
* @throws UnknownHostException if host name is not found
1441
*/
1442
private static InetAddress[] getAllByName0(String host,
1443
InetAddress reqAddr,
1444
boolean check,
1445
boolean useCache)
1446
throws UnknownHostException {
1447
1448
/* If it gets here it is presumed to be a hostname */
1449
1450
/* make sure the connection to the host is allowed, before we
1451
* give out a hostname
1452
*/
1453
if (check) {
1454
@SuppressWarnings("removal")
1455
SecurityManager security = System.getSecurityManager();
1456
if (security != null) {
1457
security.checkConnect(host, -1);
1458
}
1459
}
1460
1461
// remove expired addresses from cache - expirySet keeps them ordered
1462
// by expiry time so we only need to iterate the prefix of the NavigableSet...
1463
long now = System.nanoTime();
1464
for (CachedAddresses caddrs : expirySet) {
1465
// compare difference of time instants rather than
1466
// time instants directly, to avoid possible overflow.
1467
// (see System.nanoTime() recommendations...)
1468
if ((caddrs.expiryTime - now) < 0L) {
1469
// ConcurrentSkipListSet uses weakly consistent iterator,
1470
// so removing while iterating is OK...
1471
if (expirySet.remove(caddrs)) {
1472
// ... remove from cache
1473
cache.remove(caddrs.host, caddrs);
1474
}
1475
} else {
1476
// we encountered 1st element that expires in future
1477
break;
1478
}
1479
}
1480
1481
// look-up or remove from cache
1482
Addresses addrs;
1483
if (useCache) {
1484
addrs = cache.get(host);
1485
} else {
1486
addrs = cache.remove(host);
1487
if (addrs != null) {
1488
if (addrs instanceof CachedAddresses) {
1489
// try removing from expirySet too if CachedAddresses
1490
expirySet.remove(addrs);
1491
}
1492
addrs = null;
1493
}
1494
}
1495
1496
if (addrs == null) {
1497
// create a NameServiceAddresses instance which will look up
1498
// the name service and install it within cache...
1499
Addresses oldAddrs = cache.putIfAbsent(
1500
host,
1501
addrs = new NameServiceAddresses(host, reqAddr)
1502
);
1503
if (oldAddrs != null) { // lost putIfAbsent race
1504
addrs = oldAddrs;
1505
}
1506
}
1507
1508
// ask Addresses to get an array of InetAddress(es) and clone it
1509
return addrs.get().clone();
1510
}
1511
1512
static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)
1513
throws UnknownHostException
1514
{
1515
InetAddress[] addresses = null;
1516
UnknownHostException ex = null;
1517
1518
try {
1519
addresses = nameService.lookupAllHostAddr(host);
1520
} catch (UnknownHostException uhe) {
1521
if (host.equalsIgnoreCase("localhost")) {
1522
addresses = new InetAddress[] { impl.loopbackAddress() };
1523
}
1524
else {
1525
ex = uhe;
1526
}
1527
}
1528
1529
if (addresses == null) {
1530
throw ex == null ? new UnknownHostException(host) : ex;
1531
}
1532
1533
// More to do?
1534
if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {
1535
// Find it?
1536
int i = 1;
1537
for (; i < addresses.length; i++) {
1538
if (addresses[i].equals(reqAddr)) {
1539
break;
1540
}
1541
}
1542
// Rotate
1543
if (i < addresses.length) {
1544
InetAddress tmp, tmp2 = reqAddr;
1545
for (int j = 0; j < i; j++) {
1546
tmp = addresses[j];
1547
addresses[j] = tmp2;
1548
tmp2 = tmp;
1549
}
1550
addresses[i] = tmp2;
1551
}
1552
}
1553
1554
return addresses;
1555
}
1556
1557
/**
1558
* Returns an {@code InetAddress} object given the raw IP address .
1559
* The argument is in network byte order: the highest order
1560
* byte of the address is in {@code getAddress()[0]}.
1561
*
1562
* <p> This method doesn't block, i.e. no reverse name service lookup
1563
* is performed.
1564
*
1565
* <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
1566
* must be 16 bytes long
1567
*
1568
* @param addr the raw IP address in network byte order
1569
* @return an InetAddress object created from the raw IP address.
1570
* @throws UnknownHostException if IP address is of illegal length
1571
* @since 1.4
1572
*/
1573
public static InetAddress getByAddress(byte[] addr)
1574
throws UnknownHostException {
1575
return getByAddress(null, addr);
1576
}
1577
1578
private static final class CachedLocalHost {
1579
final String host;
1580
final InetAddress addr;
1581
final long expiryTime = System.nanoTime() + 5000_000_000L; // now + 5s;
1582
1583
CachedLocalHost(String host, InetAddress addr) {
1584
this.host = host;
1585
this.addr = addr;
1586
}
1587
}
1588
1589
private static volatile CachedLocalHost cachedLocalHost;
1590
1591
/**
1592
* Returns the address of the local host. This is achieved by retrieving
1593
* the name of the host from the system, then resolving that name into
1594
* an {@code InetAddress}.
1595
*
1596
* <P>Note: The resolved address may be cached for a short period of time.
1597
* </P>
1598
*
1599
* <p>If there is a security manager, its
1600
* {@code checkConnect} method is called
1601
* with the local host name and {@code -1}
1602
* as its arguments to see if the operation is allowed.
1603
* If the operation is not allowed, an InetAddress representing
1604
* the loopback address is returned.
1605
*
1606
* @return the address of the local host.
1607
*
1608
* @throws UnknownHostException if the local host name could not
1609
* be resolved into an address.
1610
*
1611
* @see SecurityManager#checkConnect
1612
* @see java.net.InetAddress#getByName(java.lang.String)
1613
*/
1614
public static InetAddress getLocalHost() throws UnknownHostException {
1615
1616
@SuppressWarnings("removal")
1617
SecurityManager security = System.getSecurityManager();
1618
try {
1619
// is cached data still valid?
1620
CachedLocalHost clh = cachedLocalHost;
1621
if (clh != null && (clh.expiryTime - System.nanoTime()) >= 0L) {
1622
if (security != null) {
1623
security.checkConnect(clh.host, -1);
1624
}
1625
return clh.addr;
1626
}
1627
1628
String local = impl.getLocalHostName();
1629
1630
if (security != null) {
1631
security.checkConnect(local, -1);
1632
}
1633
1634
InetAddress localAddr;
1635
if (local.equals("localhost")) {
1636
// shortcut for "localhost" host name
1637
localAddr = impl.loopbackAddress();
1638
} else {
1639
// call getAllByName0 without security checks and
1640
// without using cached data
1641
try {
1642
localAddr = getAllByName0(local, null, false, false)[0];
1643
} catch (UnknownHostException uhe) {
1644
// Rethrow with a more informative error message.
1645
UnknownHostException uhe2 =
1646
new UnknownHostException(local + ": " +
1647
uhe.getMessage());
1648
uhe2.initCause(uhe);
1649
throw uhe2;
1650
}
1651
}
1652
cachedLocalHost = new CachedLocalHost(local, localAddr);
1653
return localAddr;
1654
} catch (java.lang.SecurityException e) {
1655
return impl.loopbackAddress();
1656
}
1657
}
1658
1659
/**
1660
* Perform class load-time initializations.
1661
*/
1662
private static native void init();
1663
1664
1665
/*
1666
* Returns the InetAddress representing anyLocalAddress
1667
* (typically 0.0.0.0 or ::0)
1668
*/
1669
static InetAddress anyLocalAddress() {
1670
return impl.anyLocalAddress();
1671
}
1672
1673
/*
1674
* Load and instantiate an underlying impl class
1675
*/
1676
static InetAddressImpl loadImpl(String implName) {
1677
Object impl = null;
1678
1679
/*
1680
* Property "impl.prefix" will be prepended to the classname
1681
* of the implementation object we instantiate, to which we
1682
* delegate the real work (like native methods). This
1683
* property can vary across implementations of the java.
1684
* classes. The default is an empty String "".
1685
*/
1686
String prefix = GetPropertyAction.privilegedGetProperty("impl.prefix", "");
1687
try {
1688
@SuppressWarnings("deprecation")
1689
Object tmp = Class.forName("java.net." + prefix + implName).newInstance();
1690
impl = tmp;
1691
} catch (ClassNotFoundException e) {
1692
System.err.println("Class not found: java.net." + prefix +
1693
implName + ":\ncheck impl.prefix property " +
1694
"in your properties file.");
1695
} catch (InstantiationException e) {
1696
System.err.println("Could not instantiate: java.net." + prefix +
1697
implName + ":\ncheck impl.prefix property " +
1698
"in your properties file.");
1699
} catch (IllegalAccessException e) {
1700
System.err.println("Cannot access class: java.net." + prefix +
1701
implName + ":\ncheck impl.prefix property " +
1702
"in your properties file.");
1703
}
1704
1705
if (impl == null) {
1706
try {
1707
@SuppressWarnings("deprecation")
1708
Object tmp = Class.forName(implName).newInstance();
1709
impl = tmp;
1710
} catch (Exception e) {
1711
throw new Error("System property impl.prefix incorrect");
1712
}
1713
}
1714
1715
return (InetAddressImpl) impl;
1716
}
1717
1718
/**
1719
* Initializes an empty InetAddress.
1720
*/
1721
@java.io.Serial
1722
private void readObjectNoData () {
1723
if (getClass().getClassLoader() != null) {
1724
throw new SecurityException ("invalid address type");
1725
}
1726
}
1727
1728
private static final jdk.internal.misc.Unsafe UNSAFE
1729
= jdk.internal.misc.Unsafe.getUnsafe();
1730
private static final long FIELDS_OFFSET
1731
= UNSAFE.objectFieldOffset(InetAddress.class, "holder");
1732
1733
/**
1734
* Restores the state of this object from the stream.
1735
*
1736
* @param s the {@code ObjectInputStream} from which data is read
1737
* @throws IOException if an I/O error occurs
1738
* @throws ClassNotFoundException if a serialized class cannot be loaded
1739
*/
1740
@java.io.Serial
1741
private void readObject (ObjectInputStream s) throws
1742
IOException, ClassNotFoundException {
1743
if (getClass().getClassLoader() != null) {
1744
throw new SecurityException ("invalid address type");
1745
}
1746
GetField gf = s.readFields();
1747
String host = (String)gf.get("hostName", null);
1748
int address = gf.get("address", 0);
1749
int family = gf.get("family", 0);
1750
if (family != IPv4 && family != IPv6) {
1751
throw new InvalidObjectException("invalid address family type: " + family);
1752
}
1753
InetAddressHolder h = new InetAddressHolder(host, address, family);
1754
UNSAFE.putReference(this, FIELDS_OFFSET, h);
1755
}
1756
1757
/* needed because the serializable fields no longer exist */
1758
1759
/**
1760
* @serialField hostName String the hostname for this address
1761
* @serialField address int holds a 32-bit IPv4 address.
1762
* @serialField family int specifies the address family type, for instance,
1763
* {@code '1'} for IPv4 addresses, and {@code '2'} for IPv6 addresses.
1764
*/
1765
@java.io.Serial
1766
private static final ObjectStreamField[] serialPersistentFields = {
1767
new ObjectStreamField("hostName", String.class),
1768
new ObjectStreamField("address", int.class),
1769
new ObjectStreamField("family", int.class),
1770
};
1771
1772
/**
1773
* Writes the state of this object to the stream.
1774
*
1775
* @param s the {@code ObjectOutputStream} to which data is written
1776
* @throws IOException if an I/O error occurs
1777
*/
1778
@java.io.Serial
1779
private void writeObject (ObjectOutputStream s) throws
1780
IOException {
1781
if (getClass().getClassLoader() != null) {
1782
throw new SecurityException ("invalid address type");
1783
}
1784
PutField pf = s.putFields();
1785
pf.put("hostName", holder().getHostName());
1786
pf.put("address", holder().getAddress());
1787
pf.put("family", holder().getFamily());
1788
s.writeFields();
1789
}
1790
}
1791
1792
/*
1793
* Simple factory to create the impl
1794
*/
1795
class InetAddressImplFactory {
1796
1797
static InetAddressImpl create() {
1798
return InetAddress.loadImpl(isIPv6Supported() ?
1799
"Inet6AddressImpl" : "Inet4AddressImpl");
1800
}
1801
1802
static native boolean isIPv6Supported();
1803
}
1804
1805