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