-
ET Phone Home v0.6.0
StableAll checks were successfulAndroid CI / Unit Tests (push) Successful in 1m33sAndroid CI / Lint (push) Successful in 2m35sAndroid CI / Build Debug APK (push) Successful in 4m8sRelease / Build Windows Release (push) Successful in 1m49sRelease / Build Linux Release (push) Successful in 2m11sRelease / Build Desktop GUI (Linux) (push) Successful in 2m49sRelease / Build Android Release (push) Successful in 3m18sRelease / Publish Forgejo release (push) Successful in 13sreleased this
2026-10-16 21:00:03 -07:00 | 159 commits to main since this releaseAdded
- The computer really gets the phone's internet, without root. The Android app now has a userspace relay (
android/core/.../relay/UserspaceRelay.kt): it terminates the desktop's TCP connections and UDP flows itself and re-opens them as ordinary phone sockets (with sequence/ACK handling, flow control, retransmission, FIN/RST), answers ping for the phone and relays ping to other hosts. Before this the app only copied raw packets into a phone VPN, which Android never forwards, so no traffic ever reached the internet. - The phone keeps its own internet. The phone VPN is gone: nothing on the phone is captured, and the app no longer asks for VPN permission.
- Encrypted WiFi by default. The app serves cert-pinned TLS 1.3 (same token-derived Ed25519 pinning as the desktop, via Bouncy Castle) and auto-detects TLS vs. plaintext.
etphonehome wifiand WiFi profiles use TLS by default (--no-tlsto opt out); the app refuses plaintext WiFi unless "Require encryption" is switched off. - Live status and statistics on the phone: "Waiting for desktop" until a desktop has actually completed the handshake, then the desktop's address, encryption, data each way, open/total connections, uptime and filter state; the notification shows the same and has a Stop button.
- Traffic filter on the phone: right after the handshake the desktop sends the profile's filter (mode and every rule) to the phone, which enforces it on the connections it opens and resets connections a new rule blocks.
- DNS on the desktop: the client points DNS for the tunnel at the phone's DNS server (
resolvectlon Linux,netshon Windows). - Real-internet end-to-end CI: the e2e job now runs the app's actual networking core (
android/core, as the JVMstandin) and checks, from a desktop container whose only way out is the tunnel: public HTTPS and HTTP, DNS, a 5 MiB download, TCP echo both ways, UDP, ICMP, 20 parallel connections, USB, filter rules, wrong tokens, plaintext refusal, reconnects. - Releases are published on Forgejo (the workflow used a GitHub-only action and never created one) and checked to contain all four packages.
Removed
- Root mode. It was claimed as implemented, but nothing could start it, and its iptables rules redirected all of the phone's own traffic to the desktop. Removed until a correct kernel-NAT design exists.
- Dead Android TLS/connection classes that were never wired in.
Changed
- Android 8.0+ is now required (was 5.0).
Fixed
- USB tethering never connected: the desktop client (and
setup-adb,quick-start-linux.sh, and every doc) usedadb reverse, which maps a phone port to the computer. The app's USB server listens on the phone's loopback, so the client needsadb forward(computer port -> phone port); with the app running,adb reversefailed with "cannot bind listener: Address already in use". Confirmed against a real phone. The e2e adb stand-in now emulates both directions faithfully, so the wrong one fails the test. - Android: the phone lost its internet after a desktop session, and Stop didn't fix it: when the desktop disconnected, the VPN stayed established (all phone traffic routed into a dead tunnel), the app never accepted another connection (so desktop auto-reconnect could not work) and kept showing "Connected". The Stop button used
stopService(), which cannot stop a VpnService whose VPN is up, so only force-stopping the app restored the phone's network. Sessions now run in a loop that tears the VPN down after every session and waits for the next desktop; Stop sends an explicit stop action. The VPN is also only established after a successful handshake, so a client with a wrong token no longer touches the phone's routing. Found on a real phone (Android 13). - Ctrl-C raced the Disconnect message: the retry loop could drop the live session before it told the phone it was leaving; it now lets the session finish (up to 3 s) and never reconnects once stopping.
- Desktop forwarding stall: the TUN reader held the device mutex during its blocking read, so packets from the phone were only written to the TUN device when the desktop happened to send something. The forwarding loop now uses the async TUN device with independent read/write halves (shared
sessionmodule). - GUI Connect did nothing: the button only changed the status label. It now runs a real session (same runner as the CLI) with live state, stats and logs; Disconnect stops it. GUI-created profiles defaulted to port 8765 instead of 8888.
- Bluetooth (Linux): the RFCOMM connection was opened and then abandoned with "integration incomplete"; it now completes the handshake (with
--token/auth.bluetooth_token) and forwards packets. - CLI:
--reconnectcould not be turned off (it defaulted to true);save-profile --typefrom the README was rejected;sudo etphonehome connectlooked in root's config instead of the invoking user's; WiFi hosts had to be IP literals; Ctrl-C now sends Disconnect; wrong-token rejections now show the phone's reason instead of "Unexpected message type"; saving a profile from the CLI no longer wipes its filter rules;list-profilesoutput goes to stdout; a silent phone is detected after 90 s so auto-reconnect can kick in. - Android: stats, keepalive and packet writers shared one socket stream without locking (frames could interleave); StatsUpdate was 20 bytes instead of the specified 24. One shared
ServerHandshakereplaces three copies. - Release packaging: release.yml stripped/zipped binaries that don't exist (
etphonehome-linux,etphonehome-windows.exe) and expected an unsigned APK; CI artifact uploads pointed at the same wrong names. - quick-start-linux.sh: failed on kernels with built-in tun (modprobe under
set -e) and required Rust even when the client was already built. - Docs: Windows needs
wintun.dll, not TAP-Windows; Windows Bluetooth is not supported yet.
Tests / CI
- New end-to-end CI job runs the real client through a real TUN device against an Android-protocol stand-in (plaintext, TLS, wrong tokens, USB via adb, filters, auto-reconnect, quick-start script).
- Shared Rust/Kotlin golden wire vectors (
protocol/test-vectors.txt); 13 orphaned protocol tests that never compiled now run; TUN tests run with CAP_NET_ADMIN in CI.
Downloads
-
Source code (ZIP)
1 download
-
Source code (TAR.GZ)
2 downloads
- The computer really gets the phone's internet, without root. The Android app now has a userspace relay (