lock to tor (#426)

* lock to tor

* bootstrap state
This commit is contained in:
callebtc
2025-09-14 16:36:02 +02:00
committed by GitHub
parent df4aa4b25d
commit 9c7567e62e
2 changed files with 24 additions and 5 deletions
@@ -43,11 +43,12 @@ object OkHttpProvider {
private fun baseBuilderForCurrentProxy(): OkHttpClient.Builder {
val builder = OkHttpClient.Builder()
val socks: InetSocketAddress? = TorManager.currentSocksAddress()
if (socks != null && TorManager.isProxyEnabled()) {
// If a SOCKS address is defined, always use it. TorManager sets this as soon as Tor mode is ON,
// even before bootstrap, to prevent any direct connections from occurring.
if (socks != null) {
val proxy = Proxy(Proxy.Type.SOCKS, socks)
builder.proxy(proxy)
}
return builder
}
}
@@ -82,9 +82,18 @@ object TorManager {
currentApplication = application
TorPreferenceManager.init(application)
// Apply saved mode at startup
// Apply saved mode at startup. If ON, set planned SOCKS immediately to avoid any leak.
val savedMode = TorPreferenceManager.get(application)
if (savedMode == TorMode.ON) {
if (currentSocksPort < DEFAULT_SOCKS_PORT) {
currentSocksPort = DEFAULT_SOCKS_PORT
}
desiredMode = savedMode
socksAddr = InetSocketAddress("127.0.0.1", currentSocksPort)
try { OkHttpProvider.reset() } catch (_: Throwable) { }
}
appScope.launch {
applyMode(application, TorPreferenceManager.get(application))
applyMode(application, savedMode)
}
// Observe changes
@@ -136,6 +145,11 @@ object TorManager {
bindRetryAttempts = 0
lifecycleState = LifecycleState.STARTING
_status.value = _status.value.copy(mode = TorMode.ON, running = false, bootstrapPercent = 0, state = TorState.STARTING)
// Immediately set the planned SOCKS address so all traffic is forced through it,
// even before Tor is fully bootstrapped. This prevents any direct connections.
socksAddr = InetSocketAddress("127.0.0.1", currentSocksPort)
try { OkHttpProvider.reset() } catch (_: Throwable) { }
try { com.bitchat.android.nostr.NostrRelayManager.shared.resetAllConnections() } catch (_: Throwable) { }
startArti(application, useDelay = false)
// Defer enabling proxy until bootstrap completes
appScope.launch {
@@ -198,6 +212,10 @@ object TorManager {
bindRetryAttempts++
currentSocksPort++
Log.w(TAG, "Port bind failed (attempt $bindRetryAttempts/$MAX_RETRY_ATTEMPTS), retrying with port $currentSocksPort")
// Update planned SOCKS address immediately so all new connections target the new port
socksAddr = InetSocketAddress("127.0.0.1", currentSocksPort)
try { OkHttpProvider.reset() } catch (_: Throwable) { }
try { com.bitchat.android.nostr.NostrRelayManager.shared.resetAllConnections() } catch (_: Throwable) { }
// Immediate retry with incremented port, no exponential backoff for bind errors
startArti(application, useDelay = false)
} else if (isBindError) {
@@ -339,7 +357,7 @@ object TorManager {
completeWaitersIf(TorState.STARTING)
}
s.contains("Sufficiently bootstrapped; system SOCKS now functional", ignoreCase = true) -> {
_status.value = _status.value.copy(bootstrapPercent = 100, state = TorState.BOOTSTRAPPING)
_status.value = _status.value.copy(bootstrapPercent = 75, state = TorState.BOOTSTRAPPING)
retryAttempts = 0
bindRetryAttempts = 0
startInactivityMonitoring()