From 4d70dab6e7cc3aa0f852010748c1c407db566ee2 Mon Sep 17 00:00:00 2001 From: Igor Cota Date: Mon, 29 Jan 2024 22:36:39 +0100 Subject: [PATCH] Add restart function --- lib/generated_bindings.dart | 632 +++++++++++++++++++++++++++++++++--- lib/tor.dart | 41 ++- lib/util.dart | 6 +- pubspec.yaml | 4 +- rust/Cargo.lock | 7 +- rust/Cargo.toml | 3 +- rust/build.rs | 4 +- rust/src/lib.rs | 77 ++++- rust/target/tor.h | 13 +- 9 files changed, 702 insertions(+), 85 deletions(-) diff --git a/lib/generated_bindings.dart b/lib/generated_bindings.dart index 6da7658..c1daa92 100644 --- a/lib/generated_bindings.dart +++ b/lib/generated_bindings.dart @@ -18,7 +18,14 @@ class NativeLibrary { lookup) : _lookup = lookup; - ffi.Pointer tor_start( + late final ffi.Pointer> _suboptarg = + _lookup>('suboptarg'); + + ffi.Pointer get suboptarg => _suboptarg.value; + + set suboptarg(ffi.Pointer value) => _suboptarg.value = value; + + Tor tor_start( int socks_port, ffi.Pointer state_dir, ffi.Pointer cache_dir, @@ -32,25 +39,54 @@ class NativeLibrary { late final _tor_startPtr = _lookup< ffi.NativeFunction< - ffi.Pointer Function(ffi.Uint16, ffi.Pointer, + Tor Function(ffi.Uint16, ffi.Pointer, ffi.Pointer)>>('tor_start'); late final _tor_start = _tor_startPtr.asFunction< - ffi.Pointer Function( - int, ffi.Pointer, ffi.Pointer)>(); + Tor Function(int, ffi.Pointer, ffi.Pointer)>(); - bool tor_bootstrap( + bool tor_client_bootstrap( ffi.Pointer client, ) { - return _tor_bootstrap( + return _tor_client_bootstrap( client, ); } - late final _tor_bootstrapPtr = + late final _tor_client_bootstrapPtr = + _lookup)>>( + 'tor_client_bootstrap'); + late final _tor_client_bootstrap = _tor_client_bootstrapPtr + .asFunction)>(); + + bool tor_proxy_stop( + ffi.Pointer proxy, + ) { + return _tor_proxy_stop( + proxy, + ); + } + + late final _tor_proxy_stopPtr = _lookup)>>( - 'tor_bootstrap'); - late final _tor_bootstrap = - _tor_bootstrapPtr.asFunction)>(); + 'tor_proxy_stop'); + late final _tor_proxy_stop = + _tor_proxy_stopPtr.asFunction)>(); + + Tor tor_proxy_restart( + Tor tor, + int port, + ) { + return _tor_proxy_restart( + tor, + port, + ); + } + + late final _tor_proxy_restartPtr = + _lookup>( + 'tor_proxy_restart'); + late final _tor_proxy_restart = + _tor_proxy_restartPtr.asFunction(); void tor_hello() { return _tor_hello(); @@ -95,17 +131,23 @@ class NativeLibrary { _tor_set_nofile_limitPtr.asFunction(); } -const int true1 = 1; +abstract class idtype_t { + static const int P_ALL = 0; + static const int P_PID = 1; + static const int P_PGID = 2; +} -const int false1 = 0; +class Tor extends ffi.Struct { + external ffi.Pointer client; -const int INT8_MIN = -128; + external ffi.Pointer proxy; +} -const int INT16_MIN = -32768; +const int true1 = 1; -const int INT32_MIN = -2147483648; +const int false1 = 0; -const int INT64_MIN = -9223372036854775808; +const int USER_ADDR_NULL = 0; const int INT8_MAX = 127; @@ -115,6 +157,14 @@ const int INT32_MAX = 2147483647; const int INT64_MAX = 9223372036854775807; +const int INT8_MIN = -128; + +const int INT16_MIN = -32768; + +const int INT32_MIN = -2147483648; + +const int INT64_MIN = -9223372036854775808; + const int UINT8_MAX = 255; const int UINT16_MAX = 65535; @@ -149,77 +199,575 @@ const int UINT_LEAST64_MAX = -1; const int INT_FAST8_MIN = -128; -const int INT_FAST16_MIN = -9223372036854775808; +const int INT_FAST16_MIN = -32768; -const int INT_FAST32_MIN = -9223372036854775808; +const int INT_FAST32_MIN = -2147483648; const int INT_FAST64_MIN = -9223372036854775808; const int INT_FAST8_MAX = 127; -const int INT_FAST16_MAX = 9223372036854775807; +const int INT_FAST16_MAX = 32767; -const int INT_FAST32_MAX = 9223372036854775807; +const int INT_FAST32_MAX = 2147483647; const int INT_FAST64_MAX = 9223372036854775807; const int UINT_FAST8_MAX = 255; -const int UINT_FAST16_MAX = -1; +const int UINT_FAST16_MAX = 65535; -const int UINT_FAST32_MAX = -1; +const int UINT_FAST32_MAX = 4294967295; const int UINT_FAST64_MAX = -1; -const int INTPTR_MIN = -9223372036854775808; - const int INTPTR_MAX = 9223372036854775807; -const int UINTPTR_MAX = -1; +const int INTPTR_MIN = -9223372036854775808; -const int INTMAX_MIN = -9223372036854775808; +const int UINTPTR_MAX = -1; const int INTMAX_MAX = 9223372036854775807; const int UINTMAX_MAX = -1; +const int INTMAX_MIN = -9223372036854775808; + const int PTRDIFF_MIN = -9223372036854775808; const int PTRDIFF_MAX = 9223372036854775807; +const int SIZE_MAX = -1; + +const int RSIZE_MAX = 9223372036854775807; + +const int WCHAR_MAX = 2147483647; + +const int WCHAR_MIN = -2147483648; + +const int WINT_MIN = -2147483648; + +const int WINT_MAX = 2147483647; + const int SIG_ATOMIC_MIN = -2147483648; const int SIG_ATOMIC_MAX = 2147483647; -const int SIZE_MAX = -1; +const int MAC_OS_X_VERSION_10_0 = 1000; -const int WCHAR_MIN = -2147483648; +const int MAC_OS_X_VERSION_10_1 = 1010; -const int WCHAR_MAX = 2147483647; +const int MAC_OS_X_VERSION_10_2 = 1020; -const int WINT_MIN = 0; +const int MAC_OS_X_VERSION_10_3 = 1030; -const int WINT_MAX = 4294967295; +const int MAC_OS_X_VERSION_10_4 = 1040; -const int NULL = 0; +const int MAC_OS_X_VERSION_10_5 = 1050; + +const int MAC_OS_X_VERSION_10_6 = 1060; + +const int MAC_OS_X_VERSION_10_7 = 1070; + +const int MAC_OS_X_VERSION_10_8 = 1080; + +const int MAC_OS_X_VERSION_10_9 = 1090; + +const int MAC_OS_X_VERSION_10_10 = 101000; + +const int MAC_OS_X_VERSION_10_10_2 = 101002; + +const int MAC_OS_X_VERSION_10_10_3 = 101003; + +const int MAC_OS_X_VERSION_10_11 = 101100; + +const int MAC_OS_X_VERSION_10_11_2 = 101102; + +const int MAC_OS_X_VERSION_10_11_3 = 101103; + +const int MAC_OS_X_VERSION_10_11_4 = 101104; + +const int MAC_OS_X_VERSION_10_12 = 101200; + +const int MAC_OS_X_VERSION_10_12_1 = 101201; + +const int MAC_OS_X_VERSION_10_12_2 = 101202; + +const int MAC_OS_X_VERSION_10_12_4 = 101204; + +const int MAC_OS_X_VERSION_10_13 = 101300; + +const int MAC_OS_X_VERSION_10_13_1 = 101301; + +const int MAC_OS_X_VERSION_10_13_2 = 101302; + +const int MAC_OS_X_VERSION_10_13_4 = 101304; + +const int MAC_OS_X_VERSION_10_14 = 101400; + +const int MAC_OS_X_VERSION_10_14_1 = 101401; + +const int MAC_OS_X_VERSION_10_14_4 = 101404; + +const int MAC_OS_X_VERSION_10_14_5 = 101405; + +const int MAC_OS_X_VERSION_10_14_6 = 101406; + +const int MAC_OS_X_VERSION_10_15 = 101500; + +const int MAC_OS_X_VERSION_10_15_1 = 101501; + +const int MAC_OS_X_VERSION_10_15_4 = 101504; + +const int MAC_OS_X_VERSION_10_16 = 101600; + +const int MAC_OS_VERSION_11_0 = 110000; + +const int MAC_OS_VERSION_11_1 = 110100; + +const int MAC_OS_VERSION_11_3 = 110300; + +const int MAC_OS_VERSION_11_4 = 110400; + +const int MAC_OS_VERSION_11_5 = 110500; + +const int MAC_OS_VERSION_11_6 = 110600; + +const int MAC_OS_VERSION_12_0 = 120000; + +const int MAC_OS_VERSION_12_1 = 120100; + +const int MAC_OS_VERSION_12_2 = 120200; + +const int MAC_OS_VERSION_12_3 = 120300; + +const int MAC_OS_VERSION_12_4 = 120400; + +const int MAC_OS_VERSION_12_5 = 120500; + +const int MAC_OS_VERSION_12_6 = 120600; + +const int MAC_OS_VERSION_12_7 = 120700; + +const int MAC_OS_VERSION_13_0 = 130000; + +const int MAC_OS_VERSION_13_1 = 130100; + +const int MAC_OS_VERSION_13_2 = 130200; + +const int MAC_OS_VERSION_13_3 = 130300; + +const int MAC_OS_VERSION_13_4 = 130400; + +const int MAC_OS_VERSION_13_5 = 130500; + +const int MAC_OS_VERSION_13_6 = 130600; + +const int MAC_OS_VERSION_14_0 = 140000; + +const int MAC_OS_VERSION_14_1 = 140100; + +const int MAC_OS_VERSION_14_2 = 140200; + +const int NSIG = 32; + +const int SIGHUP = 1; + +const int SIGINT = 2; + +const int SIGQUIT = 3; + +const int SIGILL = 4; + +const int SIGTRAP = 5; + +const int SIGABRT = 6; + +const int SIGIOT = 6; + +const int SIGEMT = 7; + +const int SIGFPE = 8; + +const int SIGKILL = 9; + +const int SIGBUS = 10; + +const int SIGSEGV = 11; + +const int SIGSYS = 12; + +const int SIGPIPE = 13; + +const int SIGALRM = 14; + +const int SIGTERM = 15; + +const int SIGURG = 16; + +const int SIGSTOP = 17; + +const int SIGTSTP = 18; + +const int SIGCONT = 19; + +const int SIGCHLD = 20; + +const int SIGTTIN = 21; + +const int SIGTTOU = 22; + +const int SIGIO = 23; + +const int SIGXCPU = 24; + +const int SIGXFSZ = 25; + +const int SIGVTALRM = 26; + +const int SIGPROF = 27; + +const int SIGWINCH = 28; + +const int SIGINFO = 29; + +const int SIGUSR1 = 30; + +const int SIGUSR2 = 31; + +const int SIGEV_NONE = 0; + +const int SIGEV_SIGNAL = 1; + +const int SIGEV_THREAD = 3; + +const int ILL_NOOP = 0; + +const int ILL_ILLOPC = 1; + +const int ILL_ILLTRP = 2; + +const int ILL_PRVOPC = 3; + +const int ILL_ILLOPN = 4; + +const int ILL_ILLADR = 5; + +const int ILL_PRVREG = 6; + +const int ILL_COPROC = 7; + +const int ILL_BADSTK = 8; + +const int FPE_NOOP = 0; + +const int FPE_FLTDIV = 1; + +const int FPE_FLTOVF = 2; + +const int FPE_FLTUND = 3; + +const int FPE_FLTRES = 4; + +const int FPE_FLTINV = 5; + +const int FPE_FLTSUB = 6; + +const int FPE_INTDIV = 7; + +const int FPE_INTOVF = 8; + +const int SEGV_NOOP = 0; + +const int SEGV_MAPERR = 1; + +const int SEGV_ACCERR = 2; + +const int BUS_NOOP = 0; + +const int BUS_ADRALN = 1; + +const int BUS_ADRERR = 2; + +const int BUS_OBJERR = 3; + +const int TRAP_BRKPT = 1; + +const int TRAP_TRACE = 2; + +const int CLD_NOOP = 0; + +const int CLD_EXITED = 1; + +const int CLD_KILLED = 2; + +const int CLD_DUMPED = 3; + +const int CLD_TRAPPED = 4; + +const int CLD_STOPPED = 5; + +const int CLD_CONTINUED = 6; + +const int POLL_IN = 1; + +const int POLL_OUT = 2; + +const int POLL_MSG = 3; + +const int POLL_ERR = 4; + +const int POLL_PRI = 5; + +const int POLL_HUP = 6; + +const int SA_ONSTACK = 1; + +const int SA_RESTART = 2; + +const int SA_RESETHAND = 4; + +const int SA_NOCLDSTOP = 8; + +const int SA_NODEFER = 16; + +const int SA_NOCLDWAIT = 32; + +const int SA_SIGINFO = 64; + +const int SA_USERTRAMP = 256; + +const int SA_64REGSET = 512; + +const int SA_USERSPACE_MASK = 127; + +const int SIG_BLOCK = 1; + +const int SIG_UNBLOCK = 2; + +const int SIG_SETMASK = 3; + +const int SI_USER = 65537; + +const int SI_QUEUE = 65538; + +const int SI_TIMER = 65539; + +const int SI_ASYNCIO = 65540; + +const int SI_MESGQ = 65541; + +const int SS_ONSTACK = 1; + +const int SS_DISABLE = 4; + +const int MINSIGSTKSZ = 32768; + +const int SIGSTKSZ = 131072; + +const int SV_ONSTACK = 1; + +const int SV_INTERRUPT = 2; + +const int SV_RESETHAND = 4; + +const int SV_NODEFER = 16; + +const int SV_NOCLDSTOP = 8; + +const int SV_SIGINFO = 64; + +const int PRIO_PROCESS = 0; + +const int PRIO_PGRP = 1; + +const int PRIO_USER = 2; + +const int PRIO_DARWIN_THREAD = 3; + +const int PRIO_DARWIN_PROCESS = 4; + +const int PRIO_MIN = -20; + +const int PRIO_MAX = 20; + +const int PRIO_DARWIN_BG = 4096; + +const int PRIO_DARWIN_NONUI = 4097; + +const int RUSAGE_SELF = 0; + +const int RUSAGE_CHILDREN = -1; + +const int RUSAGE_INFO_V0 = 0; + +const int RUSAGE_INFO_V1 = 1; + +const int RUSAGE_INFO_V2 = 2; + +const int RUSAGE_INFO_V3 = 3; + +const int RUSAGE_INFO_V4 = 4; + +const int RUSAGE_INFO_V5 = 5; + +const int RUSAGE_INFO_V6 = 6; + +const int RUSAGE_INFO_CURRENT = 6; + +const int RU_PROC_RUNS_RESLIDE = 1; + +const int RLIM_INFINITY = 9223372036854775807; + +const int RLIM_SAVED_MAX = 9223372036854775807; + +const int RLIM_SAVED_CUR = 9223372036854775807; + +const int RLIMIT_CPU = 0; + +const int RLIMIT_FSIZE = 1; + +const int RLIMIT_DATA = 2; + +const int RLIMIT_STACK = 3; + +const int RLIMIT_CORE = 4; + +const int RLIMIT_AS = 5; + +const int RLIMIT_RSS = 5; + +const int RLIMIT_MEMLOCK = 6; + +const int RLIMIT_NPROC = 7; + +const int RLIMIT_NOFILE = 8; + +const int RLIM_NLIMITS = 9; + +const int RLIMIT_WAKEUPS_MONITOR = 1; + +const int RLIMIT_CPU_USAGE_MONITOR = 2; + +const int RLIMIT_THREAD_CPULIMITS = 3; + +const int RLIMIT_FOOTPRINT_INTERVAL = 4; + +const int WAKEMON_ENABLE = 1; + +const int WAKEMON_DISABLE = 2; + +const int WAKEMON_GET_PARAMS = 4; + +const int WAKEMON_SET_DEFAULTS = 8; + +const int WAKEMON_MAKE_FATAL = 16; + +const int CPUMON_MAKE_FATAL = 4096; + +const int FOOTPRINT_INTERVAL_RESET = 1; + +const int IOPOL_TYPE_DISK = 0; + +const int IOPOL_TYPE_VFS_ATIME_UPDATES = 2; + +const int IOPOL_TYPE_VFS_MATERIALIZE_DATALESS_FILES = 3; + +const int IOPOL_TYPE_VFS_STATFS_NO_DATA_VOLUME = 4; + +const int IOPOL_TYPE_VFS_TRIGGER_RESOLVE = 5; + +const int IOPOL_TYPE_VFS_IGNORE_CONTENT_PROTECTION = 6; + +const int IOPOL_TYPE_VFS_IGNORE_PERMISSIONS = 7; + +const int IOPOL_TYPE_VFS_SKIP_MTIME_UPDATE = 8; + +const int IOPOL_TYPE_VFS_ALLOW_LOW_SPACE_WRITES = 9; + +const int IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY = 10; + +const int IOPOL_SCOPE_PROCESS = 0; + +const int IOPOL_SCOPE_THREAD = 1; + +const int IOPOL_SCOPE_DARWIN_BG = 2; + +const int IOPOL_DEFAULT = 0; + +const int IOPOL_IMPORTANT = 1; + +const int IOPOL_PASSIVE = 2; + +const int IOPOL_THROTTLE = 3; + +const int IOPOL_UTILITY = 4; + +const int IOPOL_STANDARD = 5; + +const int IOPOL_APPLICATION = 5; + +const int IOPOL_NORMAL = 1; + +const int IOPOL_ATIME_UPDATES_DEFAULT = 0; + +const int IOPOL_ATIME_UPDATES_OFF = 1; + +const int IOPOL_MATERIALIZE_DATALESS_FILES_DEFAULT = 0; + +const int IOPOL_MATERIALIZE_DATALESS_FILES_OFF = 1; + +const int IOPOL_MATERIALIZE_DATALESS_FILES_ON = 2; + +const int IOPOL_VFS_STATFS_NO_DATA_VOLUME_DEFAULT = 0; + +const int IOPOL_VFS_STATFS_FORCE_NO_DATA_VOLUME = 1; + +const int IOPOL_VFS_TRIGGER_RESOLVE_DEFAULT = 0; + +const int IOPOL_VFS_TRIGGER_RESOLVE_OFF = 1; + +const int IOPOL_VFS_CONTENT_PROTECTION_DEFAULT = 0; + +const int IOPOL_VFS_CONTENT_PROTECTION_IGNORE = 1; + +const int IOPOL_VFS_IGNORE_PERMISSIONS_OFF = 0; + +const int IOPOL_VFS_IGNORE_PERMISSIONS_ON = 1; + +const int IOPOL_VFS_SKIP_MTIME_UPDATE_OFF = 0; + +const int IOPOL_VFS_SKIP_MTIME_UPDATE_ON = 1; + +const int IOPOL_VFS_ALLOW_LOW_SPACE_WRITES_OFF = 0; + +const int IOPOL_VFS_ALLOW_LOW_SPACE_WRITES_ON = 1; + +const int IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_DEFAULT = 0; + +const int IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_ON = 1; + +const int IOPOL_VFS_NOCACHE_WRITE_FS_BLKSIZE_DEFAULT = 0; + +const int IOPOL_VFS_NOCACHE_WRITE_FS_BLKSIZE_ON = 1; const int WNOHANG = 1; const int WUNTRACED = 2; -const int WSTOPPED = 2; +const int WCOREFLAG = 128; const int WEXITED = 4; -const int WCONTINUED = 8; +const int WSTOPPED = 8; -const int WNOWAIT = 16777216; +const int WCONTINUED = 16; -const int RAND_MAX = 2147483647; +const int WNOWAIT = 32; -const int EXIT_FAILURE = 1; +const int WAIT_ANY = -1; -const int EXIT_SUCCESS = 0; +const int WAIT_MYPGRP = 0; const int LITTLE_ENDIAN = 1234; @@ -229,6 +777,10 @@ const int PDP_ENDIAN = 3412; const int BYTE_ORDER = 1234; -const int FD_SETSIZE = 1024; +const int NULL = 0; -const int NFDBITS = 64; +const int EXIT_FAILURE = 1; + +const int EXIT_SUCCESS = 0; + +const int RAND_MAX = 2147483647; diff --git a/lib/tor.dart b/lib/tor.dart index 49d91e6..f06b089 100644 --- a/lib/tor.dart +++ b/lib/tor.dart @@ -11,7 +11,7 @@ import 'dart:math'; import 'package:ffi/ffi.dart'; import 'package:flutter/foundation.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:tor/generated_bindings.dart'; +import 'package:tor/generated_bindings.dart' as rust; DynamicLibrary load(name) { if (Platform.isAndroid || Platform.isLinux) { @@ -40,6 +40,7 @@ class Tor { static late DynamicLibrary _lib; Pointer _clientPtr = nullptr; + Pointer _proxyPtr = nullptr; /// Flag to indicate that Tor proxy has started. Traffic is routed through it only if it is also [enabled]. bool get started => _started; @@ -162,27 +163,27 @@ class Tor { int newPort = await _getRandomUnusedPort(); // Start the Tor service in an isolate. - int ptr = await Isolate.run(() async { + final tor = await Isolate.run(() async { // Load the Tor library. - var lib = NativeLibrary(load(libName)); + var lib = rust.NativeLibrary(load(libName)); // Start the Tor service. - final ptr = lib.tor_start( + final tor = lib.tor_start( newPort, stateDir.path.toNativeUtf8() as Pointer, cacheDir.path.toNativeUtf8() as Pointer); // Throw an exception if the Tor service fails to start. - if (ptr == nullptr) { + if (tor.client == nullptr) { throwRustException(lib); } - // Return the pointer. - return ptr.address; + return tor; }); // Set the client pointer and started flag. - _clientPtr = Pointer.fromAddress(ptr); + _clientPtr = Pointer.fromAddress(tor.client.address); + _proxyPtr = Pointer.fromAddress(tor.proxy.address); _started = true; // Bootstrap the Tor service. @@ -205,10 +206,10 @@ class Tor { /// Returns void. void bootstrap() { // Load the Tor library. - final lib = NativeLibrary(_lib); + final lib = rust.NativeLibrary(_lib); // Bootstrap the Tor service. - _bootstrapped = lib.tor_bootstrap(_clientPtr); + _bootstrapped = lib.tor_client_bootstrap(_clientPtr); // Throw an exception if the Tor service fails to bootstrap. if (!bootstrapped) { @@ -222,10 +223,18 @@ class Tor { broadcastState(); } - void restart() { - // TODO: arti seems to recover by itself and there is no client restart fn - // TODO: but follow up with them if restart is truly unnecessary - // if (enabled && started && circuitEstablished) {} + /// Restart the proxy on a new port + void restart() async { + // Load the Tor library. + final lib = rust.NativeLibrary(_lib); + final Pointer tor = calloc(); + + tor.ref.proxy = _proxyPtr; + tor.ref.client = _clientPtr; + + final newPort = await _getRandomUnusedPort(); + _proxyPtr = lib.tor_proxy_restart(tor.ref, newPort).proxy; + _proxyPort = newPort; } Future isReady() async { @@ -247,7 +256,7 @@ class Tor { })); } - static throwRustException(NativeLibrary lib) { + static throwRustException(rust.NativeLibrary lib) { String rustError = lib.tor_last_error_message().cast().toDartString(); throw _getRustException(rustError); @@ -262,6 +271,6 @@ class Tor { } void hello() { - NativeLibrary(_lib).tor_hello(); + rust.NativeLibrary(_lib).tor_hello(); } } diff --git a/lib/util.dart b/lib/util.dart index 6115615..44b7c28 100644 --- a/lib/util.dart +++ b/lib/util.dart @@ -2,13 +2,13 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import 'package:tor/generated_bindings.dart'; +import 'package:tor/generated_bindings.dart' as rust; import 'package:tor/tor.dart'; int getNofileLimit() { - return NativeLibrary(load(Tor.libName)).tor_get_nofile_limit(); + return rust.NativeLibrary(load(Tor.libName)).tor_get_nofile_limit(); } int setNofileLimit(int limit) { - return NativeLibrary(load(Tor.libName)).tor_set_nofile_limit(limit); + return rust.NativeLibrary(load(Tor.libName)).tor_set_nofile_limit(limit); } diff --git a/pubspec.yaml b/pubspec.yaml index 292f264..77f5967 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: tor description: A multi-platform Flutter plugin for managing a Tor proxy. Based on arti. -version: 0.0.2 +version: 0.0.3 homepage: https://github.com/Foundation-Devices/tor platforms: @@ -8,7 +8,7 @@ platforms: ios: linux: macos: - windows: # Not tested but it should work + windows: environment: sdk: '>=3.0.0 <4.0.0' diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 2184d12..a572d4a 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "arrayvec" @@ -3239,8 +3239,9 @@ dependencies = [ [[package]] name = "tor" -version = "0.1.0" +version = "0.0.3" dependencies = [ + "anyhow", "arti", "arti-client", "cbindgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index aa914f1..13af64a 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "tor" -version = "0.1.0" +version = "0.0.3" authors = ["Igor Cota "] edition = "2021" @@ -21,6 +21,7 @@ tor-config = "0.10.0" log = "0.4.20" #android_log-sys = "0.3.1" rlimit = "0.10.1" +anyhow = "1.0.79" [build-dependencies] cbindgen = "= 0.24.3" diff --git a/rust/build.rs b/rust/build.rs index 7939de0..d395f3c 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -21,9 +21,9 @@ fn main() { ..Default::default() }; - cbindgen::generate_with_config(&crate_dir, config) + cbindgen::generate_with_config(crate_dir, config) .unwrap() - .write_to_file(&output_file); + .write_to_file(output_file); } fn target_dir() -> PathBuf { diff --git a/rust/src/lib.rs b/rust/src/lib.rs index a495c62..b6a7f8a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -10,6 +10,7 @@ use lazy_static::lazy_static; use std::ffi::{c_char, c_void, CStr}; use std::{io, ptr}; use tokio::runtime::{Builder, Runtime}; +use tokio::task::JoinHandle; use tor_config::Listen; use tor_rtcompat::tokio::TokioNativeTlsRuntime; use tor_rtcompat::BlockOn; @@ -28,13 +29,22 @@ lazy_static! { static ref RUNTIME: io::Result = Builder::new_multi_thread().enable_all().build(); } +#[repr(C)] +pub struct Tor { + client: *mut c_void, + proxy: *mut c_void, +} + #[no_mangle] pub unsafe extern "C" fn tor_start( socks_port: u16, state_dir: *const c_char, cache_dir: *const c_char, -) -> *mut c_void { - let err_ret = ptr::null_mut(); +) -> Tor { + let err_ret = Tor { + client: ptr::null_mut(), + proxy: ptr::null_mut(), + }; let state_dir = unwrap_or_return!(CStr::from_ptr(state_dir).to_str(), err_ret); let cache_dir = unwrap_or_return!(CStr::from_ptr(cache_dir).to_str(), err_ret); @@ -60,25 +70,19 @@ pub unsafe extern "C" fn tor_start( err_ret ); - let client_clone = client.clone(); - - println!("Starting proxy!"); - let rt = RUNTIME.as_ref().unwrap(); - let handle = rt.spawn(socks::run_socks_proxy( - runtime.clone(), - client_clone, - Listen::new_localhost(socks_port), - )); + //let client_clone = client.clone(); - let handle_box = Box::new(handle); - Box::leak(handle_box); + let proxy_handle_box = Box::new(start_proxy(socks_port, client.clone())); + let client_box = Box::new(client.clone()); - let client_box = Box::new(client); - Box::into_raw(client_box) as *mut c_void + Tor { + client: Box::into_raw(client_box) as *mut c_void, + proxy: Box::into_raw(proxy_handle_box) as *mut c_void, + } } #[no_mangle] -pub unsafe extern "C" fn tor_bootstrap(client: *mut c_void) -> bool { +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) @@ -88,6 +92,47 @@ pub unsafe extern "C" fn tor_bootstrap(client: *mut c_void) -> bool { true } +#[no_mangle] +pub unsafe extern "C" fn tor_proxy_stop(proxy: *mut c_void) -> bool { + let proxy = { + assert!(!proxy.is_null()); + Box::from_raw(proxy as *mut JoinHandle>) + }; + + proxy.abort(); + true +} + +#[no_mangle] +pub unsafe extern "C" fn tor_proxy_restart(tor: Tor, port: u16) -> Tor { + tor_proxy_stop(tor.proxy); + + let client_box = { + assert!(!tor.client.is_null()); + Box::from_raw(tor.client as *mut TorClient) + }; + + let proxy_box = Box::new(start_proxy(port, *client_box.clone())); + + Tor { + client: Box::into_raw(client_box) as *mut c_void, + proxy: Box::into_raw(proxy_box) as *mut c_void, + } +} + +fn start_proxy( + port: u16, + client: TorClient, +) -> JoinHandle> { + println!("Starting proxy!"); + let rt = RUNTIME.as_ref().unwrap(); + rt.spawn(socks::run_socks_proxy( + client.runtime().clone(), + client.clone(), + Listen::new_localhost(port), + )) +} + // Due to its simple signature this dummy function is the one added (unused) to iOS swift codebase to force Xcode to link the lib #[no_mangle] pub unsafe extern "C" fn tor_hello() { diff --git a/rust/target/tor.h b/rust/target/tor.h index 3804ada..32f049b 100644 --- a/rust/target/tor.h +++ b/rust/target/tor.h @@ -3,9 +3,18 @@ #include #include -void *tor_start(uint16_t socks_port, const char *state_dir, const char *cache_dir); +typedef struct Tor { + void *client; + void *proxy; +} Tor; -bool tor_bootstrap(void *client); +struct Tor tor_start(uint16_t socks_port, const char *state_dir, const char *cache_dir); + +bool tor_client_bootstrap(void *client); + +bool tor_proxy_stop(void *proxy); + +struct Tor tor_proxy_restart(struct Tor tor, uint16_t port); void tor_hello(void);