| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. You may obtain a |
| * copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License |
| * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
| * or implied. See the License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package org.apache.geode.internal.net; |
| |
| import java.net.InetAddress; |
| import java.net.NetworkInterface; |
| import java.net.SocketException; |
| import java.net.UnknownHostException; |
| import java.util.Enumeration; |
| |
| import org.apache.geode.GemFireIOException; |
| import org.apache.geode.annotations.Immutable; |
| |
| /** |
| * Provides static utilities for manipulating, validating, and converting InetAddresses and host |
| * strings. |
| */ |
| @SuppressWarnings("unused") |
| public class InetAddressUtils { |
| |
| @Immutable |
| private static final InetAddress LOCALHOST = getLocalHost(); |
| |
| private static final String LOOPBACK_ADDRESS = |
| SocketCreator.preferIPv6Addresses() ? "::1" : "127.0.0.1"; |
| |
| @Immutable |
| private static final InetAddress LOOPBACK = toInetAddress(LOOPBACK_ADDRESS); |
| |
| private InetAddressUtils() { |
| // prevent construction |
| } |
| |
| public static InetAddress getLoopback() { |
| return LOOPBACK; |
| } |
| |
| public static String getLoopbackAddress() { |
| return LOOPBACK_ADDRESS; |
| } |
| |
| /** |
| * Returns a string version of {@code InetAddress} which can be converted back later. Essentially |
| * any leading slash is trimmed. |
| * |
| * @param val The InetAddress or String to return a formatted string of |
| * |
| * @return The string version of the InetAddress minus any leading slash |
| */ |
| public static String toHostString(Object val) { |
| if (val instanceof String) { |
| return trimLeadingSlash((String) val); |
| } |
| |
| if (val instanceof InetAddress) { |
| return ((InetAddress) val).getHostAddress(); |
| } |
| |
| return trimLeadingSlash(val.toString()); |
| } |
| |
| /** |
| * Converts the string host to an instance of {@code InetAddress}. Returns null if the string is |
| * empty. Any leading slashes on host will be ignored. The checked exception |
| * {@code UnknownHostException} is captured and an AssertionError is generated instead. |
| * |
| * @param host The string version the InetAddress |
| * |
| * @return The host converted to InetAddress instance |
| * |
| * @throws AssertionError If conversion of host results in {@code UnknownHostException} |
| */ |
| public static InetAddress toInetAddress(String host) { |
| try { |
| return toInetAddressOrThrow(host); |
| } catch (UnknownHostException e) { |
| throw new AssertionError("Failed to get InetAddress: " + host, e); |
| } |
| } |
| |
| /** |
| * Validates the host by making sure it can successfully be used to get an instance of |
| * InetAddress. Any leading slashes on host will be ignored. If the host string is null, empty or |
| * would result in {@code java.lang.UnknownHostException} then null is returned. |
| * |
| * @param host The string version the InetAddress |
| * |
| * @return The host converted to InetAddress instance |
| */ |
| public static String validateHost(String host) { |
| try { |
| return validateHostOrThrow(host); |
| } catch (UnknownHostException e) { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns true if host matches the LOCALHOST. |
| */ |
| public static boolean isLocalHost(InetAddress host) { |
| if (LOCALHOST.equals(host)) { |
| return true; |
| } |
| |
| try { |
| Enumeration en = NetworkInterface.getNetworkInterfaces(); |
| while (en.hasMoreElements()) { |
| NetworkInterface i = (NetworkInterface) en.nextElement(); |
| for (Enumeration en2 = i.getInetAddresses(); en2.hasMoreElements();) { |
| InetAddress addr = (InetAddress) en2.nextElement(); |
| if (host.equals(addr)) { |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } catch (SocketException e) { |
| throw new GemFireIOException("Unable to query network interface", e); |
| } |
| } |
| |
| /** |
| * Returns true if host matches the LOCALHOST. |
| */ |
| public static boolean isLocalHost(String host) { |
| return isLocalHost(toInetAddress(host)); |
| } |
| |
| /** |
| * Returns true if host matches the LOOPBACK (127.0.0.1). |
| */ |
| public static boolean isLoopback(InetAddress host) { |
| return LOOPBACK.equals(host); |
| } |
| |
| /** |
| * Returns true if host matches the LOOPBACK (127.0.0.1). |
| */ |
| public static boolean isLoopback(String host) { |
| return isLoopback(toInetAddress(host)); |
| } |
| |
| /** |
| * Returns a version of the value after removing any leading slashes |
| */ |
| protected static String trimLeadingSlash(String value) { |
| if (value == null) { |
| return ""; |
| } |
| |
| while (value.indexOf('/') > -1) { |
| value = value.substring(value.indexOf('/') + 1); |
| } |
| |
| return value; |
| } |
| |
| /** |
| * Converts the string host to an instance of {@code InetAddress}. Returns null if the string is |
| * empty. Any leading slashes on host will be ignored. |
| * |
| * @param host The string version the InetAddress |
| * |
| * @return The host converted to InetAddress instance |
| * |
| * @throws UnknownHostException if no IP address for the {@code host} could be found |
| */ |
| protected static InetAddress toInetAddressOrThrow(String host) throws UnknownHostException { |
| if (host == null || host.isEmpty()) { |
| return null; |
| } |
| |
| if (host.contains("/")) { |
| return InetAddress.getByName(host.substring(host.indexOf('/') + 1)); |
| } |
| |
| return InetAddress.getByName(host); |
| } |
| |
| /** |
| * Validates the host by making sure it can successfully be used to get an instance of |
| * InetAddress. Any leading slashes on host will be ignored. If the host string is null or empty |
| * then null is returned. |
| * |
| * @param host The string version the InetAddress |
| * |
| * @return The host converted to InetAddress instance |
| * |
| * @throws UnknownHostException if no IP address for the {@code host} could be found |
| */ |
| protected static String validateHostOrThrow(String host) throws UnknownHostException { |
| if (host == null || host.isEmpty()) { |
| return null; |
| } |
| |
| InetAddress.getByName(trimLeadingSlash(host)); |
| return host; |
| } |
| |
| /** |
| * Returns an {@code InetAddress} representing the local host. The checked exception |
| * {@code UnknownHostException} is captured and an AssertionError is generated instead. |
| * |
| * @return The InetAddress instance representing the local host |
| * |
| * @throws AssertionError If conversion of host results in {@code UnknownHostException} |
| */ |
| private static InetAddress getLocalHost() { |
| try { |
| return SocketCreator.getLocalHost(); |
| } catch (UnknownHostException e) { |
| throw new AssertionError("Failed to get local host", e); |
| } |
| } |
| } |