Skip to content

Commit

Permalink
Consider about improvement of get IP address inaccurate (#1039)
Browse files Browse the repository at this point in the history
  • Loading branch information
Technoboy- committed Jul 15, 2020
1 parent 6ebe356 commit 569d34e
Showing 1 changed file with 81 additions and 23 deletions.
Expand Up @@ -20,11 +20,16 @@
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.net.Inet6Address;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
* IP address utility.
Expand All @@ -34,6 +39,8 @@ public final class IpUtils {

public static final String IP_REGEX = "((\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)){3})";

public static final String PREFERRED_NETWORK_INTERFACE = "elasticjob.preferred.network.interface";

private static volatile String cachedIpAddress;

/**
Expand All @@ -45,42 +52,93 @@ public static String getIp() {
if (null != cachedIpAddress) {
return cachedIpAddress;
}
Enumeration<NetworkInterface> netInterfaces;
NetworkInterface networkInterface = findNetworkInterface();
if (null != networkInterface) {
Enumeration<InetAddress> ipAddresses = networkInterface.getInetAddresses();
while (ipAddresses.hasMoreElements()) {
InetAddress ipAddress = ipAddresses.nextElement();
if (isValidAddress(ipAddress)) {
cachedIpAddress = ipAddress.getHostAddress();
return cachedIpAddress;
}
}
}
return null;
}

private static NetworkInterface findNetworkInterface() {
Enumeration<NetworkInterface> interfaces;
try {
netInterfaces = NetworkInterface.getNetworkInterfaces();
interfaces = NetworkInterface.getNetworkInterfaces();
} catch (final SocketException ex) {
throw new HostException(ex);
}
String localIpAddress = null;
while (netInterfaces.hasMoreElements()) {
NetworkInterface netInterface = netInterfaces.nextElement();
Enumeration<InetAddress> ipAddresses = netInterface.getInetAddresses();
while (ipAddresses.hasMoreElements()) {
InetAddress ipAddress = ipAddresses.nextElement();
if (isPublicIpAddress(ipAddress)) {
String publicIpAddress = ipAddress.getHostAddress();
cachedIpAddress = publicIpAddress;
return publicIpAddress;
}
if (isLocalIpAddress(ipAddress)) {
localIpAddress = ipAddress.getHostAddress();
List<NetworkInterface> validNetworkInterfaces = new LinkedList<>();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = interfaces.nextElement();
if (ignoreNetworkInterface(networkInterface)) {
continue;
}
validNetworkInterfaces.add(networkInterface);
}
NetworkInterface result = null;
for (NetworkInterface each : validNetworkInterfaces) {
if (isPreferredNetworkInterface(each)) {
result = each;
break;
}
}
if (null == result) {
result = getFirstNetworkInterface(validNetworkInterfaces);
}
return result;
}

private static NetworkInterface getFirstNetworkInterface(final List<NetworkInterface> validNetworkInterfaces) {
NetworkInterface result = null;
for (NetworkInterface each : validNetworkInterfaces) {
Enumeration<InetAddress> addresses = each.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress inetAddress = addresses.nextElement();
if (isValidAddress(inetAddress)) {
result = each;
break;
}
}
}
cachedIpAddress = localIpAddress;
return localIpAddress;
if (null == result && !validNetworkInterfaces.isEmpty()) {
result = validNetworkInterfaces.get(0);
}
return result;
}

private static boolean isPublicIpAddress(final InetAddress ipAddress) {
return !ipAddress.isSiteLocalAddress() && !ipAddress.isLoopbackAddress() && !isV6IpAddress(ipAddress);
private static boolean isPreferredNetworkInterface(final NetworkInterface networkInterface) {
String preferredNetworkInterface = System.getProperty(PREFERRED_NETWORK_INTERFACE);
return Objects.equals(networkInterface.getDisplayName(), preferredNetworkInterface);
}

private static boolean isLocalIpAddress(final InetAddress ipAddress) {
return ipAddress.isSiteLocalAddress() && !ipAddress.isLoopbackAddress() && !isV6IpAddress(ipAddress);
private static boolean ignoreNetworkInterface(final NetworkInterface networkInterface) {
try {
return null == networkInterface
|| networkInterface.isLoopback()
|| networkInterface.isVirtual()
|| !networkInterface.isUp();
} catch (final SocketException ex) {
return true;
}
}

private static boolean isValidAddress(final InetAddress inetAddress) {
try {
return !inetAddress.isLoopbackAddress() && !inetAddress.isAnyLocalAddress()
&& !isIp6Address(inetAddress) && inetAddress.isReachable(100);
} catch (final IOException ex) {
return false;
}
}

private static boolean isV6IpAddress(final InetAddress ipAddress) {
return ipAddress.getHostAddress().contains(":");
private static boolean isIp6Address(final InetAddress ipAddress) {
return ipAddress instanceof Inet6Address;
}

/**
Expand Down

0 comments on commit 569d34e

Please sign in to comment.