Repository navigation
Releases
v4.9.1
VPeeN v4.9.1 — "Sangar" patch
A one-fix patch for v4.9.0, plus release-integrity hardening that
landed on main right after the v4.9.0 tag.
1. Fixed: the Doctor modal was invisible
The v4.9.0 headline feature had a self-inflicted wound: the modal
open-state CSS listed only the settings and update dialogs, so
body[data-modal="doctor"] never matched — the protection self-check
ran silently behind an opacity: 0 overlay and the shield button in
the top bar appeared to do nothing.
- Both open-state rules now include the doctor dialog (visible +
card transform), and a regression check
(test_doctor3e2) pins the selector so it cannot regress silently. - Everything else about the Doctor worked — which made it worse: the
checks ran, the log line appeared, only the results were unreachable.
2. Improved: Persian glyph fallback
--font now appends Vazirmatn and Tahoma after the Latin
stack: Latin UI text is untouched (earlier fonts still win per glyph),
and Persian text falls back to a properly designed Persian UI font
instead of whatever the OS guesses. Users with Vazirmatn installed get
the best rendering; Windows gets Tahoma.
3. Release integrity (repo-side, landed post-v4.9.0)
- Every release asset is checksummed now. The Chrome-extension zip
used to ship without a SHA256SUMS entry — users could not verify it.
It is built into the checksummed release directory and a-ge 5
tripwire fails any future release that drops the contract. The live
v4.9.0 sums were repaired to cover it (verified by the canary). - Daily release canary (read-only): verifies the latest release
downloads, every hash matches, the Windows Setup installer exists,
no asset ships unverified, magic bytes are sane, and nov*tag
exists without its release. - Changelog-driven release bodies: each tag's CHANGELOG-vX.Y.Z.md
is published as the release body automatically (with a guard, so a
missing changelog can never block a release). - Dispatchable sums repair (
Release toolsworkflow) for
maintainers: surgical append-only rebuild of SHA256SUMS.txt.
4. Docs
- README refreshed for v4.9: stale badges fixed, version history
table, the v4.8 "Sentinel" section restored, project structure
updated, and new screenshots — including the first Persian (RTL)
screenshot and the Doctor panel. - Repo topics fixed (dropped
customtkinter, which was removed in
v4.4.0; addedkill-switch,tun,tun2socks,pywebview).
Tests (the gate)
444 checks / 11 suites, all green before tagging:
| Suite | Checks | Covers |
|---|---|---|
| test_tunnel_fixes | 32 | tunnel worker regression |
| test_selfupdate | 36 | updater + registry sync |
| test_speed_pass | 42 | speed/quality regression |
| test_vpeen_fixes | 59 | core fixes regression |
| test_vpeen_integration | 11 | end-to-end proxy chain |
| test_webui_demo | 23 | web UI regression |
| test_installer | 67 | installer, CI pipeline, updater compat, canary/tools |
| test_killswitch | 51 | containment engine, repair, lockdown, sweeps |
| test_i18n | 36 | dictionary parity, RTL wiring, settings flow |
| test_bypass | 30 | parser + 3 desktops + plumbing |
| test_doctor | 57 | check engine + endpoint + frontend (+ modal visibility) |
Upgrading
In-app self-update (v4.8.0+) picks this up automatically; the Windows
installer and portable zip both update in place. No settings or
protocol changes.
Full Changelog: v4.9.0...v4.9.1
v4.9.0
📦 Downloads
| File | OS | Note |
|---|---|---|
VPeeN-Setup-4.9.0.exe |
Windows 10/11 | the installer — double-click, no admin/UAC, Start Menu + Apps & Features uninstaller |
VPeeN-4.9.0-Windows.zip |
Windows 10/11 | portable alternative |
VPeeN-4.9.0-macOS.zip |
macOS 10.13+ | ad-hoc signed — see the README Gatekeeper note |
VPeeN-4.9.0-Linux.tar.gz |
Linux x64 | extract → ./VPeeN |
VPeeN-Chrome-Extension.zip |
Chrome 108+ | VPeeN Bridge |
نصبکنندهٔ واقعی ویندوز، کیلسوئیچِ فایروالی، رابط فارسی راستبهچپ، Split Tunneling و خودآزمایی محافظت — با ۴۳۴ تست سبز در ۱۱ مجموعه.
Theme of this release: hold the line. A real Windows installer, a firewall-grade
kill switch, a Persian UI, split tunneling, and a one-click protection self-check.
Everything shipped only after the full CI test gate passed — 434 checks across
11 suites.
1. Windows: a real installer (the #1 user request)
VPeeN-Setup-x.y.z.exe replaces the zip as the way to install VPeeN on Windows:
- Inno Setup builds a proper setup exe in CI (
installer/vpeen.iss). - Per-user install (
PrivilegesRequired=lowest) into
%LOCALAPPDATA%\Programs\VPeeN— no UAC prompt, no admin rights to install
or upgrade (the VS Code "user setup" model). - Start Menu shortcuts, an optional desktop icon, a run-after-install task, and a
real uninstaller in Apps & Features. - Stable
AppId→ in-place upgrades keep your install location. CloseApplications=yes→ upgrading over a running VPeeN closes it cleanly
instead of failing on a locked exe.- The portable zip stays as a secondary asset (USB sticks, restricted machines).
- The in-app self-updater still consumes the zip asset for its atomic swap
(the per-user install dir stays user-writable), and now syncs the
"Apps & Features" DisplayVersion after every self-update
(selfupdate.refresh_installed_version, cosmetic failures are swallowed).
2. Kill switch — traffic is blocked, never leaked (tunnel mode)
The uncomfortable truth first: when tun2socks dies mid-session, the TUN adapter
dies with it and the kernel drops the hijack routes — every packet then
silently leaves through your real gateway while the UI still says "Protected".
v4.8's "crash sweep" only cleaned up afterwards; it did not contain.
v4.9's kill switch (vpeen/killswitch.py, default ON):
- DETECT — the elevated worker polls tun2socks every second.
- CONTAIN — tagged firewall rules drop all non-loopback outbound traffic:
- Windows:
netsh advfirewallblock ruleVPeeN-KS
(loopback is exempt in WFAS, so the repair plumbing stays alive) - Linux:
iptables/ip6tablesOUTPUT DROP (! -o lo), comment-tagged - macOS: no safe stdlib primitive — detection + repair only (documented)
- Windows:
- REPAIR — respawn tun2socks (loopback only), re-bind the address +
hijack routes to the reborn adapter (tunnel_platforms.rebind_tun_routes,
incl. the new Windows interface index), restart the DNS relay, verify it
stays alive — and only then lift the containment. The successful path
has no leak window after detection; the local SOCKS core reconnects by
itself once rules lift. - LOCKDOWN — after 3 failed repairs the containment stays: nothing in,
nothing out, a red "Kill Switch ON" state, one click to disconnect/retry.
Never-brick guarantees: rules are journaled into the session file (crash
recovery replays their removal), engage is delete-then-add (no stacking),
release is idempotent, and the boot/cleanup sweeps remove stale VPeeN-KS
rules even with no session file. Heartbeat loss with the kill switch ON now
keeps the blackhole instead of restoring routes under a dead GUI.
3. Persian UI (فارسی) with full RTL
- Settings → Interface → Language: English / فارسی — persisted, applied
instantly, no reload. - ~120 translated strings;
dir="rtl"flips the whole layout (sheets slide
from the left, row directions, text alignment) while logs/figures stay LTR. - The dictionary is pure JSON inside
app.js; the CI test gate verifies
key parity, placeholder parity and real Persian script.
4. Split tunneling (proxy mode)
Settings → Local proxy → Bypass list (*.ir, bank.example.com, …):
those destinations connect directly while the system proxy is on — bank
sites that block foreign IPs keep working.
- Windows: merged into
ProxyOverride(restored byte-for-byte on disconnect). - macOS:
networksetup -setproxybypassdomainsper service, original lists
backed up and restored (empty originals restored asEmpty). - GNOME:
ignore-hosts, backed up and restored verbatim. - CLI:
--bypass "*.ir,example.com"with--set-system. - One parser everywhere (
systemproxy.parse_bypass): wildcards kept, junk
dropped, de-duplicated, capped at 200 entries; loopback safety floor always
merged first. Tunnel mode deliberately ignores the list (full tunnel).
5. Doctor — one-click protection self-check
The shield button in the top bar runs 8 honest checks on the live state
(no third-party "what is my IP" sites — it uses the app's own probes):
| Check | Catches |
|---|---|
| Local proxy listeners | listeners actually up |
| Exit IP ≠ real IP | the leak itself (red FAIL if they match) |
| Traffic routing | proxy-mode partial coverage |
| DNS privacy | DNS going to your ISP |
| Kill switch | armed / engaged / lockdown / disabled |
| System proxy applied | + bypass-list summary |
| QUIC / UDP side channel | QUIC bypassing an HTTP proxy |
| WebRTC advisory | browser-level IP exposure |
Results are sorted problems-first, localized (EN/FA), and summarized in the
log (Self-check: 8 checks: 4 ok, 4 warnings, 0 problems).
Upgrading & compatibility
- Settings file gains
kill_switch(defaulttrue),ui_lang("en"),
bypass_domains("") — older settings.json files upgrade silently. - No protocol changes; existing sessions and locations work as before.
- macOS containment is repair-only for now (pf integration is future work);
everything else behaves identically cross-platform.
Tests (the gate)
434 checks / 11 suites, all green before tagging:
| Suite | Checks | Covers |
|---|---|---|
| test_tunnel_fixes | 32 | tunnel worker regression |
| test_selfupdate | 36 | updater + new registry sync |
| test_speed_pass | 42 | speed/quality regression |
| test_vpeen_fixes | 59 | core fixes regression |
| test_vpeen_integration | 11 | end-to-end proxy chain |
| test_webui_demo | 23 | web UI regression |
| test_installer | 58 | .iss script, CI pipeline, updater compat |
| test_killswitch | 51 | containment engine, repair, lockdown, sweeps |
| test_i18n | 36 | dictionary parity, RTL wiring, settings flow |
| test_bypass | 30 | parser + 3 desktops + plumbing |
| test_doctor | 56 | check engine + endpoint + frontend |
VPeeN v4.8.0 — Sentinel
VPeeN v4.8.0 — "Sentinel"
Tunnel mode, root-caused and fixed. Automatic updates with one click. A CI test gate so a broken build can never ship.
Tunnel mode — the real bugs, all fixed
- The "connected but dead" blackhole — on the first connect the TUN layer was raised with an empty anti-loop IP list (the
listenersevent arrived afterphase=connected), so the default route was hijacked with zero host routes for the upstream servers and every dial looped back into the tunnel. Fixed at three levels: correct event order, payload on the phase event itself, and the worker now refuses to hijack at all when the IP set is empty. - Hostnames are not routes — upstream "IPs" could be hostnames, which
ip routerejects androute.exeresolves inconsistently. All addresses are now resolved to concrete IPs before any route is touched; hostname/v6 entries never reach a route command. - Round-robin DNS re-poisoning — after the hijack, re-resolving a proxy hostname through the tunnelled resolver could return an unrouted A record: instant mid-session blackhole. Proxy hostnames are now pinned pre-hijack and answered from the pin map (process resolver + DNS relay).
- The crash-recovery sweep that never ran — a crash while the tunnel was up could leave the hijack routes behind (network bricked until reboot). The sweep now actually runs on every boot, and the session journal is checkpointed after every route mutation.
- DNS order-of-operations — the system resolver used to be swapped to the tunnel relay before the relay had bound. Now the relay binds first; a failed bind keeps your physical resolver instead of killing DNS for the whole session.
--interfaceremoved from tun2socks (pure risk on some stacks),updrace guard for credential rotations, relay-bind failure keeps the tunnel up with a leak warning instead of a blackout.
Automatic updates (new)
- Checks GitHub on start + every 6 h, pre-downloads the update in the background (through the app's own SOCKS5 when GitHub is unreachable directly), verifies it against the release's SHA256SUMS.txt (CI now generates it — a release without checksums is refused), and switches you over with one button: install → clean disconnect → restart into the new version.
- The swap renames the old build aside (rollback on any failure), a boot marker verifies the new version actually landed, and leftovers are swept on the next start. Source installs (git) are detected and told to
git pullinstead. - New Update sheet in the UI: current → new version, download progress, release notes, one-click install. A dot on the footer version chip shows when an update is waiting.
Release discipline
- CI now runs the full regression suite (202 checks) as a dedicated gate job — tunnel fixes, self-update, speed pass, fix pack, integration, Web UI — and the release job depends on it. Failing test anywhere = no release, period.
Verification: 31 tunnel-fix + 36 self-update + 42 speed + 59 fix-pack + 11 integration + 23 Web UI = 202/202 green.
This is the release that brings the updater — download it once from the assets below; every future release updates itself with one click.
VPeeN v4.7.0 — Nitro
VPeeN v4.7.0 — Nitro
The tail-latency release: hedged connects, a resolver cache, and a pool that adapts to reality.
⚡ What got faster
Hedged upstream connects — when the chosen server's TLS handshake has not landed within 350 ms, a parallel backup connect to the next-best server starts; the first success wins. A stalled "best" server used to cost every connection of a browsing burst its full 8 s budget — it now costs 0.35 s. The loser is reaped in the background (never cancelled mid-handshake: that is a socket-leak path) and gets no breaker penalty. Hedges only fire when a handshake permit is free, so bursts never double their load on the free proxy.
Resolver cache with singleflight — every fresh connect used to pay a blocking getaddrinfo (on Windows the resolver also tries LLMNR/mDNS first — routinely 50–200 ms). Resolved proxy IPs are now cached for 60 s and shared by every connect, refill wave and latency probe; a 30-socket burst produces ONE lookup instead of 30. A dead resolver serves the stale cached answer instead of failing.
Happy-Eyeballs across DNS records — a server given by hostname is expanded to its concrete A/AAAA records and ALL of them race staggered. A blackholed first record costs 150 ms instead of the full timeout. TLS SNI and certificate validation still use the original hostname, so security is unchanged.
🎯 What got smarter
Adaptive warm-pool TTL (8–25 s) — servers that reap idle sockets faster than we assumed used to turn warm hits into failed CONNECTs. Each stale entry now shrinks the TTL toward an 8 s floor; it recovers slowly between probe cycles.
Demand-adaptive pool size (12→24) — the refill target tracks the last 10 s of connection demand. Browsing is bursty; the burst after a burst now starts mostly pre-paid.
Throughput ranking that ages — a measured-KB/s number only ranks a server for 10 minutes, and the top candidates are re-measured every ~3 minutes, so a "best" server that collapses under load is demoted mid-session.
Wider handshake window — parallel-handshake cap 12 → 16; with the resolver cache each handshake starts without the getaddrinfo hop, so the wider window is no longer a flood. The DNS relay's cache went 30 → 60 s, aligned with the SOCKS-UDP relay.
🖥 Visible in the UI
The status line now shows "N rescued" — hedged connects that saved a stalled handshake — next to "N warm". The 30-second log line reports hedges and the adaptive TTL alongside hits/stale.
📊 The numbers
| Scenario | v4.6.0 | v4.7.0 |
|---|---|---|
| First connect of a burst | getaddrinfo + TCP + TLS + CONNECT | cached resolve + TCP + TLS + CONNECT |
| Best server stalls mid-session | every connection waits up to 8 s | 0.35 s hedge, backup carries it |
| Blackholed first DNS record | up to 8 s | 150 ms |
| Server reaps idle conns at 10 s | warm hits become failed CONNECTs | TTL shrinks to fit, hits stay real |
| Second burst within 10 s | pool back to floor 12 | pool sized to the burst (≤ 24) |
| "Best" server collapses under load | ranked by a 10-min-old number | re-measured every ~3 min |
✅ Quality
135 checks green: 42 speed-pass (10 new for Nitro), 59 regression, 11 integration, 23 web-UI. No settings, commands or file formats changed — the SOCKS5/HTTP surface is untouched; the only observable differences are speed, two status fields and one log line.
Full changelog: CHANGELOG-v4.7.0.md
Windows — download VPeeN-4.7.0-Windows.zip, extract, run VPeeN.exe.
macOS — download VPeeN-4.7.0-macOS.zip; on Sequoia/Tahoe 26 right-click → Open (the binary is ad-hoc signed; see README's Gatekeeper section).
Linux — download VPeeN-4.7.0-Linux.tar.gz, extract, run ./VPeeN (or use the AppImage-style launcher inside).
VPeeN 4.6.0 — Turbo ⚡
⚡ The speed release
v4.5.0 Velocity removed the handshake tax in theory — v4.6.0 Turbo makes it land on your page loads, and adds the one thing no client-side proxy could honestly claim before: a measured, server-side quality signal for picking the exit server.
Measured on the real free network (region nl, 6 sequential connections — the shape of one browser page load):
| Metric | v4.5-like cold path | v4.6.0 Turbo | Gain |
|---|---|---|---|
| Connection setup (avg) | 1309 ms | 386 ms | 3.4× faster |
| Whole 6-connection burst | 36.8 s | 13.0 s | 2.8× faster |
| Effective throughput | 42 KiB/s | 119 KiB/s | 2.8× |
Reproduce it yourself: python3 scripts/test_real_speed.py nl
🚀 What actually changed
- Fixed the 1/N pool-hit bug — the warm pool only matched the round-robin cursor's server, so with 3 servers two thirds of every browsing burst still paid the full TCP+TLS+CONNECT handshake. Every connection now takes the newest warm connection, whatever server it belongs to.
- Pool 4 → 12, filled in parallel waves — and pre-warming starts the moment you press connect, so the first page load is fast now too, not just the tenth.
- Throughput ranking — the server-side signal 📡 — at connect time each top server is measured with a real 128 KiB download through its own tunnel; the best-bandwidth server wins, not merely the lowest-ping one. Re-measured every 60 s. (This is the strongest server-side quality pull a client can make.)
- Handshake concurrency 8 → 12, macOS 512 KiB socket buffers, faster Happy-Eyeballs stagger (150 ms), DNS cache TTL 60 s,
N warmlive in the stats line + a warm-pool health log every 30 s.
🍏 macOS users — first launch (fixes #1)
The app is free open-source software without a paid Apple Developer certificate, so Gatekeeper on Sequoia/Tahoe 26 shows "Apple could not verify…". It is a warning, not a defect:
- Try to open the app once → System Settings → Privacy & Security → scroll down → “Open Anyway”. Once. Done forever.
- Or in Terminal:
xattr -cr /Applications/VPeeN.app
This release's macOS builds are also ad-hoc code-signed, which removes the "damaged copy" failure mode.
🧩 Chrome extension — VPeeN Bridge (fixes #2)
New in every release: VPeeN-Chrome-Extension.zip — a 2-permission MV3 extension (proxy, storage) that routes all of Chrome through the local VPeeN SOCKS5 tunnel with one click, remote DNS and the same localhost/LAN bypass list as the desktop app. Unzip → chrome://extensions → Developer mode → Load unpacked.
✅ Verification
scripts/test_speed_pass.py— 25/25 (5 new checks for the Turbo paths)scripts/test_vpeen_fixes.py— 59/59scripts/test_vpeen_integration.py— 11/11scripts/test_webui_demo.py— 23/23- Real-network A/B benchmark — the table above
Full changelog: CHANGELOG-v4.6.0.md · Compare: v4.5.0...v4.6.0
📥 Downloads
| File | OS |
|---|---|
VPeeN-4.6.0-Windows.zip |
Windows 10/11 |
VPeeN-4.6.0-macOS.zip |
macOS 10.13+ (see the Gatekeeper note) |
VPeeN-4.6.0-Linux.tar.gz |
Linux x64 |
VPeeN-Chrome-Extension.zip |
Chrome 108+ |
v4.5.0 — “Velocity”
⚡ The speed & quality pass
One goal: make every proxied connection faster and make Connect feel instant. All client-side — the round-trips we spend on the server network are now a third of what they were.
🔥 Pre-warmed TLS connection pool
Every proxied connection used to pay the full setup toll — TCP + complete TLS handshake + CONNECT ≈ 3 round-trips before the first byte of real data (≈450 ms on a 150 ms path, per connection; browsers open 20–40 at once). The factory now keeps up to 4 TLS-established (pre-CONNECT) connections warm in the background:
- a client CONNECT costs one round-trip — ~3× lower per-connection latency (measured 2.3× even on loopback)
- stale warm connections (silently reaped by the server) are detected instantly and retried transparently — never surfaced to the client
- the refiller shares the handshake semaphore, so it never starves real traffic
🏁 Happy-Eyeballs address racing (RFC 8305 style)
A blackholed server address used to cost the full 8 s timeout before the next one was tried. Addresses now race with a 250 ms stagger — worst case 250 ms instead of 8 s.
📊 Latency-ranked servers
Servers inside a region were picked by blind round-robin. At startup every server is probed concurrently and the list is reordered fastest-first (sticky); the warm pool targets the same winner. The GUI’s per-region ping now reports the region’s best server (up to 5 probed concurrently), not just its first entry.
⚡ Instant “connected”
The UI used to sit on the exit-IP probe (up to 15 s × 2 servers) after the proxies were already live. The connected phase now flips the moment the listeners are up; the exit IP is verified in the background and arrives as its own event.
🧰 Everything else
- Cached SSL contexts — no system-CA-bundle reload per connection (tens of ms on Windows, every time)
- 256 KiB relay chunks & reader limits (was 64 KiB) — lifts throughput on high-bandwidth × high-latency paths
- DNS cache for the SOCKS5 UDP-DNS path — repeat lookups answered locally (question-section key, ID-rewritten replies)
- TCP tuning — contractual
TCP_NODELAY, 512 KiB buffers on Windows - CLI parity — same probe, pool and limits in
python -m vpeen.cli run
📦 Downloads
| Asset | Platform | Install |
|---|---|---|
VPeeN-4.5.0-Windows.zip |
Windows 10/11 | unzip → VPeeN.exe |
VPeeN-4.5.0-macOS.zip |
macOS 10.13+ | unzip → VPeeN.app (right-click → Open the first time) |
VPeeN-4.5.0-Linux.tar.gz |
Linux x64 | extract → ./VPeeN |
✅ Verification
scripts/test_speed_pass.py 17/17 PASS (fake TLS upstream)
scripts/test_webui_demo.py 23/23 PASS (live demo-mode server)
scripts/test_vpeen_integration.py 11/11 PASS (fake TLS upstream)
scripts/test_vpeen_fixes.py 59/59 PASS
bench (loopback): cold connect 3.4 ms → warm-pool 1.5 ms (2.3×)
Full Changelog: v4.4.0...v4.5.0
v4.4.0 — “Aurora”
✨ The Aurora GUI
The desktop GUI is now a local web application: a loopback-only HTTP bridge (vpeen/webui.py) runs the proxy core + tunnel controller and serves a zero-dependency UI (vanilla HTML/CSS/JS) shown in a native window via pywebview (Windows/macOS) or the default browser (Linux). CustomTkinter / Pillow / the whole Tk runtime are gone — the core stays pure-stdlib Python.
- 🌌 Deep-space dark theme — drifting aurora gradients, dot grid, glass surfaces, gradient-ring power orb with phase-reactive states (connecting shimmer / connected glow / error arc)
- 🗺️ Location sheet with circular flags, live search, per-region latency bars (real TCP-probe ms) and an “Optimal” card
- 📊 Live stat cards: down/up totals with live rates, session timer, connections; IP card flips between real IP and exit IP, click-to-copy
- ⚙️ Settings modal with full server-side validation, toasts, color-coded copyable log sheet
- ⚡ Long-poll event stream (
/api/poll) — sub-second UI updates, zero third-party JS - ♿ Full keyboard operation, focus rings,
prefers-reduced-motion, ARIA labels - 🎬 New cinematic demo GIF — bespoke “aurora dart” cursor with comet trail and layered click ripples (README)
🔧 12 defects found & fixed (full audit of the new bridge + UI)
Critical
- Demo/data connect crashed mid-response (
KeyError: country) → UI stuck on “Connecting…” forever - Bridge exceptions killed HTTP responses — every endpoint now answers with a logged JSON 500
- Tunnel mode never showed the exit country (region recorded after the TUN layer was raised)
High
- Tunnel disconnect hung for 8 s — core stops the moment the tunnel confirms down
- Region switch while connected did nothing in demo mode
- Disconnect during “connecting” self-reconnected ~4 s later (generation counters now invalidate stale timelines)
- Out-of-range ports/MTU saved silently — validated at save time with per-field messages
Medium
- Switch reconnect could be lost forever
- Stale tunnel styling after disconnect
- Footer showed stale ports after saving settings
- Tunnel switch while connected didn’t apply (v4.3 parity restored)
- Misleading System-Proxy tooltip
📦 Downloads
| Asset | Platform | Install |
|---|---|---|
VPeeN-4.4.0-Windows.zip |
Windows 10/11 | unzip → VPeeN.exe |
VPeeN-4.4.0-macOS.zip |
macOS 10.13+ | unzip → VPeeN.app (right-click → Open the first time) |
VPeeN-4.4.0-Linux.tar.gz |
Linux x64 | extract → ./VPeeN |
Windows/macOS open the UI in a native desktop window; Linux opens it in the default browser — same UI, same features.
✅ Verification
scripts/test_webui_demo.py 27/27 PASS (live demo-mode server)
scripts/test_vpeen_fixes.py 59/59 PASS
scripts/test_vpeen_integration.py 11/11 PASS (fake TLS upstream)
manual real-network check connect → SOCKS5 fetch → exit-IP match
Full Changelog: v4.3.1...v4.4.0