feat(tunnel): pipelined polls with adaptive depth, wseq ordering, STUN blocking (#1115)

feat(tunnel): pipelined full-tunnel polls, ordered writes, and STUN blocking

Merged trusted PR #1115 by @yyoyoian-pixel after local verification and a small maintainer fix on the PR branch.

---
Answered via LLM, Supervised @therealaleph
This commit is contained in:
yyoyoian-pixel
2026-05-16 16:46:08 +02:00
committed by GitHub
parent d822d67a26
commit 919b13b166
14 changed files with 1422 additions and 209 deletions
@@ -35,6 +35,7 @@ class MhrvVpnService : VpnService() {
private var proxyHandle: Long = 0L
private var tun2proxyThread: Thread? = null
private val tun2proxyRunning = AtomicBoolean(false)
private var debugOverlay: PipelineDebugOverlay? = null
// Idempotency guard. teardown() is reachable from three paths:
// 1. ACTION_STOP onStartCommand branch (background thread)
@@ -149,6 +150,7 @@ class MhrvVpnService : VpnService() {
Log.i(TAG, "PROXY_ONLY mode: listeners up, skipping VpnService/TUN")
VpnState.setProxyHandle(proxyHandle)
VpnState.setRunning(true)
showDebugOverlay()
return
}
@@ -314,6 +316,16 @@ class MhrvVpnService : VpnService() {
// a failed-to-establish run.
VpnState.setProxyHandle(proxyHandle)
VpnState.setRunning(true)
showDebugOverlay()
}
private fun showDebugOverlay() {
if (debugOverlay != null) return
if (!android.provider.Settings.canDrawOverlays(this)) {
Log.w(TAG, "overlay permission not granted — skipping debug overlay")
return
}
debugOverlay = PipelineDebugOverlay(this).also { it.show() }
}
/**
@@ -434,6 +446,10 @@ class MhrvVpnService : VpnService() {
Log.w(TAG, "tun2proxy thread still alive after join timeout — proceeding anyway")
}
// Hide debug overlay before flipping UI state.
debugOverlay?.hide()
debugOverlay = null
// Flip UI state last — the button reverts to Connect only after
// the native-side cleanup actually happened, not optimistically.
VpnState.setProxyHandle(0L)