diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 99163d87..a2f47b60 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,3 +1,2 @@ - + diff --git a/cargokit/build_tool/lib/src/android_environment.dart b/cargokit/build_tool/lib/src/android_environment.dart index 9342964b..be3c4911 100644 --- a/cargokit/build_tool/lib/src/android_environment.dart +++ b/cargokit/build_tool/lib/src/android_environment.dart @@ -186,7 +186,17 @@ class AndroidEnvironment { if (rustFlags.isNotEmpty) { rustFlags = '$rustFlags\x1f'; } - rustFlags = '$rustFlags-L\x1f$workaroundDir'; + rustFlags = '$rustFlags-L\x1f$workaroundDir\x1f'; + + const pageSizeArgs = [ + "-C", + "link-arg=-Wl,--hash-style=both", + "-C", + "link-arg=-Wl,-z,max-page-size=16384" + ]; + final pageSizeArgsString = pageSizeArgs.join("\x1f"); + + rustFlags = '$rustFlags$pageSizeArgsString'; return rustFlags; } } diff --git a/lib/tor_ffi_plugin.dart b/lib/tor_ffi_plugin.dart index 41beb402..b44477d4 100644 --- a/lib/tor_ffi_plugin.dart +++ b/lib/tor_ffi_plugin.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:ffi'; import 'dart:io'; import 'dart:isolate'; -import 'dart:math'; import 'package:ffi/ffi.dart'; import 'package:flutter/foundation.dart'; @@ -174,9 +173,16 @@ class Tor { /// Stop the proxy. stop() async { + // Return early if already stopped. + if (_proxyPtr == nullptr) { + return; + } + final lib = TorFfiPluginBindings(_lib); lib.tor_proxy_stop(_proxyPtr); _proxyPtr = nullptr; + _bootstrapped = false; + _status = TorStatus.off; } setClientDormant(bool dormant) async { @@ -192,16 +198,16 @@ class Tor { Pointer _proxyPtr = nullptr; Future _getRandomUnusedPort({List excluded = const []}) async { - var random = Random.secure(); - int potentialPort = 0; + int port = 0; retry: - while (potentialPort <= 0 || excluded.contains(potentialPort)) { - potentialPort = random.nextInt(65535); + while (port == 0 || excluded.contains(port)) { try { - var socket = await ServerSocket.bind("0.0.0.0", potentialPort); + // Bind to port 0 to let the OS assign a free port. + var socket = await ServerSocket.bind("0.0.0.0", 0); + port = socket.port; socket.close(); - return potentialPort; + return port; } catch (_) { continue retry; } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 3af430ce..75fa863e 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -57,6 +57,12 @@ pub unsafe extern "C" fn tor_start( .state_dir(CfgPath::new(state_dir.to_owned())) .cache_dir(CfgPath::new(cache_dir.to_owned())); cfg_builder.address_filter().allow_onion_addrs(true); + cfg_builder + .preemptive_circuits() + .disable_at_threshold(1) + .min_exit_circs_for_port(1) + .initial_predicted_ports() + .clear(); let cfg = unwrap_or_return!(cfg_builder.build(), err_ret); @@ -81,10 +87,12 @@ pub unsafe extern "C" fn tor_start( #[no_mangle] pub unsafe extern "C" fn tor_client_bootstrap(client: *mut c_void) -> bool { - let client = { - assert!(!client.is_null()); - Box::from_raw(client as *mut TorClient) - }; + // Return false if client is null (not started). + if client.is_null() { + return false; + } + + let client = Box::from_raw(client as *mut TorClient); unwrap_or_return!(client.runtime().block_on(client.bootstrap()), false); true @@ -92,10 +100,12 @@ pub unsafe extern "C" fn tor_client_bootstrap(client: *mut c_void) -> bool { #[no_mangle] pub unsafe extern "C" fn tor_client_set_dormant(client: *mut c_void, soft_mode: bool) { - let client = { - assert!(!client.is_null()); - Box::from_raw(client as *mut TorClient) - }; + // Return early if client is null (not started). + if client.is_null() { + return; + } + + let client = Box::from_raw(client as *mut TorClient); let dormant_mode = if soft_mode { DormantMode::Soft