From 9c7567e62ec25bb3b40cf51b6eceaa43d875b215 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Sun, 14 Sep 2025 16:36:02 +0200 Subject: [PATCH] lock to tor (#426) * lock to tor * bootstrap state --- .../com/bitchat/android/net/OkHttpProvider.kt | 5 ++-- .../com/bitchat/android/net/TorManager.kt | 24 ++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/bitchat/android/net/OkHttpProvider.kt b/app/src/main/java/com/bitchat/android/net/OkHttpProvider.kt index 60431476..45cff773 100644 --- a/app/src/main/java/com/bitchat/android/net/OkHttpProvider.kt +++ b/app/src/main/java/com/bitchat/android/net/OkHttpProvider.kt @@ -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 } } - diff --git a/app/src/main/java/com/bitchat/android/net/TorManager.kt b/app/src/main/java/com/bitchat/android/net/TorManager.kt index efa2eab5..d428c590 100644 --- a/app/src/main/java/com/bitchat/android/net/TorManager.kt +++ b/app/src/main/java/com/bitchat/android/net/TorManager.kt @@ -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()