• پایداری چرخه‌ٔ سشن VPN در اندروید ([#187](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/pull/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](https://github.com/therealaleph/MasterHttpRelayVPN-RUST/pull/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