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