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