diff --git a/core/java/src/net/i2p/util/Addresses.java b/core/java/src/net/i2p/util/Addresses.java index 6022bf35b72570b57912a51ed27c112922b3869b..15352975bc8bf14fdac88f634f1dcdfe0bff478b 100644 --- a/core/java/src/net/i2p/util/Addresses.java +++ b/core/java/src/net/i2p/util/Addresses.java @@ -9,7 +9,10 @@ import java.net.Inet4Address; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; @@ -294,6 +297,79 @@ public abstract class Addresses { return rv; } + /** + * For literal IP addresses, this is the same as getIP(String). + * For host names, will return the preferred type (IPv4/v6) if available, + * else the other type if available. + * Will resolve but not cache DNS host names. + * + * @param host DNS or IPv4 or IPv6 host name; if null returns null + * @return IP or null + * @since 0.9.28 + */ + public static byte[] getIP(String host, boolean preferIPv6) { + if (host == null) + return null; + if (InetAddressUtils.isIPv4Address(host) || InetAddressUtils.isIPv6Address(host)) + return getIP(host); + byte[] rv = null; + try { + InetAddress[] addrs = InetAddress.getAllByName(host); + if (addrs == null || addrs.length == 0) + return null; + for (int i = 0; i < addrs.length; i++) { + rv = addrs[i].getAddress(); + if (preferIPv6) { + if (rv.length == 16) + break; + } else { + if (rv.length == 4) + break; + } + } + } catch (UnknownHostException uhe) {} + return rv; + } + + /** + * For literal IP addresses, this is the same as getIP(String). + * For host names, will return the preferred type (IPv4/v6) if available, + * else the other type if available. + * Will resolve but not cache DNS host names. + * + * Note that order of returned results, and whether + * multiple results for either IPv4 or IPv6 or both are actually + * returned, is platform-specific and may also depend on + * JVM options such as java.net.preverIPv4Stack and java.net.preferIPv6Addresses. + * Number of results may also change based on caching at various layers, + * even if the ultimate name server results did not change. + * + * @param host DNS or IPv4 or IPv6 host name; if null returns null + * @return non-empty list IPs, or null if none + * @since 0.9.28 + */ + public static List<byte[]> getIPs(String host) { + if (host == null) + return null; + if (InetAddressUtils.isIPv4Address(host) || InetAddressUtils.isIPv6Address(host)) { + byte[] brv = getIP(host); + if (brv == null) + return null; + return Collections.singletonList(brv); + } + try { + InetAddress[] addrs = InetAddress.getAllByName(host); + if (addrs == null || addrs.length == 0) + return null; + List<byte[]> rv = new ArrayList<byte[]>(addrs.length); + for (int i = 0; i < addrs.length; i++) { + rv.add(addrs[i].getAddress()); + } + return rv; + } catch (UnknownHostException uhe) {} + return null; + } + /** * @since 0.9.3 */