Five small but real Android-only fixes: 1. Connect/Disconnect button gated on VpnState.isRunning state-flow with 12s backstop, replacing the fixed 2s transitionCooldown timer. Closes the race where a tap-after-Stop hit "Address already in use" because the previous teardown's listener-socket release wasn't done. 2. Tun2proxy.stop() wrapped in 2s join() — if the native call hangs, bounded teardown still releases the listener port instead of holding the teardown thread. 3. fd-leak fixed between parcelFd.detachFd() and Thread.start(): an OOM-thrown Thread.start used to orphan the detached fd. Now adopted into a fresh ParcelFileDescriptor purely so we can close() it. 4. Misleading teardown doc-comment rewritten — the "step 2 closes the TUN fd to force EBADF on read" claim has been factually wrong since detachFd landed. 5. Recursive crash trap: Log.e in MhrvApp's uncaught handler now wrapped in try/catch so a logd failure during exception logging falls through to the previous handler with the real exception. No Rust changes; 98 lib + 22 tunnel-node tests still pass. Local Android build verified, APK installed on mhrv_test emulator, launches cleanly with v1.6.1 in title. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2.6 KiB
• پایداری چرخهٔ سشن VPN در اندروید (#187): پنج رفع باگ کوچک ولی واقعی در سرویس VPN اندروید: (۱) دکمهٔ Connect/Disconnect حالا روی state-flow VpnState.isRunning گیت میشه (با backstop ۱۲ ثانیهای) به جای تایمر ثابت ۲ ثانیه — جلوی race condition بین Stop و Connect رو میگیره که قبلاً منجر به Address already in use میشد. (۲) Tun2proxy.stop() حالا با timeout ۲ ثانیهای بسته شده تا اگر روی native call hang کنه، کل teardown thread رو نگه نداره. (۳) رفع نشت file descriptor بین detachFd() و Thread.start() — اگه start بخاطر OOM throw میکرد، fd یتیم میشد. (۴) doc-comment گمراهکننده در teardown اصلاح شد. (۵) handler crash trap حالا Log.e رو در try/catch میپیچه تا اگه خود لاگ throw کنه، handler بازگشتی نشه
• Android VPN session lifecycle reliability (#187): five small but real fixes in the Android VPN service. (1) Connect/Disconnect button is now gated on the VpnState.isRunning state flow with a 12 s backstop instead of a fixed 2 s transitionCooldown timer — closes the race window where users tapping Connect right after Stop would hit "Address already in use" because the previous teardown's listener-socket release hadn't completed yet. (2) Tun2proxy.stop() is now wrapped in a 2 s join() timeout — if the native call hangs, the bounded tun2proxy thread join + bounded rt.shutdown_timeout below it still release the listener port instead of holding the teardown thread. (3) File-descriptor leak fixed between parcelFd.detachFd() and Thread.start() — if start() threw (OOM under memory pressure), the detached fd had no owner and leaked for the process lifetime; now adopted into a fresh ParcelFileDescriptor purely so we can close() it. (4) Misleading teardown doc-comment rewritten — the "step 2 closes the TUN fd to force EBADF on read" claim has been factually wrong since detachFd landed; corrected so future debuggers don't chase a phantom safety net. (5) Recursive crash trap in MhrvApp's uncaught-exception handler — Log.e is now wrapped in try/catch so a logd failure during exception logging falls through to the previous handler with the real exception