fix: proxy mode failing to shutdown properly, improved port availability checks

This commit is contained in:
zaneschepke
2026-05-26 04:48:53 -04:00
parent 7e264a6f19
commit 82bda83464
10 changed files with 93 additions and 33 deletions
@@ -7,13 +7,30 @@ sealed interface TunnelErrorEvent {
data class StateConflict(val tunnelId: Int, val message: String) : TunnelErrorEvent
data class InternalFailure(val tunnelId: Int?, val message: String) : TunnelErrorEvent
data class InternalFailure(val tunnelId: Int, val message: String) : TunnelErrorEvent
data class Socks5PortUnavailable(val tunnelId: Int, val port: Int) : TunnelErrorEvent
data class HttpPortUnavailable(val tunnelId: Int, val port: Int) : TunnelErrorEvent
companion object {
fun from(throwable: Throwable, id: Int?): TunnelErrorEvent {
fun from(throwable: Throwable, id: Int): TunnelErrorEvent {
return when (throwable) {
is BackendException.StateConflict -> StateConflict(id ?: -1, throwable.message)
is BackendException.Unauthorized -> InternalFailure(id, "Unauthorized")
is BackendException.StateConflict -> {
StateConflict(id, throwable.message)
}
is BackendException.Unauthorized -> {
VpnPermissionDenied(id)
}
is BackendException.InternalError -> {
InternalFailure(id, throwable.message)
}
is BackendException.Socks5PortUnavailable -> {
Socks5PortUnavailable(id, throwable.port)
}
is BackendException.HttpPortUnavailable -> {
HttpPortUnavailable(id, throwable.port)
}
else -> InternalFailure(id, throwable.message ?: "Unknown")
}
}
@@ -61,6 +61,14 @@ class TunnelEventDispatcher(private val notificationManager: TunnelNotificationS
is TunnelErrorEvent.InternalFailure -> {
notificationManager.showError(error.message)
}
is TunnelErrorEvent.Socks5PortUnavailable -> {
notificationManager.showSocks5PortUnavailable(error.port)
}
is TunnelErrorEvent.HttpPortUnavailable -> {
notificationManager.showHttpPortUnavailable(error.port)
}
}
}
.launchIn(scope)
@@ -150,6 +150,20 @@ class AndroidTunnelNotificationService(
showError(context.getString(R.string.error_root_denied))
}
override suspend fun showSocks5PortUnavailable(port: Int) {
val context = notificationService.context
val message = context.getString(R.string.error_socks5_port_unavailable, port)
showError(message)
}
override suspend fun showHttpPortUnavailable(port: Int) {
val context = notificationService.context
val message = context.getString(R.string.error_http_port_unavailable, port)
showError(message)
}
override suspend fun showError(message: String) {
val notification =
@@ -16,6 +16,10 @@ interface TunnelNotificationService {
suspend fun showStateConflict(tunnelId: Int)
suspend fun showSocks5PortUnavailable(port: Int)
suspend fun showHttpPortUnavailable(port: Int)
suspend fun showRootShellAccess()
suspend fun showError(message: String)
+3
View File
@@ -567,4 +567,7 @@
<string name="tunnel_scripting">Pre/Post script support</string>
<string name="name_error_empty">Tunnel name cannot be empty</string>
<string name="more_options">More options</string>
<string name="error_socks5_port_unavailable">SOCKS5 port %1$d is already in use.\nPlease choose a different port.</string>
<string name="error_http_port_unavailable">HTTP listener port %1$d is already in use.\nPlease choose a different port.</string>
</resources>