Net Flex v版本的 MD5 值为:385c18cd288a0634841c2be4c516c1dd

以下内容为反编译后的 VpnUtils.java 源代码,内容仅作参考


package com.romzkie.ultrasshservice.tunnel.vpn;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.os.Build;
import com.romzkie.ultrasshservice.logger.SkStatus;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
public class VpnUtils {
    private static final String DEFAULT_PRIMARY_DNS_SERVER = "8.8.4.4";
    private static final String DEFAULT_SECONDARY_DNS_SERVER = "8.8.8.8";
    private static final Pattern IPV4_PATTERN = Pattern.compile("^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
    private static final Pattern IPV6_STD_PATTERN = Pattern.compile("^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
    private static final Pattern IPV6_HEX_COMPRESSED_PATTERN = Pattern.compile("^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$");

    public static int findProcessId(String str) throws IOException {
        String[] strArr = {"ps -ef", "ps -A", TunnelConstants.SHELL_CMD_PS};
        int i = 0;
        while (i < 3) {
            Process exec = Runtime.getRuntime().exec(strArr[i]);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
            while (true) {
                String readLine = bufferedReader.readLine();
                if (readLine != null) {
                    if (!readLine.contains("PID") && readLine.contains(str)) {
                        String[] split = readLine.split("\\s+");
                        try {
                            try {
                                int parseInt = Integer.parseInt(split[1]);
                                try {
                                    exec.destroy();
                                } catch (Exception unused) {
                                }
                                return parseInt;
                            } catch (NumberFormatException unused2) {
                                int parseInt2 = Integer.parseInt(split[0]);
                                try {
                                    exec.destroy();
                                } catch (Exception unused3) {
                                }
                                return parseInt2;
                            }
                        } catch (Throwable th) {
                            try {
                                exec.destroy();
                            } catch (Exception unused4) {
                            }
                            throw th;
                        }
                    }
                }
            }
        }
        return -1;
    }

    public static void killProcess(File file) throws Exception {
        killProcess(file, "-9");
    }

    public static int killProcess(File file, String str) throws Exception {
        int i = 0;
        do {
            int findProcessId = findProcessId(file.getName());
            if (findProcessId == -1) {
                return findProcessId;
            }
            i++;
            String valueOf = String.valueOf(findProcessId);
            String[] strArr = {"", "busybox ", "toolbox "};
            for (int i2 = 0; i2 < 3; i2++) {
                try {
                    Runtime runtime = Runtime.getRuntime();
                    runtime.exec(strArr[i2] + "killall " + str + " " + file.getName());
                } catch (IOException unused) {
                }
                try {
                    Runtime runtime2 = Runtime.getRuntime();
                    runtime2.exec(strArr[i2] + "killall " + str + " " + file.getCanonicalPath());
                } catch (IOException unused2) {
                }
            }
            killProcess(valueOf, str);
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException unused3) {
            }
        } while (i <= 4);
        throw new Exception("Cannot kill: " + file.getAbsolutePath());
    }

    public static void killProcess(String str, String str2) throws Exception {
        String[] strArr = {"", "toolbox ", "busybox "};
        for (int i = 0; i < 3; i++) {
            try {
                Runtime runtime = Runtime.getRuntime();
                runtime.exec(strArr[i] + "kill " + str2 + " " + str);
            } catch (IOException e) {
                SkStatus.logDebug(String.format("error killing process: %s, %s", str, e.getMessage()));
            }
        }
    }

    public static List<String> getActiveNetworkDnsResolver(Context context) throws Exception {
        Collection<InetAddress> activeNetworkDnsResolvers = getActiveNetworkDnsResolvers(context);
        if (!activeNetworkDnsResolvers.isEmpty()) {
            ArrayList arrayList = new ArrayList();
            int i = 2;
            for (InetAddress inetAddress : activeNetworkDnsResolvers) {
                String obj = inetAddress.toString();
                if (obj.startsWith("/")) {
                    obj = obj.substring(1);
                }
                if (!obj.contains(":")) {
                    arrayList.add(obj);
                    i--;
                    if (i <= 0) {
                        break;
                    }
                }
            }
            return arrayList;
        }
        throw new Exception("no active network DNS resolver");
    }

    private static Collection<InetAddress> getActiveNetworkDnsResolvers(Context context) throws Exception {
        ArrayList arrayList = new ArrayList();
        try {
            Class<?> cls = Class.forName("android.net.LinkProperties");
            Object invoke = ConnectivityManager.class.getMethod("getActiveLinkProperties", new Class[0]).invoke((ConnectivityManager) context.getSystemService("connectivity"), new Object[0]);
            if (invoke != null) {
                if (Build.VERSION.SDK_INT < 21) {
                    for (InetAddress inetAddress : (Collection) cls.getMethod("getDnses", new Class[0]).invoke(invoke, new Object[0])) {
                        arrayList.add(inetAddress);
                    }
                } else {
                    for (InetAddress inetAddress2 : ((LinkProperties) invoke).getDnsServers()) {
                        arrayList.add(inetAddress2);
                    }
                }
            }
            return arrayList;
        } catch (ClassNotFoundException e) {
            throw new Exception("getActiveNetworkDnsResolvers failed", e);
        } catch (IllegalAccessException e2) {
            throw new Exception("getActiveNetworkDnsResolvers failed", e2);
        } catch (IllegalArgumentException e3) {
            throw new Exception("getActiveNetworkDnsResolvers failed", e3);
        } catch (NoSuchMethodException e4) {
            throw new Exception("getActiveNetworkDnsResolvers failed", e4);
        } catch (NullPointerException e5) {
            throw new Exception("getActiveNetworkDnsResolvers failed", e5);
        } catch (InvocationTargetException e6) {
            throw new Exception("getActiveNetworkDnsResolvers failed", e6);
        }
    }

    public static List<String> getNetworkDnsServer(Context context) {
        ArrayList arrayList = new ArrayList();
        try {
            return getActiveNetworkDnsResolver(context);
        } catch (Exception unused) {
            arrayList.add(DEFAULT_PRIMARY_DNS_SERVER);
            arrayList.add(DEFAULT_SECONDARY_DNS_SERVER);
            return arrayList;
        }
    }

    public static boolean isIPv4Address(String str) {
        return IPV4_PATTERN.matcher(str).matches();
    }

    public static boolean isIPv6StdAddress(String str) {
        return IPV6_STD_PATTERN.matcher(str).matches();
    }

    public static boolean isIPv6HexCompressedAddress(String str) {
        return IPV6_HEX_COMPRESSED_PATTERN.matcher(str).matches();
    }

    public static boolean isIPv6Address(String str) {
        return isIPv6StdAddress(str) || isIPv6HexCompressedAddress(str);
    }

    public static class PrivateAddress {
        public final String mIpAddress;
        public final int mPrefixLength;
        public final String mRouter;
        public final String mSubnet;

        public PrivateAddress(String str, String str2, int i, String str3) {
            this.mIpAddress = str;
            this.mSubnet = str2;
            this.mPrefixLength = i;
            this.mRouter = str3;
        }
    }

    public static PrivateAddress selectPrivateAddress() throws Exception {
        HashMap hashMap = new HashMap();
        hashMap.put("10", new PrivateAddress("10.0.0.1", "10.0.0.0", 8, "10.0.0.2"));
        hashMap.put("172", new PrivateAddress("172.16.0.1", "172.16.0.0", 12, "172.16.0.2"));
        hashMap.put("192", new PrivateAddress("192.168.0.1", "192.168.0.0", 16, "192.168.0.2"));
        hashMap.put("169", new PrivateAddress("169.254.1.1", "169.254.1.0", 24, "169.254.1.2"));
        try {
            for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
                Iterator it = Collections.list(networkInterface.getInetAddresses()).iterator();
                while (it.hasNext()) {
                    InetAddress inetAddress = (InetAddress) it.next();
                    if (!inetAddress.isLoopbackAddress() && (inetAddress instanceof Inet4Address)) {
                        String hostAddress = inetAddress.getHostAddress();
                        if (hostAddress.startsWith("10.")) {
                            hashMap.remove("10");
                        } else if (hostAddress.length() >= 6 && hostAddress.substring(0, 6).compareTo("172.16") >= 0 && hostAddress.substring(0, 6).compareTo("172.31") <= 0) {
                            hashMap.remove("172");
                        } else if (hostAddress.startsWith("192.168")) {
                            hashMap.remove("192");
                        }
                    }
                }
            }
            if (hashMap.size() > 0) {
                return (PrivateAddress) hashMap.values().iterator().next();
            }
            throw new Exception("no private address available");
        } catch (SocketException e) {
            e.printStackTrace();
            throw new Exception("selectPrivateAddress failed", e);
        }
    }

    private static boolean isPortAvailable(int i) {
        Socket socket = new Socket();
        try {
            try {
                socket.connect(new InetSocketAddress("127.0.0.1", i), 1000);
                try {
                    socket.close();
                } catch (IOException unused) {
                }
                return false;
            } catch (IOException unused2) {
                return false;
            }
        } catch (SocketTimeoutException unused3) {
            socket.close();
            return false;
        } catch (IOException unused4) {
            try {
                socket.close();
            } catch (IOException unused5) {
            }
            return true;
        } catch (Throwable th) {
            try {
                socket.close();
            } catch (IOException unused6) {
            }
            throw th;
        }
    }

    public static int findAvailablePort(int i, int i2) {
        for (int i3 = i; i3 < i + i2; i3++) {
            if (isPortAvailable(i3)) {
                return i3;
            }
        }
        return 0;
    }
}