diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 15a36a4..eadc634 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,14 +24,20 @@ jobs: target: x86_64-pc-windows-msvc artifact_name: ostp.exe release_name: ostp-windows-amd64.zip + tun2socks_arch: windows-amd64 + wintun_arch: amd64 - os: windows-latest target: i686-pc-windows-msvc artifact_name: ostp.exe release_name: ostp-windows-386.zip + tun2socks_arch: windows-386 + wintun_arch: x86 - os: windows-latest target: aarch64-pc-windows-msvc artifact_name: ostp.exe release_name: ostp-windows-arm64.zip + tun2socks_arch: windows-arm64 + wintun_arch: arm64 # ========================================== # 🍏 APPLE DARWIN (macOS) @@ -40,10 +46,12 @@ jobs: target: x86_64-apple-darwin artifact_name: ostp release_name: ostp-darwin-amd64.tar.gz + tun2socks_arch: darwin-amd64 - os: macos-latest target: aarch64-apple-darwin artifact_name: ostp release_name: ostp-darwin-arm64.tar.gz + tun2socks_arch: darwin-arm64 # ========================================== # 🐧 LINUX & FreeBSD STANDARD @@ -52,24 +60,29 @@ jobs: target: x86_64-unknown-linux-musl artifact_name: ostp release_name: ostp-linux-amd64.tar.gz + tun2socks_arch: linux-amd64 - os: ubuntu-latest target: i686-unknown-linux-musl artifact_name: ostp release_name: ostp-linux-386.tar.gz + tun2socks_arch: linux-386 - os: ubuntu-latest target: aarch64-unknown-linux-musl artifact_name: ostp release_name: ostp-linux-arm64.tar.gz + tun2socks_arch: linux-arm64 use_cross: true - os: ubuntu-latest target: armv7-unknown-linux-musleabihf artifact_name: ostp release_name: ostp-linux-armv7.tar.gz + tun2socks_arch: linux-armv7 use_cross: true - os: ubuntu-latest target: x86_64-unknown-freebsd artifact_name: ostp release_name: ostp-freebsd-amd64.tar.gz + tun2socks_arch: freebsd-amd64 use_cross: true # ========================================== @@ -79,12 +92,14 @@ jobs: target: mipsel-unknown-linux-musl artifact_name: ostp release_name: ostp-linux-mipsle.tar.gz + tun2socks_arch: linux-mipsle use_cross: true toolchain: nightly - os: ubuntu-latest target: riscv64gc-unknown-linux-gnu artifact_name: ostp release_name: ostp-linux-riscv64.tar.gz + tun2socks_arch: linux-riscv64 use_cross: true # ========================================== @@ -94,6 +109,7 @@ jobs: target: aarch64-linux-android artifact_name: ostp release_name: ostp-android-arm64.tar.gz + tun2socks_arch: android-arm64 use_cross: true steps: @@ -137,18 +153,63 @@ jobs: cargo install cross --git https://github.com/cross-rs/cross.git cross build --release --target ${{ matrix.target }} --bin ostp + - name: Inject Win32 Driver Dependencies (Windows) + if: ${{ matrix.os == 'windows-latest' && matrix.tun2socks_arch }} + shell: pwsh + run: | + cd target/${{ matrix.target }}/release + $ProgressPreference = 'SilentlyContinue' + # 1. Acquire tun2socks + Invoke-WebRequest -Uri "https://github.com/xjasonlyu/tun2socks/releases/download/v2.6.0/tun2socks-${{ matrix.tun2socks_arch }}.zip" -OutFile "tun2socks.zip" + Expand-Archive -Path "tun2socks.zip" -DestinationPath "tun_temp" -Force + Get-ChildItem -Path "tun_temp" -Filter "*.exe" -Recurse | Copy-Item -Destination "." -Force + # 2. Acquire wintun + Invoke-WebRequest -Uri "https://www.wintun.net/builds/wintun-0.14.1.zip" -OutFile "wintun.zip" + Expand-Archive -Path "wintun.zip" -DestinationPath "wintun_temp" -Force + Get-ChildItem -Path "wintun_temp" -Filter "wintun.dll" -Recurse | Where-Object { $_.FullName -match 'bin[\\/]${{ matrix.wintun_arch }}[\\/]' } | Copy-Item -Destination "." -Force + # Cleanup + Remove-Item "tun2socks.zip", "tun_temp", "wintun.zip", "wintun_temp" -Recurse -Force + + - name: Inject Unix Driver Dependencies (Unix) + if: ${{ matrix.os != 'windows-latest' && matrix.tun2socks_arch }} + shell: bash + run: | + cd target/${{ matrix.target }}/release + # Fetch using correct extension (Linux = .tar.gz, Darwin/FreeBSD = .zip) + if [[ "${{ matrix.tun2socks_arch }}" == *"linux"* ]]; then + URL="https://github.com/xjasonlyu/tun2socks/releases/download/v2.6.0/tun2socks-${{ matrix.tun2socks_arch }}.tar.gz" + curl -L "$URL" -o "tun2socks.tar.gz" + tar -xzf "tun2socks.tar.gz" + find . -maxdepth 2 -name "tun2socks*" ! -name "*.tar.gz" -type f -exec mv {} ./tun2socks \; + rm -f "tun2socks.tar.gz" + else + URL="https://github.com/xjasonlyu/tun2socks/releases/download/v2.6.0/tun2socks-${{ matrix.tun2socks_arch }}.zip" + curl -L "$URL" -o "tun2socks.zip" + unzip -o "tun2socks.zip" + find . -maxdepth 2 -name "tun2socks*" ! -name "*.zip" -type f -exec mv {} ./tun2socks \; + rm -f "tun2socks.zip" + fi + chmod +x tun2socks || true + - name: Package release artifact (Windows) if: ${{ matrix.os == 'windows-latest' }} shell: pwsh run: | cd target/${{ matrix.target }}/release - Compress-Archive -Path ${{ matrix.artifact_name }} -DestinationPath ../../../${{ matrix.release_name }} + $files = @("${{ matrix.artifact_name }}") + if (Test-Path "tun2socks.exe") { $files += "tun2socks.exe" } + if (Test-Path "wintun.dll") { $files += "wintun.dll" } + Compress-Archive -Path $files -DestinationPath ../../../${{ matrix.release_name }} - name: Package release artifact (Unix Systems) if: ${{ matrix.os != 'windows-latest' }} run: | cd target/${{ matrix.target }}/release - tar -czf ../../../${{ matrix.release_name }} ${{ matrix.artifact_name }} + FILES="${{ matrix.artifact_name }}" + if [ -f "tun2socks" ]; then + FILES="$FILES tun2socks" + fi + tar -czf ../../../${{ matrix.release_name }} $FILES - name: Inject artifact to Global GitHub Release Assets if: ${{ startsWith(github.ref, 'refs/tags/') }} diff --git a/Cargo.lock b/Cargo.lock index f7421dd..34c2dae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -476,7 +476,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "ostp" -version = "0.1.26" +version = "0.1.31" dependencies = [ "anyhow", "base64", @@ -491,7 +491,7 @@ dependencies = [ [[package]] name = "ostp-client" -version = "0.1.26" +version = "0.1.31" dependencies = [ "anyhow", "bytes", @@ -506,7 +506,7 @@ dependencies = [ [[package]] name = "ostp-core" -version = "0.1.26" +version = "0.1.31" dependencies = [ "anyhow", "async-trait", @@ -538,7 +538,7 @@ dependencies = [ [[package]] name = "ostp-server" -version = "0.1.26" +version = "0.1.31" dependencies = [ "anyhow", "bytes", diff --git a/ostp-client/src/runner.rs b/ostp-client/src/runner.rs index 3957e9f..eae3c23 100644 --- a/ostp-client/src/runner.rs +++ b/ostp-client/src/runner.rs @@ -116,10 +116,6 @@ pub async fn run_client(config: crate::config::ClientConfig) -> Result<()> { println!("[ostp-client] WARNING: process exclusions are not supported in the current TUN implementation"); } - if config.mode == "tun" { - tunnel::download_wintun_dll(config.debug)?; - tunnel::download_tun2socks(config.debug)?; - } let (proxy_events_tx, proxy_events_rx) = mpsc::channel(10000); let (client_msgs_tx, client_msgs_rx) = mpsc::channel(10000); diff --git a/ostp-client/src/tunnel/linux_handler.rs b/ostp-client/src/tunnel/linux_handler.rs index 98822d4..837c8cd 100644 --- a/ostp-client/src/tunnel/linux_handler.rs +++ b/ostp-client/src/tunnel/linux_handler.rs @@ -18,9 +18,6 @@ pub async fn run_linux_tunnel( println!("[ostp-client] Starting Linux TUN handler initialization..."); } - // 1. Automatically ensure tun2socks binary is downloaded and present - super::download_tun2socks(debug)?; - let exe = std::env::current_exe()?; let dir = exe.parent().ok_or_else(|| anyhow!("failed to get binary directory"))?; diff --git a/ostp-client/src/tunnel/mod.rs b/ostp-client/src/tunnel/mod.rs index 1467da5..83ffe97 100644 --- a/ostp-client/src/tunnel/mod.rs +++ b/ostp-client/src/tunnel/mod.rs @@ -1,11 +1,7 @@ mod proxy; -mod wintun_downloader; mod wintun_handler; mod linux_handler; -pub use wintun_downloader::download_wintun_dll; -pub use wintun_downloader::download_tun2socks; - pub async fn run_tun_tunnel( config: crate::config::ClientConfig, shutdown: watch::Receiver, diff --git a/ostp-client/src/tunnel/wintun_downloader.rs b/ostp-client/src/tunnel/wintun_downloader.rs deleted file mode 100644 index 740e566..0000000 --- a/ostp-client/src/tunnel/wintun_downloader.rs +++ /dev/null @@ -1,168 +0,0 @@ -#![allow(unused_imports)] -use anyhow::Result; -#[cfg(target_os = "windows")] -use anyhow::anyhow; -use std::path::PathBuf; - -#[cfg(target_os = "windows")] -pub fn download_wintun_dll(debug: bool) -> Result<()> { - let exe = std::env::current_exe()?; - let dir = exe.parent().ok_or_else(|| anyhow!("failed to get binary directory"))?; - let dll_path = dir.join("wintun.dll"); - - if !dll_path.exists() { - if debug { - println!("[ostp-client] wintun.dll not found. Downloading automatically..."); - } - - // Correctly map compilation target architecture to Wintun zip layout folder structure - let arch = if cfg!(target_arch = "x86_64") { - "amd64" - } else if cfg!(target_arch = "aarch64") { - "arm64" - } else if cfg!(target_arch = "arm") { - "arm" - } else { - "x86" - }; - - let zip_path = dir.join("wintun.zip").to_string_lossy().replace('\\', "/"); - let temp_path = dir.join("wintun_temp").to_string_lossy().replace('\\', "/"); - let dll_dest = dll_path.to_string_lossy().replace('\\', "/"); - - // Explicitly filter via Where-Object to select ONLY the single architecture matching dll. - // This guarantees we never overwrite the correct x64 dll with x86/ARM formats during Expand-Archive recursions. - let ps_script = format!( - "$ProgressPreference = 'SilentlyContinue'; \ - Invoke-WebRequest -Uri 'https://www.wintun.net/builds/wintun-0.14.1.zip' -OutFile '{}' -UseBasicParsing -ErrorAction Stop; \ - Expand-Archive -Path '{}' -DestinationPath '{}' -Force; \ - Get-ChildItem -Path '{}' -Filter 'wintun.dll' -Recurse | Where-Object {{ $_.FullName -match 'bin[\\\\/]{}[\\\\/]' }} | Copy-Item -Destination '{}' -Force; \ - Remove-Item '{}', '{}' -Recurse -Force", - zip_path, zip_path, temp_path, temp_path, arch, dll_dest, zip_path, temp_path - ); - - let output = std::process::Command::new("powershell") - .args(["-Command", &ps_script]) - .current_dir(dir) - .output()?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - return Err(anyhow!("Failed to download and extract wintun.dll for architecture {}: {}", arch, stderr)); - } - if debug { - println!("[ostp-client] wintun.dll ({}) successfully downloaded and registered!", arch); - } - } - Ok(()) -} - -#[cfg(not(target_os = "windows"))] -pub fn download_wintun_dll(_debug: bool) -> Result<()> { - Ok(()) -} - -#[cfg(target_os = "windows")] -pub fn download_tun2socks(debug: bool) -> Result<()> { - let exe = std::env::current_exe()?; - let dir = exe.parent().ok_or_else(|| anyhow!("failed to get binary directory"))?; - let tun2socks_path = dir.join("tun2socks.exe"); - - if !tun2socks_path.exists() { - if debug { - println!("[ostp-client] tun2socks.exe not found. Downloading automatically..."); - } - - let arch = if cfg!(target_arch = "x86_64") { - "amd64" - } else if cfg!(target_arch = "aarch64") { - "arm64" - } else if cfg!(target_arch = "arm") { - "arm" - } else { - "386" - }; - - let zip_path = dir.join("tun2socks.zip").to_string_lossy().replace('\\', "/"); - let temp_path = dir.join("tun2socks_temp").to_string_lossy().replace('\\', "/"); - let dest_path = tun2socks_path.to_string_lossy().replace('\\', "/"); - - let url = format!("https://github.com/xjasonlyu/tun2socks/releases/download/v2.6.0/tun2socks-windows-{}.zip", arch); - - let ps_script = format!( - "$ProgressPreference = 'SilentlyContinue'; \ - Invoke-WebRequest -Uri '{}' -OutFile '{}' -UseBasicParsing -ErrorAction Stop; \ - Expand-Archive -Path '{}' -DestinationPath '{}' -Force; \ - Get-ChildItem -Path '{}' -Filter '*.exe' -Recurse | Copy-Item -Destination '{}' -Force; \ - Remove-Item '{}', '{}' -Recurse -Force", - url, zip_path, zip_path, temp_path, temp_path, dest_path, zip_path, temp_path - ); - - let output = std::process::Command::new("powershell") - .args(["-Command", &ps_script]) - .current_dir(dir) - .output()?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - return Err(anyhow!("Failed to download tun2socks.exe: {}", stderr)); - } - if debug { - println!("[ostp-client] tun2socks.exe ({}) downloaded and installed successfully!", arch); - } - } - Ok(()) -} - -#[cfg(target_os = "linux")] -pub fn download_tun2socks(debug: bool) -> Result<()> { - let exe = std::env::current_exe()?; - let dir = exe.parent().ok_or_else(|| anyhow::anyhow!("failed to get binary directory"))?; - let tun2socks_path = dir.join("tun2socks"); - - if !tun2socks_path.exists() { - if debug { - println!("[ostp-client] tun2socks not found. Downloading automatically for Linux..."); - } - - let arch = if cfg!(target_arch = "x86_64") { - "amd64" - } else if cfg!(target_arch = "aarch64") { - "arm64" - } else if cfg!(target_arch = "arm") { - "arm" - } else { - "386" - }; - - let tar_path = dir.join("tun2socks.tar.gz").to_string_lossy().into_owned(); - let dest_path = tun2socks_path.to_string_lossy().into_owned(); - let url = format!("https://github.com/xjasonlyu/tun2socks/releases/download/v2.6.0/tun2socks-linux-{}.tar.gz", arch); - - let sh_script = format!( - "curl -L -o '{}' '{}' && tar -xzf '{}' -C '{}' --wildcards '*/tun2socks' --strip-components=1 || tar -xzf '{}' -C '{}' tun2socks; \ - chmod +x '{}'; \ - rm -f '{}'", - tar_path, url, tar_path, dir.to_string_lossy(), tar_path, dir.to_string_lossy(), dest_path, tar_path - ); - - let output = std::process::Command::new("sh") - .args(["-c", &sh_script]) - .current_dir(dir) - .output()?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - return Err(anyhow::anyhow!("Failed to download tun2socks for Linux: {}", stderr)); - } - if debug { - println!("[ostp-client] tun2socks ({}) downloaded and installed successfully!", arch); - } - } - Ok(()) -} - -#[cfg(not(any(target_os = "windows", target_os = "linux")))] -pub fn download_tun2socks(_debug: bool) -> Result<()> { - Err(anyhow::anyhow!("Operating system unsupported, text an issue at github.")) -} diff --git a/ostp-client/src/tunnel/wintun_handler.rs b/ostp-client/src/tunnel/wintun_handler.rs index 8c8a510..577287c 100644 --- a/ostp-client/src/tunnel/wintun_handler.rs +++ b/ostp-client/src/tunnel/wintun_handler.rs @@ -15,16 +15,12 @@ pub async fn run_wintun_tunnel( println!("[ostp-client] Initializing high-performance TUN tunnel via tun2socks..."); } - // 1. Automatically ensure Wintun and tun2socks dependencies are downloaded and present - super::download_wintun_dll(debug)?; - super::download_tun2socks(debug)?; - let exe = std::env::current_exe()?; let dir = exe.parent().ok_or_else(|| anyhow!("failed to get binary directory"))?; let tun2socks_exe = dir.join("tun2socks.exe"); if !tun2socks_exe.exists() { - return Err(anyhow!("tun2socks.exe not found! Even after download attempt, binary remains missing.")); + return Err(anyhow!("tun2socks.exe not found in current directory! Please make sure the pre-packaged dependency is present near the executable.")); } // 2. Resolve Server IP for routing table exclusion