§A.3: remove dead tun2socks code (native OSTP TUN is the only path)

The "system" TUN stack that shelled out to a bundled tun2socks binary is
long-dead — Flutter already hardcodes the native OSTP stack — and only
bloats the build.

- ostp-jni: drop the tun2socks spawn branch and the tun_child handle;
  the native TUN (run_native_tunnel_from_fd) is now unconditional. The
  JNI signature is kept ABI-stable (t2sBinPath/localProxy retained but
  ignored) to avoid breaking the Kotlin linkage without an Android build.
- Delete the committed 10 MB tun2socks-arm64 asset; drop the tun2socks
  download steps from the Android build scripts.
- Remove the dead tun2socks.exe entry from the desktop build_dist.js
  (it required a file nothing downloads, breaking the GUI dist build).
- Reword stale tun2socks references in proxy.rs, the GUI config comment,
  install.ps1, the release workflow matrix, and CONTRIBUTING.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ospab 2026-06-27 16:29:55 +03:00
parent 92d6b06d75
commit 7704e0bdb1
10 changed files with 18 additions and 128 deletions

View File

@ -444,7 +444,6 @@ jobs:
- arch: armeabi-v7a - arch: armeabi-v7a
rust_target: armv7-linux-androideabi rust_target: armv7-linux-androideabi
flutter_target: android-arm flutter_target: android-arm
tun2socks_arch: linux-armv7
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@ -58,7 +58,7 @@ To build and test OSTP locally, you will need:
The repository is organized as a Cargo workspace containing the following crates: The repository is organized as a Cargo workspace containing the following crates:
* [`ostp-core/`](file:///d:/ospab-projects/ostp/ostp-core): Core protocol logic, including packet formatting, serialization, selective ACK/NACK (ARQ) state machine, and the Noise protocol (`Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s`) handshake. * [`ostp-core/`](file:///d:/ospab-projects/ostp/ostp-core): Core protocol logic, including packet formatting, serialization, selective ACK/NACK (ARQ) state machine, and the Noise protocol (`Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s`) handshake.
* [`ostp-client/`](file:///d:/ospab-projects/ostp/ostp-client): Client implementations, including SOCKS5/HTTP local proxies, `tun2socks` integration, native TUN interface routing, and split-tunneling bypass mechanisms. * [`ostp-client/`](file:///d:/ospab-projects/ostp/ostp-client): Client implementations, including SOCKS5/HTTP local proxies, the native OSTP TUN interface routing, and split-tunneling bypass mechanisms.
* [`ostp-server/`](file:///d:/ospab-projects/ostp/ostp-server): Server logic, session dispatcher, anti-probing fallback server proxying, access key database, and the REST API for control panel communication. * [`ostp-server/`](file:///d:/ospab-projects/ostp/ostp-server): Server logic, session dispatcher, anti-probing fallback server proxying, access key database, and the REST API for control panel communication.
* [`ostp-control/`](file:///d:/ospab-projects/ostp/ostp-control): A modern web dashboard for server administration (user management, real-time metrics, bandwidth limits). * [`ostp-control/`](file:///d:/ospab-projects/ostp/ostp-control): A modern web dashboard for server administration (user management, real-time metrics, bandwidth limits).
* [`ostp-gui/`](file:///d:/ospab-projects/ostp/ostp-gui): Tauri-based desktop GUI application for Windows and Linux. * [`ostp-gui/`](file:///d:/ospab-projects/ostp/ostp-gui): Tauri-based desktop GUI application for Windows and Linux.

View File

@ -58,7 +58,7 @@
Репозиторий представляет собой единый Cargo-workspace со следующими компонентами: Репозиторий представляет собой единый Cargo-workspace со следующими компонентами:
* [`ostp-core/`](file:///d:/ospab-projects/ostp/ostp-core): Базовая логика протокола: форматирование пакетов, сериализация, конечный автомат выборочного подтверждения (ARQ/ACK/NACK) и рукопожатие Noise (`Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s`). * [`ostp-core/`](file:///d:/ospab-projects/ostp/ostp-core): Базовая логика протокола: форматирование пакетов, сериализация, конечный автомат выборочного подтверждения (ARQ/ACK/NACK) и рукопожатие Noise (`Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s`).
* [`ostp-client/`](file:///d:/ospab-projects/ostp/ostp-client): Клиентская часть: локальные SOCKS5/HTTP прокси-серверы, интеграция с драйвером `wintun` / `tun2socks` и реализация раздельного туннелирования для прямого обхода трафика. * [`ostp-client/`](file:///d:/ospab-projects/ostp/ostp-client): Клиентская часть: локальные SOCKS5/HTTP прокси-серверы, нативный OSTP TUN-интерфейс (через драйвер `wintun`) и реализация раздельного туннелирования для прямого обхода трафика.
* [`ostp-server/`](file:///d:/ospab-projects/ostp/ostp-server): Серверная часть: диспетчеризация сессий, маскировка под классические веб-серверы при активном сканировании, база данных ключей доступа и REST API панели управления. * [`ostp-server/`](file:///d:/ospab-projects/ostp/ostp-server): Серверная часть: диспетчеризация сессий, маскировка под классические веб-серверы при активном сканировании, база данных ключей доступа и REST API панели управления.
* [`ostp-control/`](file:///d:/ospab-projects/ostp/ostp-control): Панель администратора (пользователи, статистика трафика в реальном времени, лимиты скорости и объема данных). * [`ostp-control/`](file:///d:/ospab-projects/ostp/ostp-control): Панель администратора (пользователи, статистика трафика в реальном времени, лимиты скорости и объема данных).
* [`ostp-gui/`](file:///d:/ospab-projects/ostp/ostp-gui): Настольное приложение-клиент для Windows и Linux на платформе Tauri. * [`ostp-gui/`](file:///d:/ospab-projects/ostp/ostp-gui): Настольное приложение-клиент для Windows и Linux на платформе Tauri.

View File

@ -208,10 +208,7 @@ pub async fn run_local_socks5_proxy(
.await .await
.with_context(|| format!("failed to bind local HTTP/SOCKS5 proxy at {}", cfg.bind_addr))?; .with_context(|| format!("failed to bind local HTTP/SOCKS5 proxy at {}", cfg.bind_addr))?;
if true { tracing::info!("local HTTP/SOCKS5 proxy listening at {}", cfg.bind_addr);
tracing::info!("local HTTP/SOCKS5 proxy listening at {}", cfg.bind_addr);
tracing::info!("Windows system proxy: set HTTP proxy to {}. tun2socks: SOCKS5 on same address.", cfg.bind_addr);
}
let physical_if_index = tokio::task::spawn_blocking(get_windows_physical_if_index).await.unwrap_or(None); let physical_if_index = tokio::task::spawn_blocking(get_windows_physical_if_index).await.unwrap_or(None);
let physical_if_name = tokio::task::spawn_blocking(get_linux_physical_if_name).await.unwrap_or(None); let physical_if_name = tokio::task::spawn_blocking(get_linux_physical_if_name).await.unwrap_or(None);

View File

@ -4,9 +4,9 @@ Write-Host "==============================================" -ForegroundColor Cya
Write-Host " OSTP Android App Release Build Pipeline " -ForegroundColor Cyan Write-Host " OSTP Android App Release Build Pipeline " -ForegroundColor Cyan
Write-Host "==============================================" -ForegroundColor Cyan Write-Host "==============================================" -ForegroundColor Cyan
# Step 1: Run JNI build script to compile Rust core and download tun2socks # Step 1: Run JNI build script to compile the Rust core into Android .so libs
Write-Host "" Write-Host ""
Write-Host "[1/3] Compiling Rust JNI Core & Downloading tun2socks..." -ForegroundColor Yellow Write-Host "[1/3] Compiling Rust JNI Core..." -ForegroundColor Yellow
$jniScript = Join-Path $PSScriptRoot "build_android_jni.ps1" $jniScript = Join-Path $PSScriptRoot "build_android_jni.ps1"
if (Test-Path $jniScript) { if (Test-Path $jniScript) {
& $jniScript & $jniScript

View File

@ -11,24 +11,8 @@ Push-Location "$PSScriptRoot\..\ostp-jni"
Write-Host "Compiling for aarch64-linux-android and armv7-linux-androideabi..." Write-Host "Compiling for aarch64-linux-android and armv7-linux-androideabi..."
cargo ndk -t arm64-v8a -t armeabi-v7a -o "$jniLibs" build --release cargo ndk -t arm64-v8a -t armeabi-v7a -o "$jniLibs" build --release
$tun2socksArm64 = "$jniLibs\arm64-v8a\libtun2socks.so" # tun2socks removed in 0.4.0 — the native OSTP TUN stack is the only path,
$tun2socksArmv7 = "$jniLibs\armeabi-v7a\libtun2socks.so" # so no external tun2socks binary is downloaded or bundled.
if (-not (Test-Path $tun2socksArm64)) {
Write-Host "Downloading tun2socks for arm64-v8a..."
Invoke-WebRequest -Uri "https://github.com/xjasonlyu/tun2socks/releases/download/v2.6.0/tun2socks-linux-arm64.zip" -OutFile "$jniLibs\t2s64.zip"
Expand-Archive "$jniLibs\t2s64.zip" "$jniLibs\t2s64_tmp" -Force
Copy-Item "$jniLibs\t2s64_tmp\tun2socks-linux-arm64" $tun2socksArm64 -Force
Remove-Item "$jniLibs\t2s64.zip", "$jniLibs\t2s64_tmp" -Recurse -Force
}
if (-not (Test-Path $tun2socksArmv7)) {
Write-Host "Downloading tun2socks for armeabi-v7a..."
Invoke-WebRequest -Uri "https://github.com/xjasonlyu/tun2socks/releases/download/v2.6.0/tun2socks-linux-armv7.zip" -OutFile "$jniLibs\t2s32.zip"
Expand-Archive "$jniLibs\t2s32.zip" "$jniLibs\t2s32_tmp" -Force
Copy-Item "$jniLibs\t2s32_tmp\tun2socks-linux-armv7" $tun2socksArmv7 -Force
Remove-Item "$jniLibs\t2s32.zip", "$jniLibs\t2s32_tmp" -Recurse -Force
}
Pop-Location Pop-Location

View File

@ -21,10 +21,6 @@ const filesToCopy = [
src: path.join(workspaceRoot, 'target', 'release', 'ostp-tun-helper.exe'), src: path.join(workspaceRoot, 'target', 'release', 'ostp-tun-helper.exe'),
dest: path.join(distDir, 'ostp-tun-helper.exe') dest: path.join(distDir, 'ostp-tun-helper.exe')
}, },
{
src: path.join(workspaceRoot, 't2s_tmp', 'tun2socks-windows-amd64.exe'),
dest: path.join(distDir, 'tun2socks.exe')
},
{ {
src: path.join(workspaceRoot, 'target', 'release', 'wintun.dll'), src: path.join(workspaceRoot, 'target', 'release', 'wintun.dll'),
dest: path.join(distDir, 'wintun.dll') dest: path.join(distDir, 'wintun.dll')

View File

@ -64,7 +64,6 @@ struct SdkState {
runtime: Option<Runtime>, runtime: Option<Runtime>,
shutdown_tx: Option<watch::Sender<bool>>, shutdown_tx: Option<watch::Sender<bool>>,
metrics: Option<Arc<BridgeMetrics>>, metrics: Option<Arc<BridgeMetrics>>,
tun_child: Option<std::process::Child>,
cmd_tx: Option<mpsc::Sender<BridgeCommand>>, cmd_tx: Option<mpsc::Sender<BridgeCommand>>,
} }
@ -74,7 +73,6 @@ impl SdkState {
runtime: None, runtime: None,
shutdown_tx: None, shutdown_tx: None,
metrics: None, metrics: None,
tun_child: None,
cmd_tx: None, cmd_tx: None,
} }
} }
@ -100,8 +98,10 @@ pub extern "system" fn Java_net_ostp_client_OstpClientSdk_nativeStartClient(
_class: JClass, _class: JClass,
config_json: JString, config_json: JString,
fd: jni::sys::jint, fd: jni::sys::jint,
t2s_bin_path: JString, // tun2socks ("system" TUN stack) removed in 0.4.0 — native OSTP TUN is the only path.
local_proxy: JString, // These two args are retained to keep the JNI signature ABI-stable with Kotlin; unused.
_t2s_bin_path: JString,
_local_proxy: JString,
) -> jboolean { ) -> jboolean {
let mut state = match STATE.write() { let mut state = match STATE.write() {
Ok(s) => s, Ok(s) => s,
@ -160,16 +160,6 @@ pub extern "system" fn Java_net_ostp_client_OstpClientSdk_nativeStartClient(
Err(_) => return jni::sys::JNI_FALSE, Err(_) => return jni::sys::JNI_FALSE,
}; };
let t2s_path: String = match env.get_string(&t2s_bin_path) {
Ok(s) => s.into(),
Err(_) => return jni::sys::JNI_FALSE,
};
let proxy_addr: String = match env.get_string(&local_proxy) {
Ok(s) => s.into(),
Err(_) => return jni::sys::JNI_FALSE,
};
// Parse config from JSON // Parse config from JSON
let config: ClientConfig = match serde_json::from_str(&config_str) { let config: ClientConfig = match serde_json::from_str(&config_str) {
Ok(cfg) => cfg, Ok(cfg) => cfg,
@ -256,81 +246,11 @@ pub extern "system" fn Java_net_ostp_client_OstpClientSdk_nativeStartClient(
let _ = cmd_tx_clone.send(BridgeCommand::ToggleTunnel).await; let _ = cmd_tx_clone.send(BridgeCommand::ToggleTunnel).await;
}); });
if config.tun_stack == "system" { // Native OSTP TUN stack is the only path (tun2socks "system" stack removed in 0.4.0).
// Spawn tun2socks if debug {
let fd_str = format!("fd://{}", fd); add_log("Using OSTP native TUN stack.".to_string());
let proxy_str = format!("socks5://{}", proxy_addr);
if debug {
add_log(format!("Spawning tun2socks: {} -device {} -proxy {}", t2s_path, fd_str, proxy_str));
}
let mut cmd = std::process::Command::new(&t2s_path);
cmd.arg("-device")
.arg(&fd_str)
.arg("-proxy")
.arg(&proxy_str);
if config.ostp.mtu > 0 {
cmd.arg("-mtu").arg(config.ostp.mtu.to_string());
} }
{
cmd.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped());
let mut child = match cmd.spawn() {
Ok(c) => c,
Err(e) => {
add_log(format!("Failed to spawn tun2socks from Rust: {e}"));
return jni::sys::JNI_FALSE;
}
};
let stdout = match child.stdout.take() {
Some(s) => s,
None => {
add_log("Failed to capture tun2socks stdout".to_string());
return jni::sys::JNI_FALSE;
}
};
let stderr = match child.stderr.take() {
Some(s) => s,
None => {
add_log("Failed to capture tun2socks stderr".to_string());
return jni::sys::JNI_FALSE;
}
};
// Read stdout
std::thread::spawn(move || {
use std::io::{BufRead, BufReader};
let reader = BufReader::new(stdout);
for line in reader.lines() {
if let Ok(l) = line {
if debug {
add_log(format!("tun2socks: {}", l));
}
}
}
});
// Read stderr & wait
std::thread::spawn(move || {
use std::io::{BufRead, BufReader};
let reader = BufReader::new(stderr);
for line in reader.lines() {
if let Ok(l) = line {
if debug {
add_log(format!("tun2socks ERROR: {}", l));
}
}
}
});
state.tun_child = Some(child);
} else {
if debug {
add_log("Using OSTP native TUN stack. Bypassing tun2socks.".to_string());
}
let shutdown_rx_clone = shutdown_tx.subscribe(); let shutdown_rx_clone = shutdown_tx.subscribe();
let config_clone = config.clone(); let config_clone = config.clone();
let (exclusions_tx, exclusions_rx) = tokio::sync::watch::channel(config.exclusions.clone()); let (exclusions_tx, exclusions_rx) = tokio::sync::watch::channel(config.exclusions.clone());
@ -368,24 +288,18 @@ pub extern "system" fn Java_net_ostp_client_OstpClientSdk_nativeStopClient(
_env: JNIEnv, _env: JNIEnv,
_class: JClass, _class: JClass,
) -> jboolean { ) -> jboolean {
let (tun_child, shutdown_tx, runtime) = { let (shutdown_tx, runtime) = {
let mut state = match STATE.write() { let mut state = match STATE.write() {
Ok(s) => s, Ok(s) => s,
Err(_) => return jni::sys::JNI_FALSE, Err(_) => return jni::sys::JNI_FALSE,
}; };
let c = state.tun_child.take();
let s = state.shutdown_tx.take(); let s = state.shutdown_tx.take();
let r = state.runtime.take(); let r = state.runtime.take();
state.cmd_tx = None; state.cmd_tx = None;
state.metrics = None; state.metrics = None;
(c, s, r) (s, r)
}; };
if let Some(mut child) = tun_child {
let _ = child.kill();
add_log("Killed tun2socks process".to_string());
}
if let Some(s) = shutdown_tx { if let Some(s) = shutdown_tx {
let _ = s.send(true); let _ = s.send(true);
} }

View File

@ -87,7 +87,7 @@ Expand-Archive -Path $zipPath -DestinationPath $extractPath -Force
$extractedFiles = Get-ChildItem -Path $extractPath -File -Recurse $extractedFiles = Get-ChildItem -Path $extractPath -File -Recurse
if ($extractedFiles.Count -gt 0) { if ($extractedFiles.Count -gt 0) {
Write-Host "Stopping active instances..." Write-Host "Stopping active instances..."
Stop-Process -Name "ostp", "tun2socks" -Force -ErrorAction SilentlyContinue Stop-Process -Name "ostp", "ostp-gui", "ostp-tun-helper" -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
foreach ($file in $extractedFiles) { foreach ($file in $extractedFiles) {