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