1 /* 2 * Copyright (c) 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.spi; 27 28 import java.lang.annotation.Native; 29 import java.net.InetAddress; 30 import java.net.UnknownHostException; 31 import java.util.stream.Stream; 32 33 /** 34 * This interface defines operations for looking-up host names and IP addresses. 35 * An instance of {@code InetAddressResolver} is 36 * <a href="{@docRoot}/java.base/java/net/InetAddress.html#resolverProviders">installed</a> 37 * as a <i>system-wide resolver</i>. 38 * {@link InetAddress} delegates all lookup requests to the installed <i>system-wide resolver</i> 39 * instance. 40 * <p> 41 * The <i>system-wide resolver</i> can be customized by 42 * <a href="{@docRoot}/java.base/java/net/InetAddress.html#resolverProviders">deploying an implementation</a> 43 * of {@link InetAddressResolverProvider}. 44 */ 45 public interface InetAddressResolver { 46 47 /** 48 * Given the name of a host, returns a stream of IP addresses of the requested 49 * address family associated with a provided hostname. 50 * <p> 51 * {@code host} should be a machine name, such as "{@code www.example.com}", 52 * not a textual representation of its IP address. No validation is performed on 53 * the given {@code host} name: if a textual representation is supplied, the name 54 * resolution is likely to fail and {@link UnknownHostException} may be thrown. 55 * <p> 56 * The address family type and addresses order are specified by the {@code LookupPolicy} instance. 57 * Lookup operation characteristics could be acquired with {@link LookupPolicy#characteristics()}. If 58 * {@link InetAddressResolver.LookupPolicy#IPV4} and {@link InetAddressResolver.LookupPolicy#IPV6} 59 * characteristics provided then this method returns addresses of both IPV4 and IPV6 families. 60 * 61 * @param host the specified hostname 62 * @param lookupPolicy the address lookup policy 63 * @return a stream of IP addresses for the requested host 64 * @throws NullPointerException if {@code host} is {@code null} 65 * @throws UnknownHostException if no IP address for the {@code host} could be found 66 * @see LookupPolicy 67 */ 68 Stream<InetAddress> lookupAddresses(String host, LookupPolicy lookupPolicy) throws UnknownHostException; 69 70 /** 71 * Lookup the host name corresponding to the raw IP address provided. 72 * 73 * <p>{@code addr} argument is in network byte order: the highest order byte of the address 74 * is in {@code addr[0]}. 75 * 76 * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array 77 * must be 16 bytes long. 78 * 79 * @param addr byte array representing a raw IP address 80 * @return {@code String} representing the host name mapping 81 * @throws UnknownHostException if no host found for the specified IP address 82 * @throws IllegalArgumentException if IP address is of illegal length 83 */ 84 String lookupHostName(byte[] addr) throws UnknownHostException; 85 86 /** 87 * A {@code LookupPolicy} object describes characteristics that can be applied to a lookup operation. 88 * In particular, it is used to specify which ordering and filtering should be performed when 89 * {@linkplain InetAddressResolver#lookupAddresses(String, LookupPolicy) looking up a host addresses}. 90 * <p> 91 * The default platform-wide lookup policy is constructed by consulting 92 * <a href="doc-files/net-properties.html#Ipv4IPv6">System Properties</a> which affect 93 * how IPv4 and IPv6 addresses are returned. 94 */ 95 final class LookupPolicy { 96 97 /** 98 * Specifies if IPv4 addresses need to be queried during lookup. 99 */ 100 @Native 101 public static final int IPV4 = 1 << 0; 102 103 /** 104 * Specifies if IPv6 addresses need to be queried during lookup. 105 */ 106 @Native 107 public static final int IPV6 = 1 << 1; 108 109 /** 110 * Specifies if IPv4 addresses should be returned first by {@code InetAddressResolver}. 111 */ 112 @Native 113 public static final int IPV4_FIRST = 1 << 2; 114 115 /** 116 * Specifies if IPv6 addresses should be returned first by {@code InetAddressResolver}. 117 */ 118 @Native 119 public static final int IPV6_FIRST = 1 << 3; 120 121 private final int characteristics; 122 123 private LookupPolicy(int characteristics) { 124 this.characteristics = characteristics; 125 } 126 127 /** 128 * This factory method creates {@link LookupPolicy LookupPolicy} instance with the provided 129 * {@code characteristics} value. 130 * <p> The {@code characteristics} value is an integer bit mask which defines 131 * parameters of a forward lookup operation. These parameters define at least: 132 * <ul> 133 * <li>the family type of the returned addresses</li> 134 * <li>the order in which a {@linkplain InetAddressResolver resolver} 135 * implementation should return its results</li> 136 * </ul> 137 * <p> To request addresses of specific family types the following bit masks can be combined: 138 * <ul> 139 * <li>{@link LookupPolicy#IPV4}: to request IPv4 addresses</li> 140 * <li>{@link LookupPolicy#IPV6}: to request IPv6 addresses</li> 141 * </ul> 142 * <br>It is an error if neither {@link LookupPolicy#IPV4} or {@link LookupPolicy#IPV6} are set. 143 * <p> To request a specific ordering of the results: 144 * <ul> 145 * <li>{@link LookupPolicy#IPV4_FIRST}: return IPv4 addresses before any IPv6 address</li> 146 * <li>{@link LookupPolicy#IPV6_FIRST}: return IPv6 addresses before any IPv4 address</li> 147 * </ul> 148 * <br>If neither {@link LookupPolicy#IPV4_FIRST} or {@link LookupPolicy#IPV6_FIRST} are set it 149 * implies <a href="{@docRoot}/java.base/java/net/doc-files/net-properties.html#Ipv4IPv6">"system"</a> 150 * order of addresses. 151 * It is an error to request both {@link LookupPolicy#IPV4_FIRST} and {@link LookupPolicy#IPV6_FIRST}. 152 * 153 * @param characteristics value which represents the set of lookup characteristics 154 * @return an instance of {@code InetAddressResolver.LookupPolicy} 155 * @throws IllegalArgumentException if illegal characteristic bit mask is provided 156 * @see InetAddressResolver#lookupAddresses(String, LookupPolicy) 157 */ 158 public static final LookupPolicy of(int characteristics) { 159 // At least one type of addresses should be requested 160 if ((characteristics & IPV4) == 0 && (characteristics & IPV6) == 0) { 161 throw new IllegalArgumentException("No address type specified"); 162 } 163 164 // Requested order of addresses couldn't be determined 165 if ((characteristics & IPV4_FIRST) != 0 && (characteristics & IPV6_FIRST) != 0) { 166 throw new IllegalArgumentException("Addresses order cannot be determined"); 167 } 168 169 // If IPv4 addresses requested to be returned first then they should be requested too 170 if ((characteristics & IPV4_FIRST) != 0 && (characteristics & IPV4) == 0) { 171 throw new IllegalArgumentException("Addresses order and type do not match"); 172 } 173 174 // If IPv6 addresses requested to be returned first then they should be requested too 175 if ((characteristics & IPV6_FIRST) != 0 && (characteristics & IPV6) == 0) { 176 throw new IllegalArgumentException("Addresses order and type do not match"); 177 } 178 return new LookupPolicy(characteristics); 179 } 180 181 /** 182 * Returns an integer value which specifies lookup operation characteristics. 183 * Type and order of address families queried during resolution of host IP addresses. 184 * 185 * @return a characteristics value 186 * @see InetAddressResolver#lookupAddresses(String, LookupPolicy) 187 */ 188 public final int characteristics() { 189 return characteristics; 190 } 191 } 192 }