This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere-elasticjob.git


The following commit(s) were added to refs/heads/master by this push:
     new 4635a5d  Consider about improvement of get IP address inaccurate 
(#1039) (#1069)
4635a5d is described below

commit 4635a5dda4bca7f6eec6c145316f8afbbf99a545
Author: Tboy <[email protected]>
AuthorDate: Thu Jul 16 10:21:47 2020 +0800

    Consider about improvement of get IP address inaccurate (#1039) (#1069)
---
 .../elasticjob/infra/env/HostException.java        |   4 +
 .../elasticjob/infra/env/IpUtils.java              | 104 ++++++++++++++++-----
 2 files changed, 85 insertions(+), 23 deletions(-)

diff --git 
a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/env/HostException.java
 
b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/env/HostException.java
index 5737135..785318b 100644
--- 
a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/env/HostException.java
+++ 
b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/env/HostException.java
@@ -29,4 +29,8 @@ public final class HostException extends RuntimeException {
     public HostException(final IOException cause) {
         super(cause);
     }
+    
+    public HostException(final String message) {
+        super(message);
+    }
 }
diff --git 
a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/env/IpUtils.java
 
b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/env/IpUtils.java
index a104ef5..f27a7f6 100644
--- 
a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/env/IpUtils.java
+++ 
b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/env/IpUtils.java
@@ -20,11 +20,16 @@ package org.apache.shardingsphere.elasticjob.infra.env;
 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.
@@ -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})";
     
+    private static final String PREFERRED_NETWORK_INTERFACE = 
"elasticjob.preferred.network.interface";
+    
     private static volatile String cachedIpAddress;
     
     /**
@@ -45,42 +52,93 @@ public final class IpUtils {
         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;
+                }
+            }
+        }
+        throw new HostException("ip is 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;
     }
     
     /**

Reply via email to