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();
}
}