Peach VPN v4.0版本的 MD5 值为:44c7a87caba90fec9b7945dd44651111

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


package dev.dev7.lib.v2ray.services;

import android.app.Service;
import android.content.Intent;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.net.VpnService;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import dev.dev7.lib.v2ray.core.V2rayCoreManager;
import dev.dev7.lib.v2ray.interfaces.V2rayServicesListener;
import dev.dev7.lib.v2ray.utils.AppConfigs;
import dev.dev7.lib.v2ray.utils.V2rayConfig;
import java.io.File;
import java.io.FileDescriptor;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;

public class V2rayVPNService extends VpnService implements V2rayServicesListener {
    private boolean isRunning = true;
    private ParcelFileDescriptor mInterface;
    private Process process;
    private V2rayConfig v2rayConfig;

    public static void lambda$sendFileDescriptor$2(String str, FileDescriptor fileDescriptor) {
        int i = 0;
        while (true) {
            try {
                Thread.sleep(i * 50);
                LocalSocket localSocket = new LocalSocket();
                localSocket.connect(new LocalSocketAddress(str, LocalSocketAddress.Namespace.FILESYSTEM));
                if (localSocket.isConnected()) {
                    Log.e("SOCK_FILE", "connected to sock file [" + str + "]");
                } else {
                    Log.e("SOCK_FILE", "Unable to connect to localSocksFile [" + str + "]");
                }
                OutputStream outputStream = localSocket.getOutputStream();
                localSocket.setFileDescriptorsForSend(new FileDescriptor[]{fileDescriptor});
                outputStream.write(32);
                localSocket.setFileDescriptorsForSend(null);
                localSocket.shutdownOutput();
                localSocket.close();
                return;
            } catch (Exception e) {
                Log.e("V2rayVPNService", "sendFd failed =>", e);
                if (i > 5) {
                    return;
                } else {
                    i++;
                }
            }
        }
    }

    private void runTun2socks() {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(new ArrayList(Arrays.asList(new File(getApplicationInfo().nativeLibraryDir, "libtun2socks.so").getAbsolutePath(), "--netif-ipaddr", "26.26.26.2", "--netif-netmask", "255.255.255.252", "--socks-server-addr", "127.0.0.1:" + this.v2rayConfig.LOCAL_SOCKS5_PORT, "--tunmtu", "1500", "--sock-path", "sock_path", "--enable-udprelay", "--loglevel", "error")));
            processBuilder.redirectErrorStream(true);
            this.process = processBuilder.directory(getApplicationContext().getFilesDir()).start();
            new Thread(new Runnable() {
                @Override
                public final void run() {
                    V2rayVPNService.this.m72x4f97e9ff();
                }
            }, "Tun2socks_Thread").start();
            sendFileDescriptor();
        } catch (Exception unused) {
            onDestroy();
        }
    }

    private void sendFileDescriptor() {
        final String absolutePath = new File(getApplicationContext().getFilesDir(), "sock_path").getAbsolutePath();
        final FileDescriptor fileDescriptor = this.mInterface.getFileDescriptor();
        new Thread(new Runnable() {
            @Override
            public final void run() {
                V2rayVPNService.lambda$sendFileDescriptor$2(absolutePath, fileDescriptor);
            }
        }, "sendFd_Thread").start();
    }

    private void setup() {
        if (prepare(this) != null) {
            return;
        }
        VpnService.Builder builder = new VpnService.Builder(this);
        builder.setSession(this.v2rayConfig.REMARK);
        builder.setMtu(ConnectionResult.DRIVE_EXTERNAL_STORAGE_REQUIRED);
        builder.addAddress("26.26.26.1", 30);
        builder.addRoute("0.0.0.0", 0);
        builder.addDnsServer("1.1.1.1");
        builder.addDnsServer("8.8.4.4");
        if (this.v2rayConfig.BLOCKED_APPS != null) {
            for (int i = 0; i < this.v2rayConfig.BLOCKED_APPS.size(); i++) {
                try {
                    builder.addDisallowedApplication(this.v2rayConfig.BLOCKED_APPS.get(i));
                } catch (Exception unused) {
                }
            }
        }
        try {
            this.mInterface.close();
        } catch (Exception unused2) {
        }
        if (Build.VERSION.SDK_INT >= 29) {
            builder.setMetered(false);
        }
        try {
            this.mInterface = builder.establish();
            this.isRunning = true;
            runTun2socks();
        } catch (Exception unused3) {
            stopAllProcess();
        }
    }

    private void stopAllProcess() {
        stopForeground(true);
        this.isRunning = false;
        Process process = this.process;
        if (process != null) {
            process.destroy();
        }
        V2rayCoreManager.getInstance().stopCore();
        try {
            stopSelf();
        } catch (Exception unused) {
        }
        try {
            this.mInterface.close();
        } catch (Exception unused2) {
        }
    }

    @Override
    public Service getService() {
        return this;
    }

    public void m71xd8d46647() {
        Intent intent = new Intent("CONNECTED_V2RAY_SERVER_DELAY");
        intent.putExtra("DELAY", String.valueOf(V2rayCoreManager.getInstance().getConnectedV2rayServerDelay()));
        sendBroadcast(intent);
    }

    public void m72x4f97e9ff() {
        try {
            this.process.waitFor();
            if (this.isRunning) {
                runTun2socks();
            }
        } catch (InterruptedException unused) {
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        V2rayCoreManager.getInstance().setUpListener(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public boolean onProtect(int i) {
        return protect(i);
    }

    @Override
    public void onRevoke() {
        stopAllProcess();
    }

    @Override
    public int onStartCommand(Intent intent, int i, int i2) {
        AppConfigs.V2RAY_SERVICE_COMMANDS v2ray_service_commands = (AppConfigs.V2RAY_SERVICE_COMMANDS) intent.getSerializableExtra("COMMAND");
        if (!v2ray_service_commands.equals(AppConfigs.V2RAY_SERVICE_COMMANDS.START_SERVICE)) {
            if (v2ray_service_commands.equals(AppConfigs.V2RAY_SERVICE_COMMANDS.STOP_SERVICE)) {
                V2rayCoreManager.getInstance().stopCore();
                return 1;
            }
            if (v2ray_service_commands.equals(AppConfigs.V2RAY_SERVICE_COMMANDS.MEASURE_DELAY)) {
                new Thread(new Runnable() {
                    @Override
                    public final void run() {
                        V2rayVPNService.this.m71xd8d46647();
                    }
                }, "MEASURE_CONNECTED_V2RAY_SERVER_DELAY").start();
                return 1;
            }
            onDestroy();
            return 1;
        }
        V2rayConfig v2rayConfig = (V2rayConfig) intent.getSerializableExtra("V2RAY_CONFIG");
        this.v2rayConfig = v2rayConfig;
        if (v2rayConfig == null) {
            onDestroy();
        }
        if (V2rayCoreManager.getInstance().isV2rayCoreRunning()) {
            V2rayCoreManager.getInstance().stopCore();
        }
        if (V2rayCoreManager.getInstance().startCore(this.v2rayConfig)) {
            Log.e("V2rayProxyOnlyService", "onStartCommand success => v2ray core started.");
            return 1;
        }
        onDestroy();
        return 1;
    }

    @Override
    public void startService() {
        setup();
    }

    @Override
    public void stopService() {
        stopAllProcess();
    }
}