001/* 002 * Copyright 2019-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2019-2020 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2019-2020 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk; 037 038 039 040import java.net.InetAddress; 041import java.net.UnknownHostException; 042 043import com.unboundid.util.Extensible; 044import com.unboundid.util.StaticUtils; 045import com.unboundid.util.ThreadSafety; 046import com.unboundid.util.ThreadSafetyLevel; 047 048 049 050/** 051 * This class defines an API that the LDAP SDK can use to resolve host names to 052 * IP addresses, and vice versa. The default implementations of the name 053 * resolution methods simply delegates to the corresponding methods provided in 054 * the {@code InetAddress} class. Subclasses may override these methods to 055 * provide support for caching, improved instrumentation, or other 056 * functionality. Any such methods that are not overridden will get the 057 * JVM-default behavior. 058 */ 059@Extensible() 060@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 061public abstract class NameResolver 062{ 063 /** 064 * The name of the system property that the JVM uses to specify how long (in 065 * seconds) to cache the results of successful name service lookups. 066 */ 067 private static final String JVM_PROPERTY_POSITIVE_ADDRESS_CACHE_TTL_SECONDS = 068 "networkaddress.cache.ttl"; 069 070 071 072 /** 073 * The name of the system property that the JVM uses to specify how long (in 074 * seconds) to cache the results of unsuccessful name service lookups (that 075 * is, lookups that return no mapping). 076 */ 077 private static final String JVM_PROPERTY_NEGATIVE_ADDRESS_CACHE_TTL_SECONDS = 078 "networkaddress.cache.negative.ttl"; 079 080 081 082 /** 083 * Creates a new instance of this default name resolver. 084 */ 085 protected NameResolver() 086 { 087 // No implementation is required. 088 } 089 090 091 092 /** 093 * Retrieves an {@code InetAddress} that encapsulates an IP address associated 094 * with the provided host name. 095 * 096 * @param host The host name for which to retrieve a corresponding 097 * {@code InetAddress} object. It can be a resolvable name or 098 * a textual representation of an IP address. If the provided 099 * name is the textual representation of an IPv6 address, then 100 * it can use either the form described in RFC 2373 or RFC 2732, 101 * or it can be an IPv6 scoped address. If it is {@code null}, 102 * then the returned address should represent an address of the 103 * loopback interface. 104 * 105 * @return An {@code InetAddress} that encapsulates an IP address associated 106 * with the provided host name. 107 * 108 * @throws UnknownHostException If the provided name cannot be resolved to 109 * its corresponding IP addresses. 110 * 111 * @throws SecurityException If a security manager prevents the name 112 * resolution attempt. 113 */ 114 public InetAddress getByName(final String host) 115 throws UnknownHostException, SecurityException 116 { 117 return InetAddress.getByName(host); 118 } 119 120 121 122 /** 123 * Retrieves an array of {@code InetAddress} objects that encapsulate all 124 * known IP addresses associated with the provided host name. 125 * 126 * @param host The host name for which to retrieve the corresponding 127 * {@code InetAddress} objects. It can be a resolvable name or 128 * a textual representation of an IP address. If the provided 129 * name is the textual representation of an IPv6 address, then 130 * it can use either the form described in RFC 2373 or RFC 2732, 131 * or it can be an IPv6 scoped address. If it is {@code null}, 132 * then the returned address should represent an address of the 133 * loopback interface. 134 * 135 * @return An array of {@code InetAddress} objects that encapsulate all known 136 * IP addresses associated with the provided host name. 137 * 138 * @throws UnknownHostException If the provided name cannot be resolved to 139 * its corresponding IP addresses. 140 * 141 * @throws SecurityException If a security manager prevents the name 142 * resolution attempt. 143 */ 144 public InetAddress[] getAllByName(final String host) 145 throws UnknownHostException, SecurityException 146 { 147 return InetAddress.getAllByName(host); 148 } 149 150 151 152 /** 153 * Retrieves the host name for the provided {@code InetAddress} object. 154 * 155 * @param inetAddress The address for which to retrieve the host name. It 156 * must not be {@code null}. 157 * 158 * @return The host name for the provided {@code InetAddress} object, or a 159 * textual representation of the IP address if the name cannot be 160 * determined. 161 */ 162 public String getHostName(final InetAddress inetAddress) 163 { 164 return inetAddress.getHostName(); 165 } 166 167 168 169 /** 170 * Retrieves the canonical host name for the provided {@code InetAddress} 171 * object. 172 * 173 * @param inetAddress The address for which to retrieve the canonical host 174 * name. It must not be {@code null}. 175 * 176 * @return The canonical host name for the provided {@code InetAddress} 177 * object, or a textual representation of the IP address if the name 178 * cannot be determined. 179 */ 180 public String getCanonicalHostName(final InetAddress inetAddress) 181 { 182 return inetAddress.getCanonicalHostName(); 183 } 184 185 186 187 /** 188 * Retrieves the address of the local host. This should be the name of the 189 * host obtained from the system, converted to an {@code InetAddress}. 190 * 191 * @return The address of the local host. 192 * 193 * @throws UnknownHostException If the local host name cannot be resolved. 194 * 195 * @throws SecurityException If a security manager prevents the name 196 * resolution attempt. 197 */ 198 public InetAddress getLocalHost() 199 throws UnknownHostException, SecurityException 200 { 201 return InetAddress.getLocalHost(); 202 } 203 204 205 206 /** 207 * Retrieves the loopback address for the system. This should be either the 208 * IPv4 loopback address of 127.0.0.1, or the IPv6 loopback address of ::1. 209 * 210 * @return The loopback address for the system. 211 */ 212 public InetAddress getLoopbackAddress() 213 { 214 return InetAddress.getLoopbackAddress(); 215 } 216 217 218 219 /** 220 * Sets the length of time in seconds for which the JVM should cache the 221 * results of successful name service lookups. 222 * <BR><BR> 223 * Note that this timeout only applies to lookups performed by the JVM itself 224 * and may not apply to all name resolver implementations. Some 225 * implementations may provide their own caching or their own lookup 226 * mechanisms that do not use this setting. 227 * 228 * @param seconds The length of time in seconds for which the JVM should 229 * cache the results of successful name service lookups. A 230 * value that is less than zero indicates that values should 231 * be cached forever. 232 */ 233 public static void setJVMSuccessfulLookupCacheTTLSeconds(final int seconds) 234 { 235 if (seconds < 0) 236 { 237 StaticUtils.setSystemProperty( 238 JVM_PROPERTY_POSITIVE_ADDRESS_CACHE_TTL_SECONDS, "-1"); 239 } 240 else 241 { 242 StaticUtils.setSystemProperty( 243 JVM_PROPERTY_POSITIVE_ADDRESS_CACHE_TTL_SECONDS, 244 String.valueOf(seconds)); 245 } 246 } 247 248 249 250 /** 251 * Sets the length of time in seconds for which the JVM should cache the 252 * results of unsuccessful name service lookups (that is, lookups in which no 253 * mapping is found). 254 * <BR><BR> 255 * Note that this timeout only applies to lookups performed by the JVM itself 256 * and may not apply to all name resolver implementations. Some 257 * implementations may provide their own caching or their own lookup 258 * mechanisms that do not use this setting. 259 * 260 * @param seconds The length of time in seconds for which the JVM should 261 * cache the results of unsuccessful name service lookups. A 262 * value that is less than zero indicates that values should 263 * be cached forever. 264 */ 265 public static void setJVMUnsuccessfulLookupCacheTTLSeconds(final int seconds) 266 { 267 if (seconds < 0) 268 { 269 StaticUtils.setSystemProperty( 270 JVM_PROPERTY_NEGATIVE_ADDRESS_CACHE_TTL_SECONDS, "-1"); 271 } 272 else 273 { 274 StaticUtils.setSystemProperty( 275 JVM_PROPERTY_NEGATIVE_ADDRESS_CACHE_TTL_SECONDS, 276 String.valueOf(seconds)); 277 } 278 } 279 280 281 282 /** 283 * Retrieves a string representation of this name resolver. 284 * 285 * @return A string representation of this name resolver. 286 */ 287 @Override() 288 public final String toString() 289 { 290 final StringBuilder buffer = new StringBuilder(); 291 toString(buffer); 292 return buffer.toString(); 293 } 294 295 296 297 /** 298 * Appends a string representation of this name resolver to the provided 299 * buffer. 300 * 301 * @param buffer A buffer to which the string representation should be 302 * appended. 303 */ 304 public abstract void toString(final StringBuilder buffer); 305}