diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c019e67..c55361d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -137,6 +137,13 @@ jobs: if: ${{ matrix.os == 'ubuntu-latest' && !matrix.use_cross }} run: sudo apt-get update && sudo apt-get install -y musl-tools + - name: Pre-flight compilation check + if: ${{ !matrix.use_cross }} + shell: bash + run: | + cargo check --target ${{ matrix.target }} --bin ostp 2>&1 + echo "Pre-flight check passed." + - name: Execute Standard Native Compilation (Windows) if: ${{ !matrix.use_cross && matrix.os == 'windows-latest' }} run: | diff --git a/Cargo.lock b/Cargo.lock index 6f8a9ec..c2d6098 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -745,7 +745,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "ostp" -version = "0.1.60" +version = "0.1.61" dependencies = [ "anyhow", "base64", @@ -762,7 +762,7 @@ dependencies = [ [[package]] name = "ostp-client" -version = "0.1.60" +version = "0.1.61" dependencies = [ "anyhow", "bytes", @@ -780,7 +780,7 @@ dependencies = [ [[package]] name = "ostp-core" -version = "0.1.60" +version = "0.1.61" dependencies = [ "anyhow", "async-trait", @@ -813,7 +813,7 @@ dependencies = [ [[package]] name = "ostp-server" -version = "0.1.60" +version = "0.1.61" dependencies = [ "anyhow", "bytes", @@ -828,7 +828,7 @@ dependencies = [ [[package]] name = "ostp-tun-helper" -version = "0.1.60" +version = "0.1.61" dependencies = [ "anyhow", "chrono", diff --git a/scripts/build.ps1 b/scripts/build.ps1 index c2dacee..db169b5 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -1,22 +1,23 @@ -# OSTP High-Performance Cross-Platform Build & Release Pipeline +# OSTP Build & Release Pipeline +# Usage: +# .\scripts\build.ps1 Build locally + trigger CI/CD +# .\scripts\build.ps1 -TriggerOnly Skip local builds, trigger CI/CD only +# .\scripts\build.ps1 -Check Run cargo check only (no build, no release) + param( - [switch]$Flatten, # Consolidate raw uncompressed binaries with arch suffixes under dist/release/ - [switch]$TriggerOnly # Bypasses all local builds to instantly execute global cloud CI/CD tag injection + [switch]$Flatten, + [switch]$TriggerOnly, + [switch]$Check ) $ProjectRoot = Split-Path -Parent $PSScriptRoot Push-Location $ProjectRoot -Write-Output "Synchronizing latest workspace source code from origin master..." -# Leverage autostash and rebase to pull cleanly even with uncommitted local edits +# --- Sync --- +Write-Output "Synchronizing with origin master..." & git pull origin master --rebase --autostash | Out-Null -Write-Output "Starting Universal OSTP Build & Release Pipeline in $ProjectRoot" - -# Unblock binaries by terminating any existing active instances -Stop-Process -Name ostp -ErrorAction SilentlyContinue | Out-Null - -# 1. Read and automatically bump version inside Cargo.toml PRIOR to compilation +# --- Version bump --- $CargoToml = Join-Path $ProjectRoot "Cargo.toml" $Version = "0.1.0" if (Test-Path $CargoToml) { @@ -30,195 +31,205 @@ if (Test-Path $CargoToml) { $NewVersionStr = 'version = "' + $Version + '"' $NewContent = $Content -replace 'version\s*=\s*"\d+\.\d+\.\d+"', $NewVersionStr [System.IO.File]::WriteAllText($CargoToml, $NewContent) - Write-Output "[OK] Bounded workspace package to target release version: v$Version" + Write-Output "[ok] Version: v$Version" } } -$DistDir = Join-Path $ProjectRoot "dist" -$StagingDir = Join-Path $DistDir "staging" +# --- Pre-flight: cargo check --- +Write-Output "" +Write-Output "Running pre-flight cargo check..." +$checkOutput = & cargo check 2>&1 | Out-String +$checkErrors = $checkOutput | Select-String "^error\[" -CaseSensitive -# Wipe legacy artifacts to prepare a clean clean slate -if (Test-Path $DistDir) { Remove-Item -Path $DistDir -Recurse -Force -ErrorAction SilentlyContinue } -New-Item -ItemType Directory -Force -Path $DistDir | Out-Null - -# Collection for dynamically mapping successful build archives -$ReleaseArchives = @() - -# --------------------------------------------------------------------- -# CONDITIONAL BUILD SUITE execution -# --------------------------------------------------------------------- -if (-not $TriggerOnly) { - -# --------------------------------------------------------------------- -# PHASE 1: WINDOWS COMPILATION MATRIX (Native Host) -# --------------------------------------------------------------------- -$WindowsTargets = @( - @{ Target = "x86_64-pc-windows-msvc"; Arch = "x64"; BinaryName = "ostp.exe" } -) - -Write-Output "=========================================================" -Write-Output " PHASE 1: Compiling Windows Architectures" -Write-Output "=========================================================" -$TempWinTargetDir = Join-Path $env:TEMP "ostp_target_win" - -foreach ($item in $WindowsTargets) { - $target = $item.Target - $arch = $item.Arch - $bin = $item.BinaryName - - Write-Output "--> Compiling target: Windows $arch [$target]..." - - # Attempt setup of the rust toolchain for this architecture - & rustup target add $target 2>&1 | Out-Null - - $env:CARGO_TARGET_DIR = $TempWinTargetDir - & cargo build --release --target $target --bin ostp - - if ($LASTEXITCODE -eq 0) { - $compiledBin = Join-Path $TempWinTargetDir "$target\release\$bin" - if (Test-Path $compiledBin) { - $archiveName = "ostp-v$Version-windows-$arch.zip" - $targetStaging = Join-Path $StagingDir "windows-$arch" - New-Item -ItemType Directory -Force -Path $targetStaging | Out-Null - - # Stage and package binary natively - Copy-Item -Path $compiledBin -Destination $targetStaging -Force - - $archivePath = Join-Path $DistDir $archiveName - Compress-Archive -Path "$targetStaging\*" -DestinationPath $archivePath -Force - - $ReleaseArchives += $archivePath - Write-Output "[OK] SUCCESSFULLY PACKAGED: $archiveName" - - if ($Flatten) { - $RawReleaseDir = Join-Path $DistDir "release" - New-Item -ItemType Directory -Force -Path $RawReleaseDir | Out-Null - $FlatName = "ostp-windows-$arch.exe" - Copy-Item -Path $compiledBin -Destination (Join-Path $RawReleaseDir $FlatName) -Force - Write-Output " -> Flat copied: dist/release/$FlatName" - } - } - } else { - Write-Output "[WARN] FAILED compiling Windows $arch ($target). Missing local platform C++ toolchain components." - } -} -# Restore environment variables -Remove-Item Env:\CARGO_TARGET_DIR -ErrorAction SilentlyContinue | Out-Null - -# --------------------------------------------------------------------- -# PHASE 2: LINUX CROSS-COMPILATION MATRIX (via WSL + rust-lld) -# --------------------------------------------------------------------- -Write-Output "`n=========================================================" -Write-Output " PHASE 2: Compiling Linux Architectures via WSL" -Write-Output "=========================================================" - -if (Get-Command wsl -ErrorAction SilentlyContinue) { - # Anchor output cache on Windows disk to survive WSL instance cycling - $LinuxBuildDir = Join-Path $ProjectRoot "target_linux" - New-Item -ItemType Directory -Force -Path $LinuxBuildDir | Out-Null - $LinuxBuildUnix = $LinuxBuildDir.Replace("\", "/") - $WslBuildDir = & wsl wslpath -u $LinuxBuildUnix - - $LinuxTargets = @( - @{ Target = "x86_64-unknown-linux-musl"; Arch = "x64"; BinaryName = "ostp" } - ) - - foreach ($item in $LinuxTargets) { - $target = $item.Target - $arch = $item.Arch - $bin = $item.BinaryName - - $osPrefix = "linux" - if ($target -match "freebsd") { $osPrefix = "freebsd" } - - Write-Output "--> Compiling target: $osPrefix $arch [$target] via rust-lld..." - - & wsl rustup target add $target 2>&1 | Out-Null - - # Invoke Cargo cross-compiling via toolless rust-lld LLVM backend for Musl targets! - & wsl env RUSTFLAGS="-C linker=rust-lld" CARGO_TARGET_DIR=$WslBuildDir cargo build --release --target $target --bin ostp - - if ($LASTEXITCODE -eq 0) { - $compiledBin = Join-Path $LinuxBuildDir "$target\release\$bin" - if (Test-Path $compiledBin) { - $archiveName = "ostp-v$Version-$osPrefix-$arch.tar.gz" - $targetStaging = Join-Path $StagingDir "$osPrefix-$arch" - New-Item -ItemType Directory -Force -Path $targetStaging | Out-Null - - Copy-Item -Path $compiledBin -Destination $targetStaging -Force - - # Translate staging paths to Linux formats for WSL tar archiving - $wslStagingDir = & wsl wslpath -u ($targetStaging.Replace("\", "/")) - $wslArchiveFile = & wsl wslpath -u ((Join-Path $DistDir $archiveName).Replace("\", "/")) - - # Generate clean compressed tarball natively via WSL tar engine - & wsl tar -czf $wslArchiveFile -C $wslStagingDir $bin - - $ReleaseArchives += Join-Path $DistDir $archiveName - Write-Output "[OK] SUCCESSFULLY PACKAGED: $archiveName" - - if ($Flatten) { - $RawReleaseDir = Join-Path $DistDir "release" - New-Item -ItemType Directory -Force -Path $RawReleaseDir | Out-Null - $FlatName = "ostp-$osPrefix-$arch" - Copy-Item -Path $compiledBin -Destination (Join-Path $RawReleaseDir $FlatName) -Force - Write-Output " -> Flat copied: dist/release/$FlatName" - } - } - } else { - Write-Output "[WARN] FAILED compiling Linux $arch ($target)." - } - } -} else { - Write-Output "[WARN] WSL utility not discovered on host. Skipping Linux binary compilations." -} - -# Dissolve staging buffer directory -if (Test-Path $StagingDir) { Remove-Item -Path $StagingDir -Recurse -Force -ErrorAction SilentlyContinue } - -Write-Output "`n=========================================================" -Write-Output " RELEASE ARTIFACTS SUMMARY" -Write-Output "=========================================================" -if ($ReleaseArchives.Count -gt 0) { - $ReleaseArchives | ForEach-Object { Write-Output " [+] $_" } -} else { - Write-Output "[ERROR] CRITICAL: No architectures compiled successfully." +if ($checkErrors) { + Write-Output "" + Write-Output "[error] Compilation check failed. Fix errors before releasing:" + Write-Output $checkOutput + # Revert version bump + [System.IO.File]::WriteAllText($CargoToml, $Content) Pop-Location exit 1 } +# Show warnings if any +$checkWarnings = $checkOutput | Select-String "^warning:" -CaseSensitive +if ($checkWarnings) { + Write-Output "[warn] Compiler warnings detected (non-blocking):" + $checkWarnings | ForEach-Object { Write-Output " $_" } } else { - Write-Output "`n--> [TRIGGER ONLY MODE] Bypassing all local compilations as requested." + Write-Output "[ok] No errors or warnings." } -# --------------------------------------------------------------------- -# PHASE 3: TRIGGER GLOBAL CI/CD RELEASE PIPELINE (Via Git Tag) -# --------------------------------------------------------------------- -Write-Output "`n=========================================================" -Write-Output " PHASE 3: Launching Unified Global Cloud Release" -Write-Output "=========================================================" +if ($Check) { + Write-Output "" + Write-Output "Check-only mode. Exiting without build or release." + # Revert version bump + [System.IO.File]::WriteAllText($CargoToml, $Content) + Pop-Location + exit 0 +} -Write-Output "Synchronizing workspace version metadata to origin master..." -# Commit current Cargo.toml bump to establish version lineage -& git add Cargo.toml +Write-Output "" +Write-Output "Starting build pipeline for v$Version" + +# Kill existing instances +Stop-Process -Name ostp -ErrorAction SilentlyContinue | Out-Null + +$DistDir = Join-Path $ProjectRoot "dist" +$StagingDir = Join-Path $DistDir "staging" + +if (Test-Path $DistDir) { Remove-Item -Path $DistDir -Recurse -Force -ErrorAction SilentlyContinue } +New-Item -ItemType Directory -Force -Path $DistDir | Out-Null + +$ReleaseArchives = @() + +# --- Conditional local build --- +if (-not $TriggerOnly) { + + # Phase 1: Windows + $WindowsTargets = @( + @{ Target = "x86_64-pc-windows-msvc"; Arch = "x64"; BinaryName = "ostp.exe" } + ) + + Write-Output "" + Write-Output "--- Phase 1: Windows compilation ---" + $TempWinTargetDir = Join-Path $env:TEMP "ostp_target_win" + + foreach ($item in $WindowsTargets) { + $target = $item.Target + $arch = $item.Arch + $bin = $item.BinaryName + + Write-Output " Compiling: Windows $arch ($target)" + & rustup target add $target 2>&1 | Out-Null + + $env:CARGO_TARGET_DIR = $TempWinTargetDir + & cargo build --release --target $target --bin ostp + + if ($LASTEXITCODE -eq 0) { + $compiledBin = Join-Path $TempWinTargetDir "$target\release\$bin" + if (Test-Path $compiledBin) { + $archiveName = "ostp-v$Version-windows-$arch.zip" + $targetStaging = Join-Path $StagingDir "windows-$arch" + New-Item -ItemType Directory -Force -Path $targetStaging | Out-Null + Copy-Item -Path $compiledBin -Destination $targetStaging -Force + + $archivePath = Join-Path $DistDir $archiveName + Compress-Archive -Path "$targetStaging\*" -DestinationPath $archivePath -Force + $ReleaseArchives += $archivePath + Write-Output " [ok] $archiveName" + + if ($Flatten) { + $RawReleaseDir = Join-Path $DistDir "release" + New-Item -ItemType Directory -Force -Path $RawReleaseDir | Out-Null + $FlatName = "ostp-windows-$arch.exe" + Copy-Item -Path $compiledBin -Destination (Join-Path $RawReleaseDir $FlatName) -Force + Write-Output " [ok] Flat: dist/release/$FlatName" + } + } + } else { + Write-Output " [warn] Failed: Windows $arch ($target)" + } + } + Remove-Item Env:\CARGO_TARGET_DIR -ErrorAction SilentlyContinue | Out-Null + + # Phase 2: Linux via WSL + Write-Output "" + Write-Output "--- Phase 2: Linux compilation via WSL ---" + + if (Get-Command wsl -ErrorAction SilentlyContinue) { + $LinuxBuildDir = Join-Path $ProjectRoot "target_linux" + New-Item -ItemType Directory -Force -Path $LinuxBuildDir | Out-Null + $LinuxBuildUnix = $LinuxBuildDir.Replace("\", "/") + $WslBuildDir = & wsl wslpath -u $LinuxBuildUnix + + $LinuxTargets = @( + @{ Target = "x86_64-unknown-linux-musl"; Arch = "x64"; BinaryName = "ostp" } + ) + + foreach ($item in $LinuxTargets) { + $target = $item.Target + $arch = $item.Arch + $bin = $item.BinaryName + $osPrefix = "linux" + if ($target -match "freebsd") { $osPrefix = "freebsd" } + + Write-Output " Compiling: $osPrefix $arch ($target)" + & wsl rustup target add $target 2>&1 | Out-Null + & wsl env RUSTFLAGS="-C linker=rust-lld" CARGO_TARGET_DIR=$WslBuildDir cargo build --release --target $target --bin ostp + + if ($LASTEXITCODE -eq 0) { + $compiledBin = Join-Path $LinuxBuildDir "$target\release\$bin" + if (Test-Path $compiledBin) { + $archiveName = "ostp-v$Version-$osPrefix-$arch.tar.gz" + $targetStaging = Join-Path $StagingDir "$osPrefix-$arch" + New-Item -ItemType Directory -Force -Path $targetStaging | Out-Null + Copy-Item -Path $compiledBin -Destination $targetStaging -Force + + $wslStagingDir = & wsl wslpath -u ($targetStaging.Replace("\", "/")) + $wslArchiveFile = & wsl wslpath -u ((Join-Path $DistDir $archiveName).Replace("\", "/")) + & wsl tar -czf $wslArchiveFile -C $wslStagingDir $bin + + $ReleaseArchives += Join-Path $DistDir $archiveName + Write-Output " [ok] $archiveName" + + if ($Flatten) { + $RawReleaseDir = Join-Path $DistDir "release" + New-Item -ItemType Directory -Force -Path $RawReleaseDir | Out-Null + $FlatName = "ostp-$osPrefix-$arch" + Copy-Item -Path $compiledBin -Destination (Join-Path $RawReleaseDir $FlatName) -Force + Write-Output " [ok] Flat: dist/release/$FlatName" + } + } + } else { + Write-Output " [warn] Failed: $osPrefix $arch ($target)" + } + } + } else { + Write-Output " [skip] WSL not available." + } + + # Cleanup staging + if (Test-Path $StagingDir) { Remove-Item -Path $StagingDir -Recurse -Force -ErrorAction SilentlyContinue } + + Write-Output "" + Write-Output "--- Build summary ---" + if ($ReleaseArchives.Count -gt 0) { + $ReleaseArchives | ForEach-Object { Write-Output " $_" } + } else { + Write-Output "[error] No architectures compiled successfully." + Pop-Location + exit 1 + } + +} else { + Write-Output "" + Write-Output "[info] Trigger-only mode. Skipping local compilation." +} + +# --- Phase 3: CI/CD release trigger --- +Write-Output "" +Write-Output "--- Phase 3: CI/CD release ---" + +Write-Output "Pushing version metadata..." +& git add Cargo.toml Cargo.lock & git commit -m "CI/CD: release version v$Version" --allow-empty | Out-Null & git push origin master | Out-Null -Write-Output "Generating release tracking tag: v$Version" -# Purge local tracking tag if pre-existing to guarantee clean sync +Write-Output "Creating release tag: v$Version" & git tag -d "v$Version" 2>&1 | Out-Null & git tag "v$Version" -Write-Output "Deploying trigger tag to GitHub..." -# Pushing the tag forces GitHub Actions to instantly spin up the cloud builders +Write-Output "Pushing tag to GitHub..." & git push origin "v$Version" --force if ($LASTEXITCODE -eq 0) { - Write-Output "`n[OK] EXCELLENT! Release trigger successfully synchronized with Cloud runners!" - Write-Output "[INFO] GitHub Actions is now compiling all 13 architectures in parallel." - Write-Output "[INFO] Live monitoring link: https://github.com/ospab/ostp/actions" + Write-Output "" + Write-Output "[ok] Release v$Version triggered on GitHub Actions." + Write-Output " Monitor: https://github.com/ospab/ostp/actions" } else { - Write-Output "`n[ERROR] Failed to deliver release tag to remote origin." + Write-Output "" + Write-Output "[error] Failed to push release tag." } Pop-Location diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 6879272..76bd38a 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -1,27 +1,22 @@ $ErrorActionPreference = "Stop" $repo = "ospab/ostp" -# 1. Smart & Aggressive Installation Path Resolution -$InstallDir = "C:\opt\ostp" # Standard default fallback +# 1. Install path resolution +$InstallDir = "C:\opt\ostp" if (Test-Path "config.json") { - # Config is in active current directory $InstallDir = (Get-Item .).FullName } elseif (Test-Path "ostp.exe") { - # Binary is in active current directory $InstallDir = (Get-Item .).FullName } elseif ($cmd = Get-Command "ostp" -ErrorAction SilentlyContinue) { - # Binary is registered in system PATH $InstallDir = Split-Path $cmd.Path } else { - # Aggressive search in current directory tree (excluding compiler target and Git directories) - $found = Get-ChildItem -Filter "ostp.exe" -Recurse -File -ErrorAction SilentlyContinue | - Where-Object { $_.FullName -notlike "*\target\*" -and $_.FullName -notlike "*\.git\*" } | + $found = Get-ChildItem -Filter "ostp.exe" -Recurse -File -ErrorAction SilentlyContinue | + Where-Object { $_.FullName -notlike "*\target\*" -and $_.FullName -notlike "*\.git\*" } | Select-Object -First 1 if ($found) { $InstallDir = Split-Path $found.FullName } else { - # Scan parent directory as fallback $parentFound = Get-ChildItem -Path .. -Filter "ostp.exe" -File -ErrorAction SilentlyContinue | Select-Object -First 1 if ($parentFound) { $InstallDir = Split-Path $parentFound.FullName @@ -30,18 +25,18 @@ if (Test-Path "config.json") { } Write-Host "========================================================" -Write-Host " Installing Ospab Stealth Transport Protocol (OSTP)" +Write-Host " OSTP Installer" Write-Host "========================================================" -Write-Host "Target deployment location: $InstallDir" +Write-Host "Install directory: $InstallDir" -# 2. Check Write Access & Elevation Status +# 2. Access check $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not (Test-Path $InstallDir)) { try { New-Item -ItemType Directory -Path $InstallDir -ErrorAction Stop | Out-Null } catch { - Write-Error "Access Denied: Cannot create target directory '$InstallDir'. Run as Administrator." + Write-Error "Cannot create '$InstallDir'. Run as Administrator." exit 1 } } else { @@ -50,27 +45,26 @@ if (-not (Test-Path $InstallDir)) { "test" | Set-Content $testFile -ErrorAction Stop Remove-Item $testFile -Force } catch { - Write-Error "Access Denied: Directory '$InstallDir' is read-only. Run as Administrator to update." + Write-Error "Directory '$InstallDir' is read-only. Run as Administrator." exit 1 } } -# 3. Detect Architecture +# 3. Architecture detection $arch = "amd64" if ([System.Environment]::Is64BitOperatingSystem -and ($Env:PROCESSOR_ARCHITECTURE -eq "ARM64" -or $Env:PROCESSOR_ARCHITEW6432 -eq "ARM64")) { $arch = "arm64" } -# 4. Fetch Stable Version Asset (with -UseBasicParsing to prevent Internet Explorer hangs) -Write-Host "Fetching latest stable version from the repository..." +# 4. Fetch latest release +Write-Host "Fetching latest release..." try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - # Explicitly set -UseBasicParsing to guarantee execution doesn't hang on headless servers $api = Invoke-RestMethod -Uri "https://api.github.com/repos/$repo/releases/latest" -UseBasicParsing $tag = $api.tag_name } catch { - Write-Host "[Notice] Failed to retrieve tag automatically." - $tag = Read-Host "Enter release version tag manually (e.g., v0.1.23)" + Write-Host "[notice] Could not determine latest release automatically." + $tag = Read-Host "Enter release tag (e.g. v0.1.60)" if (-not $tag) { exit 1 } } @@ -79,132 +73,125 @@ $url = "https://github.com/$repo/releases/download/$tag/$archive" $zipPath = Join-Path $env:TEMP "ostp_temp_$($PID).zip" $extractPath = Join-Path $env:TEMP "ostp_extract_$($PID)" -Write-Host "Downloading asset windows-${arch}: $url ..." -# Explicitly set -UseBasicParsing to prevent any engine initialization stalls +Write-Host "Downloading: $archive ($tag)" Invoke-WebRequest -Uri $url -OutFile $zipPath -UseBasicParsing if (-not (Test-Path $zipPath)) { - Write-Error "Failed to download zip package." + Write-Error "Download failed." exit 1 } -# Overwrite and clear file locks if (Test-Path $extractPath) { Remove-Item $extractPath -Recurse -Force } Expand-Archive -Path $zipPath -DestinationPath $extractPath -Force $extractedFiles = Get-ChildItem -Path $extractPath -File -Recurse if ($extractedFiles.Count -gt 0) { - Write-Host "Stopping any active instances of ostp to unlock binary targets..." + Write-Host "Stopping active instances..." Stop-Process -Name "ostp", "tun2socks" -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 - + foreach ($file in $extractedFiles) { $destPath = Join-Path $InstallDir $file.Name if (Test-Path $destPath) { - # Rename the existing executable out of the way to bypass file locks $oldPath = $destPath + ".old_$PID" Rename-Item -Path $destPath -NewName $oldPath -ErrorAction SilentlyContinue } Copy-Item -Path $file.FullName -Destination $destPath -Force (Get-Item $destPath).LastWriteTime = [DateTime]::Now } - - # Try to clean up any leftover old files + Get-ChildItem -Path $InstallDir -Filter "*.old_*" | Remove-Item -Force -ErrorAction SilentlyContinue - - Write-Host "Executables and dependencies successfully deployed to $InstallDir." + Write-Host "Files deployed to $InstallDir." } else { - Write-Error "No files found in archive package." + Write-Error "Archive is empty." exit 1 } Remove-Item $zipPath -Force Remove-Item $extractPath -Recurse -Force -# 5. Smart Auto-Updater Mode +# 5. Update detection $configPath = Join-Path $InstallDir "config.json" if (Test-Path $configPath) { Write-Host "--------------------------------------------------------" - Write-Host "[Update] Existing configuration detected at $configPath." - Write-Host "[Update] Binary successfully hot-swapped to version $tag." + Write-Host "Existing configuration found. Binary updated to $tag." Write-Host "--------------------------------------------------------" - Write-Host "Update completed successfully!" exit 0 } -# 6. Interactive Setup +# 6. Interactive setup Write-Host "--------------------------------------------------------" -Write-Host "Select configuration mode:" -Write-Host "1) Configure Server" -Write-Host "2) Configure Client" +Write-Host "Select mode:" +Write-Host " 1) Server" +Write-Host " 2) Client" Write-Host "--------------------------------------------------------" -$mode = Read-Host "Enter choice [1-2]" +$mode = Read-Host "Choice [1-2]" Push-Location $InstallDir if ($mode -eq "1") { Write-Host "Initializing server configuration..." & .\ostp.exe --init server --config config.json - + $config = Get-Content "config.json" -Raw | ConvertFrom-Json - $listen = Read-Host "Enter IP and port to accept incoming traffic [default: 0.0.0.0:50000]" + $listen = Read-Host "Listen address [default: 0.0.0.0:50000]" if ($listen) { $config.listen = $listen } - - $keyCount = Read-Host "How many access keys to generate? [default: 1]" + + $keyCount = Read-Host "Number of access keys [default: 1]" if (-not $keyCount) { $keyCount = 1 } - + if ([int]$keyCount -gt 1) { - Write-Host "Generating additional security keys..." + Write-Host "Generating $keyCount access keys..." $keys = & .\ostp.exe -g -c $keyCount $config.access_keys = $keys -split "`r`n" | Where-Object { $_ -ne "" } } - + $config | ConvertTo-Json -Depth 10 | Set-Content "config.json" - Write-Host "Server configuration completed. Config written to $(Join-Path $InstallDir 'config.json')" + Write-Host "Server configuration saved: $(Join-Path $InstallDir 'config.json')" } elseif ($mode -eq "2") { Write-Host "Initializing client configuration..." & .\ostp.exe --init client --config config.json - + $config = Get-Content "config.json" -Raw | ConvertFrom-Json - $server = Read-Host "Enter remote server address (IP:PORT)" + $server = Read-Host "Server address (host:port)" if ($server) { $config.server = $server } - - $key = Read-Host "Enter access key (leave blank to generate automatically)" + + $key = Read-Host "Access key (blank to generate)" if (-not $key) { $key = & .\ostp.exe -g - Write-Host "Automatically generated client access key: $key" + Write-Host "Generated key: $key" } $config.access_key = $key.Trim() - $socks = Read-Host "Enter SOCKS5 listening address [default: 127.0.0.1:1088]" + $socks = Read-Host "Local proxy address [default: 127.0.0.1:1088]" if ($socks) { $config.socks5_bind = $socks } - + $config | ConvertTo-Json -Depth 10 | Set-Content "config.json" - Write-Host "Client configuration completed. Config written to $(Join-Path $InstallDir 'config.json')" + Write-Host "Client configuration saved: $(Join-Path $InstallDir 'config.json')" } else { - Write-Error "Invalid configuration choice." + Write-Error "Invalid selection." Pop-Location exit 1 } Pop-Location -# 7. Environment PATH Registration +# 7. PATH registration Write-Host "--------------------------------------------------------" -Write-Host "Registering binary route in Environment PATH..." +Write-Host "Registering in system PATH..." $targetScope = if ($isAdmin) { [EnvironmentVariableTarget]::Machine } else { [EnvironmentVariableTarget]::User } $sysPath = [Environment]::GetEnvironmentVariable("Path", $targetScope) if ($sysPath -notlike "*$InstallDir*") { $newPath = "$sysPath;$InstallDir" [Environment]::SetEnvironmentVariable("Path", $newPath, $targetScope) - Write-Host "Environment PATH updated successfully ($($targetScope.ToString()) scope)." + Write-Host "PATH updated ($($targetScope.ToString()) scope)." } else { - Write-Host "$InstallDir is already registered in PATH." + Write-Host "$InstallDir already in PATH." } Write-Host "--------------------------------------------------------" -Write-Host "Deployment completed successfully!" -Write-Host "Binary can be executed globally by typing: ostp" -Write-Host "Config location: $(Join-Path $InstallDir 'config.json')" +Write-Host "Installation complete." +Write-Host " Binary: ostp" +Write-Host " Config: $(Join-Path $InstallDir 'config.json')" Write-Host "--------------------------------------------------------" diff --git a/scripts/install.sh b/scripts/install.sh index 4120908..65c1aa5 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,45 +1,41 @@ #!/bin/bash set -e -# Official repository settings GITHUB_REPO="ospab/ostp" INSTALL_DIR="/opt/ostp" echo "========================================================" -echo " Installing Ospab Stealth Transport Protocol (OSTP)" +echo " OSTP Installer" echo "========================================================" -# Verify superuser privileges +# Verify root if [ "$EUID" -ne 0 ]; then - echo "[Error] This script must be run with root privileges (sudo)." + echo "[error] Root privileges required. Run with sudo." exit 1 fi -# Create target directory mkdir -p "$INSTALL_DIR" -# --------------------------------------------------------- -# System Architecture Detection -# --------------------------------------------------------- +# Architecture detection ARCH=$(uname -m) case "$ARCH" in x86_64) ARCH="amd64" ;; aarch64|arm64) ARCH="arm64" ;; i386|i686) ARCH="386" ;; armv7l) ARCH="armv7" ;; - *) - echo "[Warning] Unknown architecture $ARCH, falling back to amd64." + *) + echo "[warn] Unknown architecture $ARCH, defaulting to amd64." ARCH="amd64" ;; esac -# Fetch execution binary -echo "Fetching the latest stable version from the repository..." +# Fetch latest release +echo "Fetching latest release..." LATEST_RELEASE=$(curl -s "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') if [ -z "$LATEST_RELEASE" ] || [[ "$LATEST_RELEASE" == *"null"* ]]; then - echo "[Notice] Failed to automatically retrieve release tag for ${GITHUB_REPO}." - echo "Enter a direct URL to the compiled .tar.gz archive" + echo "[notice] Could not determine latest release automatically." + echo "Enter a direct URL to the .tar.gz archive," echo "or press Enter if the binary is already in $INSTALL_DIR/ostp." read -p "URL: " DIRECT_URL if [ -n "$DIRECT_URL" ]; then @@ -51,18 +47,18 @@ if [ -z "$LATEST_RELEASE" ] || [[ "$LATEST_RELEASE" == *"null"* ]]; then else ARCHIVE_NAME="ostp-linux-${ARCH}.tar.gz" DOWNLOAD_URL="https://github.com/${GITHUB_REPO}/releases/download/${LATEST_RELEASE}/${ARCHIVE_NAME}" - echo "Downloading archive for linux-$ARCH: $DOWNLOAD_URL ..." - + echo "Downloading: $ARCHIVE_NAME ($LATEST_RELEASE)" + TEMP_TAR="/tmp/ostp_temp.tar.gz" - # Fetch archive with basic error handling HTTP_CODE=$(curl -sL -w "%{http_code}" "$DOWNLOAD_URL" -o "$TEMP_TAR") - + if [ "$HTTP_CODE" -eq 200 ]; then tar -xzf "$TEMP_TAR" -C "$INSTALL_DIR" ostp rm -f "$TEMP_TAR" else - echo "[Error] Failed to download the file (HTTP status $HTTP_CODE)." - echo "Verify that the version $LATEST_RELEASE is published and fully compiled on GitHub." + echo "[error] Download failed (HTTP $HTTP_CODE)." + echo "Verify that $LATEST_RELEASE is published at:" + echo " https://github.com/$GITHUB_REPO/releases" rm -f "$TEMP_TAR" exit 1 fi @@ -70,97 +66,93 @@ fi if [ -f "$INSTALL_DIR/ostp" ]; then chmod +x "$INSTALL_DIR/ostp" - echo "Executable configured successfully at $INSTALL_DIR/ostp." + echo "Binary installed: $INSTALL_DIR/ostp" else - echo "[Error] Binary file not found in $INSTALL_DIR/ostp. Aborting setup." + echo "[error] Binary not found at $INSTALL_DIR/ostp." exit 1 fi -# --------------------------------------------------------- -# Automatic Update Detection (Preserves Settings) -# --------------------------------------------------------- +# Update detection if [ -f "$INSTALL_DIR/config.json" ]; then echo "--------------------------------------------------------" - echo "[Update] Existing configuration detected at $INSTALL_DIR/config.json." - echo "[Update] Binary successfully updated to version ${LATEST_RELEASE:-latest}." - + echo "Existing configuration found. Binary updated to ${LATEST_RELEASE:-latest}." + if systemctl is-active --quiet ostp.service 2>/dev/null; then - echo "[Update] Restarting service ostp to apply the new version..." + echo "Restarting ostp service..." systemctl restart ostp.service - echo "[Update] Service ostp restarted successfully." - else - echo "[Update] Service ostp is registered but not currently running." - echo "Start the service manually to apply changes: systemctl start ostp" + echo "Service restarted." + elif systemctl is-enabled --quiet ostp.service 2>/dev/null; then + echo "Service registered but not running." + echo "Start manually: systemctl start ostp" fi echo "--------------------------------------------------------" - echo "Update completed successfully!" + echo "Update complete." exit 0 fi -# Interactive Setup Menu +# Interactive setup echo "--------------------------------------------------------" -echo "Select configuration mode:" -echo "1) Configure Server" -echo "2) Configure Client" +echo "Select mode:" +echo " 1) Server" +echo " 2) Client" echo "--------------------------------------------------------" -read -p "Enter choice [1-2]: " NODE_MODE +read -p "Choice [1-2]: " NODE_MODE cd "$INSTALL_DIR" if [ "$NODE_MODE" == "1" ]; then echo "Initializing server configuration..." ./ostp --init server --config config.json - - read -p "Enter IP and port to accept incoming traffic [default: 0.0.0.0:50000]: " LISTEN_ADDR + + read -p "Listen address [default: 0.0.0.0:50000]: " LISTEN_ADDR if [ -n "$LISTEN_ADDR" ]; then - sed -i "s/\"listen\": \"0.0.0.0:50000\"/\"listen\": \"$LISTEN_ADDR\"/g" config.json + sed -i "s/\"listen\": \".*\"/\"listen\": \"$LISTEN_ADDR\"/g" config.json fi - - read -p "How many access keys to generate? [default: 1]: " KEYS_COUNT + + read -p "Number of access keys [default: 1]: " KEYS_COUNT KEYS_COUNT=${KEYS_COUNT:-1} - + if [ "$KEYS_COUNT" -gt 1 ]; then - echo "Generating additional security keys..." + echo "Generating $KEYS_COUNT access keys..." NEW_KEYS=$(./ostp -g -c "$KEYS_COUNT" | sed 's/^/ "/;s/$/",/' | sed '$ s/,$//') - sed -i '/"access_keys": \[/,/\]/c\ "access_keys": [\n'"$NEW_KEYS"'\n ],' config.json - echo "Successfully generated and wrote $KEYS_COUNT keys." + sed -i '/\"access_keys\": \[/,/\]/c\ "access_keys": [\n'"$NEW_KEYS"'\n ],' config.json fi - echo "Server configuration completed. Config file: $INSTALL_DIR/config.json" + echo "Server configuration saved: $INSTALL_DIR/config.json" elif [ "$NODE_MODE" == "2" ]; then echo "Initializing client configuration..." ./ostp --init client --config config.json - - read -p "Enter remote server address (IP:PORT): " REMOTE_SERVER + + read -p "Server address (host:port): " REMOTE_SERVER if [ -n "$REMOTE_SERVER" ]; then sed -i "s/\"server\": \"127.0.0.1:50000\"/\"server\": \"$REMOTE_SERVER\"/g" config.json else - echo "[Warning] No remote address provided, keeping default (127.0.0.1:50000)." + echo "[warn] No server address provided. Using default (127.0.0.1:50000)." fi - - read -p "Enter access key (leave blank to generate automatically via ostp -g): " ACCESS_KEY + + read -p "Access key (blank to generate): " ACCESS_KEY if [ -z "$ACCESS_KEY" ]; then ACCESS_KEY=$(./ostp -g) - echo "Automatically generated client key: $ACCESS_KEY" + echo "Generated key: $ACCESS_KEY" fi sed -i "s/\"access_key\": \"[^\"]*\"/\"access_key\": \"$ACCESS_KEY\"/g" config.json - read -p "Enter local SOCKS5 listening address [default: 127.0.0.1:1088]: " SOCKS_BIND + read -p "Local proxy address [default: 127.0.0.1:1088]: " SOCKS_BIND if [ -n "$SOCKS_BIND" ]; then sed -i "s/\"socks5_bind\": \"127.0.0.1:1088\"/\"socks5_bind\": \"$SOCKS_BIND\"/g" config.json fi - echo "Client configuration completed. Config file: $INSTALL_DIR/config.json" + echo "Client configuration saved: $INSTALL_DIR/config.json" else - echo "[Error] Invalid selection choice." + echo "[error] Invalid selection." exit 1 fi -# Register Systemd daemon -echo "Registering system service..." +# Register systemd service +echo "Registering systemd service..." cat < /etc/systemd/system/ostp.service [Unit] -Description=Ospab Stealth Transport Protocol Service +Description=OSTP Service After=network.target [Service] @@ -180,8 +172,7 @@ systemctl daemon-reload systemctl enable ostp.service >/dev/null 2>&1 echo "--------------------------------------------------------" -echo "Installation completed successfully." -echo "Configuration file saved at $INSTALL_DIR/config.json" -echo "Service 'ostp' has been registered but not started." -echo "Start the service manually using: systemctl start ostp" +echo "Installation complete." +echo " Config: $INSTALL_DIR/config.json" +echo " Start: systemctl start ostp" echo "--------------------------------------------------------" diff --git a/scripts/test_linux.sh b/scripts/test_linux.sh index 106dab7..bd93cc2 100644 --- a/scripts/test_linux.sh +++ b/scripts/test_linux.sh @@ -76,7 +76,7 @@ if [ ! -z "$EXT_SERVER" ]; then echo -e "2. Awaiting Cryptographic Handshake (Noise_NNpsk0)..." HANDSHAKE_OK=0 for i in {1..10}; do - if grep -q "Bridge connection established" cli.log; then + if grep -q "Connection established" cli.log; then HANDSHAKE_OK=1 break fi @@ -91,8 +91,8 @@ if [ ! -z "$EXT_SERVER" ]; then exit 1 fi - RTT=$(grep "rtt_ms=" cli.log | tail -n 1 | awk -F'rtt_ms=' '{print $2}' | awk '{print $1}') - echo -e "${GREEN}✓ Handshake Successful!${NC} Estimated Tunnel RTT: \033[0;33m${RTT}ms${NC}\n" + RTT=$(grep "rtt=" cli.log | tail -n 1 | sed -E 's/.*rtt=([0-9.]+)ms.*/\1/') + echo -e "${GREEN}Handshake successful.${NC} RTT: ${RTT}ms\n" echo -e "3. Executing End-to-End HTTP Proxy Ping..." PING_OUTPUT=$(curl -s -o /dev/null -w "DNS: %{time_namelookup}s | Connect: %{time_connect}s | TTFB: %{time_starttransfer}s | Total: %{time_total}s" -x socks5h://127.0.0.1:$SOCKS_PORT -I $HTTP_TEST_URL) @@ -224,8 +224,8 @@ else fi # Validate log patterns -grep -q "Starting in SERVER mode" server_run.log -print_result "server dynamic mode logging" $? "Expected starting sequence omitted in log" +grep -q "Starting server" server_run.log +print_result "server startup log" $? "Expected startup log missing" # Clean up server kill $SRV_PID 2>/dev/null @@ -255,8 +255,8 @@ else fi # Verify local proxy init logging -grep -q "Starting in CLIENT mode" client_run.log -print_result "client local proxy pipeline logging" $? "Starting logs missing" +grep -q "Starting client" client_run.log +print_result "client startup log" $? "Expected startup log missing" # Verify network bindings (checking if SOCKS5 port opened) # Try both ss and netstat, or fallback to /proc parsing @@ -317,8 +317,8 @@ CLI_CONN_PID=$! sleep 3 # 4. Validate active handshake in client logs -grep -q "Bridge connection established" client_conn.log -print_result "client-server secure handshake completion" $? "Handshake signatures missing in log. Log output: $(cat client_conn.log)" +grep -q "Connection established" client_conn.log +print_result "client-server secure handshake" $? "Handshake failed. Log: $(cat client_conn.log)" # 5. Teardown integration run kill $CLI_CONN_PID 2>/dev/null @@ -391,7 +391,7 @@ SEC_UNAUTH_PID=$! sleep 3 # Verify client remained unauthorized -grep -q "Bridge connection established" client_unauth.log +grep -q "Connection established" client_unauth.log HAS_ESTABLISHED=$? if [ $HAS_ESTABLISHED -ne 0 ]; then