import tor package
This commit is contained in:
@@ -0,0 +1,542 @@
|
||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||
//
|
||||
// Generated by `package:ffigen`.
|
||||
// ignore_for_file: type=lint
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
class NativeLibrary {
|
||||
/// Holds the symbol lookup function.
|
||||
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||
_lookup;
|
||||
|
||||
/// The symbols are looked up in [dynamicLibrary].
|
||||
NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
|
||||
: _lookup = dynamicLibrary.lookup;
|
||||
|
||||
/// The symbols are looked up with [lookup].
|
||||
NativeLibrary.fromLookup(
|
||||
ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||
lookup)
|
||||
: _lookup = lookup;
|
||||
|
||||
Tor tor_start(
|
||||
int socks_port,
|
||||
ffi.Pointer<ffi.Char> state_dir,
|
||||
ffi.Pointer<ffi.Char> cache_dir,
|
||||
int obfs4_port,
|
||||
int snowflake_port,
|
||||
ffi.Pointer<ffi.Char> bridge_lines,
|
||||
) {
|
||||
return _tor_start(
|
||||
socks_port,
|
||||
state_dir,
|
||||
cache_dir,
|
||||
obfs4_port,
|
||||
snowflake_port,
|
||||
bridge_lines,
|
||||
);
|
||||
}
|
||||
|
||||
late final _tor_startPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
Tor Function(ffi.Uint16, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>,
|
||||
ffi.Uint16, ffi.Uint16, ffi.Pointer<ffi.Char>)>>('tor_start');
|
||||
late final _tor_start = _tor_startPtr.asFunction<
|
||||
Tor Function(int, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int, int,
|
||||
ffi.Pointer<ffi.Char>)>();
|
||||
|
||||
bool tor_reconfigure(
|
||||
ffi.Pointer<ffi.Void> client,
|
||||
ffi.Pointer<ffi.Char> state_dir,
|
||||
ffi.Pointer<ffi.Char> cache_dir,
|
||||
int obfs4_port,
|
||||
int snowflake_port,
|
||||
ffi.Pointer<ffi.Char> bridge_lines,
|
||||
) {
|
||||
return _tor_reconfigure(
|
||||
client,
|
||||
state_dir,
|
||||
cache_dir,
|
||||
obfs4_port,
|
||||
snowflake_port,
|
||||
bridge_lines,
|
||||
);
|
||||
}
|
||||
|
||||
late final _tor_reconfigurePtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Bool Function(
|
||||
ffi.Pointer<ffi.Void>,
|
||||
ffi.Pointer<ffi.Char>,
|
||||
ffi.Pointer<ffi.Char>,
|
||||
ffi.Uint16,
|
||||
ffi.Uint16,
|
||||
ffi.Pointer<ffi.Char>)>>('tor_reconfigure');
|
||||
late final _tor_reconfigure = _tor_reconfigurePtr.asFunction<
|
||||
bool Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>,
|
||||
ffi.Pointer<ffi.Char>, int, int, ffi.Pointer<ffi.Char>)>();
|
||||
|
||||
bool tor_client_bootstrap(
|
||||
ffi.Pointer<ffi.Void> client,
|
||||
) {
|
||||
return _tor_client_bootstrap(
|
||||
client,
|
||||
);
|
||||
}
|
||||
|
||||
late final _tor_client_bootstrapPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Void>)>>(
|
||||
'tor_client_bootstrap');
|
||||
late final _tor_client_bootstrap = _tor_client_bootstrapPtr
|
||||
.asFunction<bool Function(ffi.Pointer<ffi.Void>)>();
|
||||
|
||||
void tor_client_set_dormant(
|
||||
ffi.Pointer<ffi.Void> client,
|
||||
bool soft_mode,
|
||||
) {
|
||||
return _tor_client_set_dormant(
|
||||
client,
|
||||
soft_mode,
|
||||
);
|
||||
}
|
||||
|
||||
late final _tor_client_set_dormantPtr = _lookup<
|
||||
ffi
|
||||
.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Bool)>>(
|
||||
'tor_client_set_dormant');
|
||||
late final _tor_client_set_dormant = _tor_client_set_dormantPtr
|
||||
.asFunction<void Function(ffi.Pointer<ffi.Void>, bool)>();
|
||||
|
||||
void tor_proxy_stop(
|
||||
ffi.Pointer<ffi.Void> proxy,
|
||||
) {
|
||||
return _tor_proxy_stop(
|
||||
proxy,
|
||||
);
|
||||
}
|
||||
|
||||
late final _tor_proxy_stopPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
|
||||
'tor_proxy_stop');
|
||||
late final _tor_proxy_stop =
|
||||
_tor_proxy_stopPtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
|
||||
|
||||
void tor_hello() {
|
||||
return _tor_hello();
|
||||
}
|
||||
|
||||
late final _tor_helloPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Void Function()>>('tor_hello');
|
||||
late final _tor_hello = _tor_helloPtr.asFunction<void Function()>();
|
||||
|
||||
ffi.Pointer<ffi.Char> tor_last_error_message() {
|
||||
return _tor_last_error_message();
|
||||
}
|
||||
|
||||
late final _tor_last_error_messagePtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
|
||||
'tor_last_error_message');
|
||||
late final _tor_last_error_message =
|
||||
_tor_last_error_messagePtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
|
||||
|
||||
int tor_get_nofile_limit() {
|
||||
return _tor_get_nofile_limit();
|
||||
}
|
||||
|
||||
late final _tor_get_nofile_limitPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Uint64 Function()>>(
|
||||
'tor_get_nofile_limit');
|
||||
late final _tor_get_nofile_limit =
|
||||
_tor_get_nofile_limitPtr.asFunction<int Function()>();
|
||||
|
||||
int tor_set_nofile_limit(
|
||||
int limit,
|
||||
) {
|
||||
return _tor_set_nofile_limit(
|
||||
limit,
|
||||
);
|
||||
}
|
||||
|
||||
late final _tor_set_nofile_limitPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Uint64 Function(ffi.Uint64)>>(
|
||||
'tor_set_nofile_limit');
|
||||
late final _tor_set_nofile_limit =
|
||||
_tor_set_nofile_limitPtr.asFunction<int Function(int)>();
|
||||
}
|
||||
|
||||
typedef __u_char = ffi.UnsignedChar;
|
||||
typedef Dart__u_char = int;
|
||||
typedef __u_short = ffi.UnsignedShort;
|
||||
typedef Dart__u_short = int;
|
||||
typedef __u_int = ffi.UnsignedInt;
|
||||
typedef Dart__u_int = int;
|
||||
typedef __u_long = ffi.UnsignedLong;
|
||||
typedef Dart__u_long = int;
|
||||
typedef __int8_t = ffi.SignedChar;
|
||||
typedef Dart__int8_t = int;
|
||||
typedef __uint8_t = ffi.UnsignedChar;
|
||||
typedef Dart__uint8_t = int;
|
||||
typedef __int16_t = ffi.Short;
|
||||
typedef Dart__int16_t = int;
|
||||
typedef __uint16_t = ffi.UnsignedShort;
|
||||
typedef Dart__uint16_t = int;
|
||||
typedef __int32_t = ffi.Int;
|
||||
typedef Dart__int32_t = int;
|
||||
typedef __uint32_t = ffi.UnsignedInt;
|
||||
typedef Dart__uint32_t = int;
|
||||
typedef __int64_t = ffi.Long;
|
||||
typedef Dart__int64_t = int;
|
||||
typedef __uint64_t = ffi.UnsignedLong;
|
||||
typedef Dart__uint64_t = int;
|
||||
typedef __int_least8_t = __int8_t;
|
||||
typedef __uint_least8_t = __uint8_t;
|
||||
typedef __int_least16_t = __int16_t;
|
||||
typedef __uint_least16_t = __uint16_t;
|
||||
typedef __int_least32_t = __int32_t;
|
||||
typedef __uint_least32_t = __uint32_t;
|
||||
typedef __int_least64_t = __int64_t;
|
||||
typedef __uint_least64_t = __uint64_t;
|
||||
typedef __quad_t = ffi.Long;
|
||||
typedef Dart__quad_t = int;
|
||||
typedef __u_quad_t = ffi.UnsignedLong;
|
||||
typedef Dart__u_quad_t = int;
|
||||
typedef __intmax_t = ffi.Long;
|
||||
typedef Dart__intmax_t = int;
|
||||
typedef __uintmax_t = ffi.UnsignedLong;
|
||||
typedef Dart__uintmax_t = int;
|
||||
typedef __dev_t = ffi.UnsignedLong;
|
||||
typedef Dart__dev_t = int;
|
||||
typedef __uid_t = ffi.UnsignedInt;
|
||||
typedef Dart__uid_t = int;
|
||||
typedef __gid_t = ffi.UnsignedInt;
|
||||
typedef Dart__gid_t = int;
|
||||
typedef __ino_t = ffi.UnsignedLong;
|
||||
typedef Dart__ino_t = int;
|
||||
typedef __ino64_t = ffi.UnsignedLong;
|
||||
typedef Dart__ino64_t = int;
|
||||
typedef __mode_t = ffi.UnsignedInt;
|
||||
typedef Dart__mode_t = int;
|
||||
typedef __nlink_t = ffi.UnsignedLong;
|
||||
typedef Dart__nlink_t = int;
|
||||
typedef __off_t = ffi.Long;
|
||||
typedef Dart__off_t = int;
|
||||
typedef __off64_t = ffi.Long;
|
||||
typedef Dart__off64_t = int;
|
||||
typedef __pid_t = ffi.Int;
|
||||
typedef Dart__pid_t = int;
|
||||
|
||||
final class __fsid_t extends ffi.Struct {
|
||||
@ffi.Array.multi([2])
|
||||
external ffi.Array<ffi.Int> __val;
|
||||
}
|
||||
|
||||
typedef __clock_t = ffi.Long;
|
||||
typedef Dart__clock_t = int;
|
||||
typedef __rlim_t = ffi.UnsignedLong;
|
||||
typedef Dart__rlim_t = int;
|
||||
typedef __rlim64_t = ffi.UnsignedLong;
|
||||
typedef Dart__rlim64_t = int;
|
||||
typedef __id_t = ffi.UnsignedInt;
|
||||
typedef Dart__id_t = int;
|
||||
typedef __time_t = ffi.Long;
|
||||
typedef Dart__time_t = int;
|
||||
typedef __useconds_t = ffi.UnsignedInt;
|
||||
typedef Dart__useconds_t = int;
|
||||
typedef __suseconds_t = ffi.Long;
|
||||
typedef Dart__suseconds_t = int;
|
||||
typedef __suseconds64_t = ffi.Long;
|
||||
typedef Dart__suseconds64_t = int;
|
||||
typedef __daddr_t = ffi.Int;
|
||||
typedef Dart__daddr_t = int;
|
||||
typedef __key_t = ffi.Int;
|
||||
typedef Dart__key_t = int;
|
||||
typedef __clockid_t = ffi.Int;
|
||||
typedef Dart__clockid_t = int;
|
||||
typedef __timer_t = ffi.Pointer<ffi.Void>;
|
||||
typedef __blksize_t = ffi.Long;
|
||||
typedef Dart__blksize_t = int;
|
||||
typedef __blkcnt_t = ffi.Long;
|
||||
typedef Dart__blkcnt_t = int;
|
||||
typedef __blkcnt64_t = ffi.Long;
|
||||
typedef Dart__blkcnt64_t = int;
|
||||
typedef __fsblkcnt_t = ffi.UnsignedLong;
|
||||
typedef Dart__fsblkcnt_t = int;
|
||||
typedef __fsblkcnt64_t = ffi.UnsignedLong;
|
||||
typedef Dart__fsblkcnt64_t = int;
|
||||
typedef __fsfilcnt_t = ffi.UnsignedLong;
|
||||
typedef Dart__fsfilcnt_t = int;
|
||||
typedef __fsfilcnt64_t = ffi.UnsignedLong;
|
||||
typedef Dart__fsfilcnt64_t = int;
|
||||
typedef __fsword_t = ffi.Long;
|
||||
typedef Dart__fsword_t = int;
|
||||
typedef __ssize_t = ffi.Long;
|
||||
typedef Dart__ssize_t = int;
|
||||
typedef __syscall_slong_t = ffi.Long;
|
||||
typedef Dart__syscall_slong_t = int;
|
||||
typedef __syscall_ulong_t = ffi.UnsignedLong;
|
||||
typedef Dart__syscall_ulong_t = int;
|
||||
typedef __loff_t = __off64_t;
|
||||
typedef __caddr_t = ffi.Pointer<ffi.Char>;
|
||||
typedef __intptr_t = ffi.Long;
|
||||
typedef Dart__intptr_t = int;
|
||||
typedef __socklen_t = ffi.UnsignedInt;
|
||||
typedef Dart__socklen_t = int;
|
||||
typedef __sig_atomic_t = ffi.Int;
|
||||
typedef Dart__sig_atomic_t = int;
|
||||
typedef int_least8_t = __int_least8_t;
|
||||
typedef int_least16_t = __int_least16_t;
|
||||
typedef int_least32_t = __int_least32_t;
|
||||
typedef int_least64_t = __int_least64_t;
|
||||
typedef uint_least8_t = __uint_least8_t;
|
||||
typedef uint_least16_t = __uint_least16_t;
|
||||
typedef uint_least32_t = __uint_least32_t;
|
||||
typedef uint_least64_t = __uint_least64_t;
|
||||
typedef int_fast8_t = ffi.SignedChar;
|
||||
typedef Dartint_fast8_t = int;
|
||||
typedef int_fast16_t = ffi.Long;
|
||||
typedef Dartint_fast16_t = int;
|
||||
typedef int_fast32_t = ffi.Long;
|
||||
typedef Dartint_fast32_t = int;
|
||||
typedef int_fast64_t = ffi.Long;
|
||||
typedef Dartint_fast64_t = int;
|
||||
typedef uint_fast8_t = ffi.UnsignedChar;
|
||||
typedef Dartuint_fast8_t = int;
|
||||
typedef uint_fast16_t = ffi.UnsignedLong;
|
||||
typedef Dartuint_fast16_t = int;
|
||||
typedef uint_fast32_t = ffi.UnsignedLong;
|
||||
typedef Dartuint_fast32_t = int;
|
||||
typedef uint_fast64_t = ffi.UnsignedLong;
|
||||
typedef Dartuint_fast64_t = int;
|
||||
typedef intmax_t = __intmax_t;
|
||||
typedef uintmax_t = __uintmax_t;
|
||||
typedef _Float32 = ffi.Float;
|
||||
typedef Dart_Float32 = double;
|
||||
typedef _Float64 = ffi.Double;
|
||||
typedef Dart_Float64 = double;
|
||||
typedef _Float32x = ffi.Double;
|
||||
typedef Dart_Float32x = double;
|
||||
typedef u_char = __u_char;
|
||||
typedef u_short = __u_short;
|
||||
typedef u_int = __u_int;
|
||||
typedef u_long = __u_long;
|
||||
typedef quad_t = __quad_t;
|
||||
typedef u_quad_t = __u_quad_t;
|
||||
typedef fsid_t = __fsid_t;
|
||||
typedef loff_t = __loff_t;
|
||||
typedef ino_t = __ino_t;
|
||||
typedef dev_t = __dev_t;
|
||||
typedef gid_t = __gid_t;
|
||||
typedef mode_t = __mode_t;
|
||||
typedef nlink_t = __nlink_t;
|
||||
typedef uid_t = __uid_t;
|
||||
typedef off_t = __off_t;
|
||||
typedef pid_t = __pid_t;
|
||||
typedef id_t = __id_t;
|
||||
typedef ssize_t = __ssize_t;
|
||||
typedef daddr_t = __daddr_t;
|
||||
typedef caddr_t = __caddr_t;
|
||||
typedef key_t = __key_t;
|
||||
typedef clock_t = __clock_t;
|
||||
typedef clockid_t = __clockid_t;
|
||||
typedef time_t = __time_t;
|
||||
typedef timer_t = __timer_t;
|
||||
typedef ulong = ffi.UnsignedLong;
|
||||
typedef Dartulong = int;
|
||||
typedef ushort = ffi.UnsignedShort;
|
||||
typedef Dartushort = int;
|
||||
typedef uint = ffi.UnsignedInt;
|
||||
typedef Dartuint = int;
|
||||
typedef u_int8_t = __uint8_t;
|
||||
typedef u_int16_t = __uint16_t;
|
||||
typedef u_int32_t = __uint32_t;
|
||||
typedef u_int64_t = __uint64_t;
|
||||
typedef register_t = ffi.Long;
|
||||
typedef Dartregister_t = int;
|
||||
|
||||
final class __sigset_t extends ffi.Struct {
|
||||
@ffi.Array.multi([16])
|
||||
external ffi.Array<ffi.UnsignedLong> __val;
|
||||
}
|
||||
|
||||
typedef sigset_t = __sigset_t;
|
||||
typedef suseconds_t = __suseconds_t;
|
||||
typedef __fd_mask = ffi.Long;
|
||||
typedef Dart__fd_mask = int;
|
||||
typedef fd_mask = __fd_mask;
|
||||
typedef blksize_t = __blksize_t;
|
||||
typedef blkcnt_t = __blkcnt_t;
|
||||
typedef fsblkcnt_t = __fsblkcnt_t;
|
||||
typedef fsfilcnt_t = __fsfilcnt_t;
|
||||
|
||||
final class __pthread_internal_list extends ffi.Struct {
|
||||
external ffi.Pointer<__pthread_internal_list> __prev;
|
||||
|
||||
external ffi.Pointer<__pthread_internal_list> __next;
|
||||
}
|
||||
|
||||
typedef __pthread_list_t = __pthread_internal_list;
|
||||
|
||||
final class __pthread_internal_slist extends ffi.Struct {
|
||||
external ffi.Pointer<__pthread_internal_slist> __next;
|
||||
}
|
||||
|
||||
typedef __pthread_slist_t = __pthread_internal_slist;
|
||||
typedef __tss_t = ffi.UnsignedInt;
|
||||
typedef Dart__tss_t = int;
|
||||
typedef __thrd_t = ffi.UnsignedLong;
|
||||
typedef Dart__thrd_t = int;
|
||||
typedef pthread_t = ffi.UnsignedLong;
|
||||
typedef Dartpthread_t = int;
|
||||
typedef pthread_key_t = ffi.UnsignedInt;
|
||||
typedef Dartpthread_key_t = int;
|
||||
typedef pthread_once_t = ffi.Int;
|
||||
typedef Dartpthread_once_t = int;
|
||||
typedef __compar_fn_tFunction = ffi.Int Function(
|
||||
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>);
|
||||
typedef Dart__compar_fn_tFunction = int Function(
|
||||
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>);
|
||||
typedef __compar_fn_t = ffi.Pointer<ffi.NativeFunction<__compar_fn_tFunction>>;
|
||||
|
||||
final class Tor extends ffi.Struct {
|
||||
external ffi.Pointer<ffi.Void> client;
|
||||
|
||||
external ffi.Pointer<ffi.Void> proxy;
|
||||
}
|
||||
|
||||
const int true$ = 1;
|
||||
|
||||
const int false$ = 0;
|
||||
|
||||
const int INT8_MIN = -128;
|
||||
|
||||
const int INT16_MIN = -32768;
|
||||
|
||||
const int INT32_MIN = -2147483648;
|
||||
|
||||
const int INT64_MIN = -9223372036854775808;
|
||||
|
||||
const int INT8_MAX = 127;
|
||||
|
||||
const int INT16_MAX = 32767;
|
||||
|
||||
const int INT32_MAX = 2147483647;
|
||||
|
||||
const int INT64_MAX = 9223372036854775807;
|
||||
|
||||
const int UINT8_MAX = 255;
|
||||
|
||||
const int UINT16_MAX = 65535;
|
||||
|
||||
const int UINT32_MAX = 4294967295;
|
||||
|
||||
const int UINT64_MAX = -1;
|
||||
|
||||
const int INT_LEAST8_MIN = -128;
|
||||
|
||||
const int INT_LEAST16_MIN = -32768;
|
||||
|
||||
const int INT_LEAST32_MIN = -2147483648;
|
||||
|
||||
const int INT_LEAST64_MIN = -9223372036854775808;
|
||||
|
||||
const int INT_LEAST8_MAX = 127;
|
||||
|
||||
const int INT_LEAST16_MAX = 32767;
|
||||
|
||||
const int INT_LEAST32_MAX = 2147483647;
|
||||
|
||||
const int INT_LEAST64_MAX = 9223372036854775807;
|
||||
|
||||
const int UINT_LEAST8_MAX = 255;
|
||||
|
||||
const int UINT_LEAST16_MAX = 65535;
|
||||
|
||||
const int UINT_LEAST32_MAX = 4294967295;
|
||||
|
||||
const int UINT_LEAST64_MAX = -1;
|
||||
|
||||
const int INT_FAST8_MIN = -128;
|
||||
|
||||
const int INT_FAST16_MIN = -9223372036854775808;
|
||||
|
||||
const int INT_FAST32_MIN = -9223372036854775808;
|
||||
|
||||
const int INT_FAST64_MIN = -9223372036854775808;
|
||||
|
||||
const int INT_FAST8_MAX = 127;
|
||||
|
||||
const int INT_FAST16_MAX = 9223372036854775807;
|
||||
|
||||
const int INT_FAST32_MAX = 9223372036854775807;
|
||||
|
||||
const int INT_FAST64_MAX = 9223372036854775807;
|
||||
|
||||
const int UINT_FAST8_MAX = 255;
|
||||
|
||||
const int UINT_FAST16_MAX = -1;
|
||||
|
||||
const int UINT_FAST32_MAX = -1;
|
||||
|
||||
const int UINT_FAST64_MAX = -1;
|
||||
|
||||
const int INTPTR_MIN = -9223372036854775808;
|
||||
|
||||
const int INTPTR_MAX = 9223372036854775807;
|
||||
|
||||
const int UINTPTR_MAX = -1;
|
||||
|
||||
const int INTMAX_MIN = -9223372036854775808;
|
||||
|
||||
const int INTMAX_MAX = 9223372036854775807;
|
||||
|
||||
const int UINTMAX_MAX = -1;
|
||||
|
||||
const int PTRDIFF_MIN = -9223372036854775808;
|
||||
|
||||
const int PTRDIFF_MAX = 9223372036854775807;
|
||||
|
||||
const int SIG_ATOMIC_MIN = -2147483648;
|
||||
|
||||
const int SIG_ATOMIC_MAX = 2147483647;
|
||||
|
||||
const int SIZE_MAX = -1;
|
||||
|
||||
const int WCHAR_MIN = -2147483648;
|
||||
|
||||
const int WCHAR_MAX = 2147483647;
|
||||
|
||||
const int WINT_MIN = 0;
|
||||
|
||||
const int WINT_MAX = 4294967295;
|
||||
|
||||
const int NULL = 0;
|
||||
|
||||
const int WNOHANG = 1;
|
||||
|
||||
const int WUNTRACED = 2;
|
||||
|
||||
const int WSTOPPED = 2;
|
||||
|
||||
const int WEXITED = 4;
|
||||
|
||||
const int WCONTINUED = 8;
|
||||
|
||||
const int WNOWAIT = 16777216;
|
||||
|
||||
const int RAND_MAX = 2147483647;
|
||||
|
||||
const int EXIT_FAILURE = 1;
|
||||
|
||||
const int EXIT_SUCCESS = 0;
|
||||
|
||||
const int LITTLE_ENDIAN = 1234;
|
||||
|
||||
const int BIG_ENDIAN = 4321;
|
||||
|
||||
const int PDP_ENDIAN = 3412;
|
||||
|
||||
const int BYTE_ORDER = 1234;
|
||||
|
||||
const int FD_SETSIZE = 1024;
|
||||
|
||||
const int NFDBITS = 64;
|
||||
@@ -0,0 +1,375 @@
|
||||
// SPDX-FileCopyrightText: 2024 Cypher Stack LLC
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// A SOCKS5 socket.
|
||||
///
|
||||
/// A Dart 3 Socket wrapper that implements the SOCKS5 protocol. Now with SSL!
|
||||
///
|
||||
/// Properties:
|
||||
/// - [proxyHost]: The host of the SOCKS5 proxy server.
|
||||
/// - [proxyPort]: The port of the SOCKS5 proxy server.
|
||||
/// - [_socksSocket]: The underlying Socket that connects to the SOCKS5 proxy
|
||||
/// server.
|
||||
/// - [_responseController]: A StreamController that listens to the
|
||||
/// [_socksSocket] and broadcasts the response.
|
||||
///
|
||||
/// Methods:
|
||||
/// - connect: Connects to the SOCKS5 proxy server.
|
||||
/// - connectTo: Connects to the specified [domain] and [port] through the
|
||||
/// SOCKS5 proxy server.
|
||||
/// - write: Converts [object] to a String by invoking [Object.toString] and
|
||||
/// sends the encoding of the result to the socket.
|
||||
/// - sendServerFeaturesCommand: Sends the server.features command to the
|
||||
/// proxy server.
|
||||
/// - close: Closes the connection to the Tor proxy.
|
||||
///
|
||||
/// Usage:
|
||||
/// ```dart
|
||||
/// // Instantiate a socks socket at localhost and on the port selected by the
|
||||
/// // tor service.
|
||||
/// var socksSocket = await SOCKSSocket.create(
|
||||
/// proxyHost: InternetAddress.loopbackIPv4.address,
|
||||
/// proxyPort: tor.port,
|
||||
/// // sslEnabled: true, // For SSL connections.
|
||||
/// );
|
||||
///
|
||||
/// // Connect to the socks instantiated above.
|
||||
/// await socksSocket.connect();
|
||||
///
|
||||
/// // Connect to bitcoincash.stackwallet.com on port 50001 via socks socket.
|
||||
/// await socksSocket.connectTo(
|
||||
/// 'bitcoincash.stackwallet.com', 50001);
|
||||
///
|
||||
/// // Send a server features command to the connected socket, see method for
|
||||
/// // more specific usage example..
|
||||
/// await socksSocket.sendServerFeaturesCommand();
|
||||
/// await socksSocket.close();
|
||||
/// ```
|
||||
///
|
||||
/// See also:
|
||||
/// - SOCKS5 protocol(https://www.ietf.org/rfc/rfc1928.txt)
|
||||
class SOCKSSocket {
|
||||
/// The host of the SOCKS5 proxy server.
|
||||
final String proxyHost;
|
||||
|
||||
/// The port of the SOCKS5 proxy server.
|
||||
final int proxyPort;
|
||||
|
||||
/// The underlying Socket that connects to the SOCKS5 proxy server.
|
||||
late final Socket _socksSocket;
|
||||
|
||||
/// Getter for the underlying Socket that connects to the SOCKS5 proxy server.
|
||||
Socket get socket => sslEnabled ? _secureSocksSocket : _socksSocket;
|
||||
|
||||
/// A wrapper around the _socksSocket that enables SSL connections.
|
||||
late final Socket _secureSocksSocket;
|
||||
|
||||
/// A StreamController that listens to the _socksSocket and broadcasts.
|
||||
final StreamController<List<int>> _responseController =
|
||||
StreamController.broadcast();
|
||||
|
||||
/// A StreamController that listens to the _secureSocksSocket and broadcasts.
|
||||
final StreamController<List<int>> _secureResponseController =
|
||||
StreamController.broadcast();
|
||||
|
||||
/// Getter for the StreamController that listens to the _socksSocket and
|
||||
/// broadcasts, or the _secureSocksSocket and broadcasts if SSL is enabled.
|
||||
StreamController<List<int>> get responseController =>
|
||||
sslEnabled ? _secureResponseController : _responseController;
|
||||
|
||||
/// A StreamSubscription that listens to the _socksSocket or the
|
||||
/// _secureSocksSocket if SSL is enabled.
|
||||
StreamSubscription<List<int>>? _subscription;
|
||||
|
||||
/// Getter for the StreamSubscription that listens to the _socksSocket or the
|
||||
/// _secureSocksSocket if SSL is enabled.
|
||||
StreamSubscription<List<int>>? get subscription => _subscription;
|
||||
|
||||
/// Is SSL enabled?
|
||||
final bool sslEnabled;
|
||||
|
||||
/// Private constructor.
|
||||
SOCKSSocket._(this.proxyHost, this.proxyPort, this.sslEnabled);
|
||||
|
||||
/// Provides a stream of data as List<int>.
|
||||
Stream<List<int>> get inputStream => sslEnabled
|
||||
? _secureResponseController.stream
|
||||
: _responseController.stream;
|
||||
|
||||
/// Provides a StreamSink compatible with List<int> for sending data.
|
||||
StreamSink<List<int>> get outputStream {
|
||||
// Create a simple StreamSink wrapper for _socksSocket and
|
||||
// _secureSocksSocket that accepts List<int> and forwards it to write method.
|
||||
var sink = StreamController<List<int>>();
|
||||
sink.stream.listen((data) {
|
||||
if (sslEnabled) {
|
||||
_secureSocksSocket.add(data);
|
||||
} else {
|
||||
_socksSocket.add(data);
|
||||
}
|
||||
});
|
||||
return sink.sink;
|
||||
}
|
||||
|
||||
/// Creates a SOCKS5 socket to the specified [proxyHost] and [proxyPort].
|
||||
///
|
||||
/// This method is a factory constructor that returns a Future that resolves
|
||||
/// to a SOCKSSocket instance.
|
||||
///
|
||||
/// Parameters:
|
||||
/// - [proxyHost]: The host of the SOCKS5 proxy server.
|
||||
/// - [proxyPort]: The port of the SOCKS5 proxy server.
|
||||
///
|
||||
/// Returns:
|
||||
/// A Future that resolves to a SOCKSSocket instance.
|
||||
static Future<SOCKSSocket> create(
|
||||
{required String proxyHost,
|
||||
required int proxyPort,
|
||||
bool sslEnabled = false}) async {
|
||||
// Create a SOCKS socket instance.
|
||||
var instance = SOCKSSocket._(proxyHost, proxyPort, sslEnabled);
|
||||
|
||||
// Initialize the SOCKS socket.
|
||||
await instance._init();
|
||||
|
||||
// Return the SOCKS socket instance.
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// Constructor.
|
||||
SOCKSSocket(
|
||||
{required this.proxyHost,
|
||||
required this.proxyPort,
|
||||
required this.sslEnabled}) {
|
||||
_init();
|
||||
}
|
||||
|
||||
/// Initializes the SOCKS socket.
|
||||
///
|
||||
/// This method is a private method that is called by the constructor.
|
||||
///
|
||||
/// Returns:
|
||||
/// A Future that resolves to void.
|
||||
Future<void> _init() async {
|
||||
// Connect to the SOCKS proxy server.
|
||||
_socksSocket = await Socket.connect(
|
||||
proxyHost,
|
||||
proxyPort,
|
||||
);
|
||||
|
||||
// Listen to the socket.
|
||||
_subscription = _socksSocket.listen(
|
||||
(data) {
|
||||
// Add the data to the response controller.
|
||||
_responseController.add(data);
|
||||
},
|
||||
onError: (e) {
|
||||
// Handle errors.
|
||||
if (e is Object) {
|
||||
_responseController.addError(e);
|
||||
}
|
||||
|
||||
// If the error is not an object, send the error as a string.
|
||||
_responseController.addError("$e");
|
||||
// TODO make sure sending error as string is acceptable.
|
||||
},
|
||||
onDone: () {
|
||||
// Close the response controller when the socket is closed.
|
||||
// _responseController.close();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Connects to the SOCKS socket.
|
||||
///
|
||||
/// Returns:
|
||||
/// A Future that resolves to void.
|
||||
Future<void> connect() async {
|
||||
// Greeting and method selection.
|
||||
_socksSocket.add([0x05, 0x01, 0x00]);
|
||||
|
||||
// Wait for server response.
|
||||
var response = await _responseController.stream.first;
|
||||
|
||||
// Check if the connection was successful.
|
||||
if (response[1] != 0x00) {
|
||||
throw Exception(
|
||||
'socks_socket.connect(): Failed to connect to SOCKS5 proxy.');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// Connects to the specified [domain] and [port] through the SOCKS socket.
|
||||
///
|
||||
/// Parameters:
|
||||
/// - [domain]: The domain to connect to.
|
||||
/// - [port]: The port to connect to.
|
||||
///
|
||||
/// Returns:
|
||||
/// A Future that resolves to void.
|
||||
Future<void> connectTo(String domain, int port) async {
|
||||
// Connect command.
|
||||
var request = [
|
||||
0x05, // SOCKS version.
|
||||
0x01, // Connect command.
|
||||
0x00, // Reserved.
|
||||
0x03, // Domain name.
|
||||
domain.length,
|
||||
...domain.codeUnits,
|
||||
(port >> 8) & 0xFF,
|
||||
port & 0xFF
|
||||
];
|
||||
|
||||
// Send the connect command to the SOCKS proxy server.
|
||||
_socksSocket.add(request);
|
||||
|
||||
// Wait for server response.
|
||||
var response = await _responseController.stream.first;
|
||||
|
||||
// Check if the connection was successful.
|
||||
if (response[1] != 0x00) {
|
||||
throw Exception(
|
||||
'socks_socket.connectTo(): Failed to connect to target through SOCKS5 proxy.');
|
||||
}
|
||||
|
||||
// Upgrade to SSL if needed.
|
||||
if (sslEnabled) {
|
||||
// Upgrade to SSL.
|
||||
_secureSocksSocket = await SecureSocket.secure(
|
||||
_socksSocket,
|
||||
host: domain,
|
||||
// onBadCertificate: (_) => true, // Uncomment this to bypass certificate validation (NOT recommended for production).
|
||||
);
|
||||
|
||||
// Listen to the secure socket.
|
||||
_subscription = _secureSocksSocket.listen(
|
||||
(data) {
|
||||
// Add the data to the response controller.
|
||||
_secureResponseController.add(data);
|
||||
},
|
||||
onError: (e) {
|
||||
// Handle errors.
|
||||
if (e is Object) {
|
||||
_secureResponseController.addError(e);
|
||||
}
|
||||
|
||||
// If the error is not an object, send the error as a string.
|
||||
_secureResponseController.addError("$e");
|
||||
// TODO make sure sending error as string is acceptable.
|
||||
},
|
||||
onDone: () {
|
||||
// Close the response controller when the socket is closed.
|
||||
_secureResponseController.close();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// Converts [object] to a String by invoking [Object.toString] and
|
||||
/// sends the encoding of the result to the socket.
|
||||
///
|
||||
/// Parameters:
|
||||
/// - [object]: The object to write to the socket.
|
||||
///
|
||||
/// Returns:
|
||||
/// A Future that resolves to void.
|
||||
void write(Object? object) {
|
||||
// Don't write null.
|
||||
if (object == null) return;
|
||||
|
||||
// Write the data to the socket.
|
||||
List<int> data = utf8.encode(object.toString());
|
||||
if (sslEnabled) {
|
||||
_secureSocksSocket.add(data);
|
||||
} else {
|
||||
_socksSocket.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// Closes the connection to the Tor proxy.
|
||||
///
|
||||
/// Returns:
|
||||
/// A Future that resolves to void.
|
||||
Future<void> close() async {
|
||||
// Ensure all data is sent before closing.
|
||||
try {
|
||||
if (sslEnabled) {
|
||||
await _secureSocksSocket.flush();
|
||||
}
|
||||
await _socksSocket.flush();
|
||||
} finally {
|
||||
await _subscription?.cancel();
|
||||
await _socksSocket.close();
|
||||
_responseController.close();
|
||||
if (sslEnabled) {
|
||||
_secureResponseController.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StreamSubscription<List<int>> listen(
|
||||
void Function(List<int> data)? onData, {
|
||||
Function? onError,
|
||||
void Function()? onDone,
|
||||
bool? cancelOnError,
|
||||
}) {
|
||||
return sslEnabled
|
||||
? _secureResponseController.stream.listen(
|
||||
onData,
|
||||
onError: onError,
|
||||
onDone: onDone,
|
||||
cancelOnError: cancelOnError,
|
||||
)
|
||||
: _responseController.stream.listen(
|
||||
onData,
|
||||
onError: onError,
|
||||
onDone: onDone,
|
||||
cancelOnError: cancelOnError,
|
||||
);
|
||||
}
|
||||
|
||||
/// Sends the server.features command to the proxy server.
|
||||
///
|
||||
/// This demos how to send the server.features command. Use as an example
|
||||
/// for sending other commands.
|
||||
///
|
||||
/// Returns:
|
||||
/// A Future that resolves to void.
|
||||
Future<void> sendServerFeaturesCommand() async {
|
||||
// The server.features command.
|
||||
const String command =
|
||||
'{"jsonrpc":"2.0","id":"0","method":"server.features","params":[]}';
|
||||
|
||||
if (!sslEnabled) {
|
||||
// Send the command to the proxy server.
|
||||
_socksSocket.writeln(command);
|
||||
|
||||
// Wait for the response from the proxy server.
|
||||
var responseData = await _responseController.stream.first;
|
||||
if (kDebugMode) {
|
||||
print("responseData: ${utf8.decode(responseData)}");
|
||||
}
|
||||
} else {
|
||||
// Send the command to the proxy server.
|
||||
_secureSocksSocket.writeln(command);
|
||||
|
||||
// Wait for the response from the proxy server.
|
||||
var responseData = await _secureResponseController.stream.first;
|
||||
if (kDebugMode) {
|
||||
print("secure responseData: ${utf8.decode(responseData)}");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
// SPDX-FileCopyrightText: 2022 Foundation Devices Inc.
|
||||
// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
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';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:tor/generated_bindings.dart' as rust;
|
||||
|
||||
DynamicLibrary load(name) {
|
||||
if (Platform.isAndroid || Platform.isLinux) {
|
||||
return DynamicLibrary.open('lib$name.so');
|
||||
} else if (Platform.isIOS || Platform.isMacOS) {
|
||||
return DynamicLibrary.open('$name.framework/$name');
|
||||
} else if (Platform.isWindows) {
|
||||
return DynamicLibrary.open('$name.dll');
|
||||
} else {
|
||||
throw NotSupportedPlatform('${Platform.operatingSystem} is not supported!');
|
||||
}
|
||||
}
|
||||
|
||||
class CouldntBootstrapDirectory implements Exception {
|
||||
String? rustError;
|
||||
|
||||
CouldntBootstrapDirectory({this.rustError});
|
||||
}
|
||||
|
||||
class NotSupportedPlatform implements Exception {
|
||||
NotSupportedPlatform(String s);
|
||||
}
|
||||
|
||||
class ClientNotActive implements Exception {}
|
||||
|
||||
class Tor {
|
||||
static const String libName = "tor";
|
||||
static late DynamicLibrary _lib;
|
||||
|
||||
Pointer<Void> _clientPtr = nullptr;
|
||||
Pointer<Void> _proxyPtr = nullptr;
|
||||
|
||||
/// Flag to indicate that Tor client and proxy have started. Traffic is routed through the proxy only if it is also [enabled].
|
||||
bool get started => _proxyPort > -1;
|
||||
|
||||
bool get hasClient => _clientPtr != nullptr;
|
||||
|
||||
/// Flag to indicate that traffic should flow through the proxy.
|
||||
bool _enabled = false;
|
||||
|
||||
/// Getter for the enabled flag.
|
||||
bool get enabled => _enabled;
|
||||
|
||||
/// Flag to indicate that a Tor circuit is thought to have been established
|
||||
/// (true means that Tor has bootstrapped).
|
||||
bool get bootstrapped => _bootstrapped;
|
||||
|
||||
/// Getter for the bootstrapped flag.
|
||||
bool _bootstrapped = false;
|
||||
|
||||
/// A stream of Tor events.
|
||||
///
|
||||
/// This stream broadcast just the port for now (-1 if circuit not established or proxy not enabled)
|
||||
final StreamController events = StreamController.broadcast();
|
||||
|
||||
/// Getter for the proxy port.
|
||||
///
|
||||
/// Returns -1 if Tor is not enabled or if the circuit is not established.
|
||||
///
|
||||
/// Returns the proxy port if Tor is enabled and the circuit is established.
|
||||
///
|
||||
/// This is the port that should be used for all requests.
|
||||
int get port {
|
||||
if (!_enabled) {
|
||||
return -1;
|
||||
}
|
||||
return _proxyPort;
|
||||
}
|
||||
|
||||
/// The proxy port.
|
||||
int _proxyPort = -1;
|
||||
|
||||
/// Singleton instance of the Tor class.
|
||||
static final Tor _instance = Tor._internal();
|
||||
|
||||
/// Getter for the singleton instance of the Tor class.
|
||||
static Tor get instance => _instance;
|
||||
|
||||
/// Initialize the Tor ffi lib instance if it hasn't already been set. Nothing
|
||||
/// changes if _tor is already been set.
|
||||
///
|
||||
/// Returns a Future that completes when the Tor service has started.
|
||||
///
|
||||
/// Throws an exception if the Tor service fails to start.
|
||||
static Future<Tor> init({enabled = true}) async {
|
||||
var singleton = Tor._instance;
|
||||
singleton._enabled = enabled;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
/// Private constructor for the Tor class.
|
||||
Tor._internal() {
|
||||
_lib = load(libName);
|
||||
|
||||
if (kDebugMode) {
|
||||
print("Instance of Tor created!");
|
||||
}
|
||||
}
|
||||
|
||||
void broadcastState() {
|
||||
events.add(port);
|
||||
}
|
||||
|
||||
Future<int> _getRandomUnusedPort({List<int> excluded = const []}) async {
|
||||
var random = Random.secure();
|
||||
int potentialPort = 0;
|
||||
|
||||
retry:
|
||||
while (potentialPort <= 0 || excluded.contains(potentialPort)) {
|
||||
potentialPort = random.nextInt(65535);
|
||||
try {
|
||||
var socket = await ServerSocket.bind("0.0.0.0", potentialPort);
|
||||
socket.close();
|
||||
return potentialPort;
|
||||
} catch (_) {
|
||||
continue retry;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// Start the Tor service.
|
||||
///
|
||||
/// This will start the Tor service and establish a Tor circuit.
|
||||
///
|
||||
/// Throws an exception if the Tor service fails to start.
|
||||
///
|
||||
/// Returns a Future that completes when the Tor service has started.
|
||||
Future<void> start(
|
||||
{int? obfs4Port, int? snowflakePort, String? bridgeLines}) async {
|
||||
broadcastState();
|
||||
|
||||
// Set the state and cache directories.
|
||||
final Directory appSupportDir = await getApplicationSupportDirectory();
|
||||
final stateDir =
|
||||
await Directory('${appSupportDir.path}/tor_state').create();
|
||||
final cacheDir =
|
||||
await Directory('${appSupportDir.path}/tor_cache').create();
|
||||
|
||||
// Generate a random port.
|
||||
int newPort = await _getRandomUnusedPort();
|
||||
|
||||
// Start the Tor service in an isolate.
|
||||
final tor = await Isolate.run(() async {
|
||||
// Load the Tor library.
|
||||
var lib = rust.NativeLibrary(load(libName));
|
||||
|
||||
// Start the Tor service.
|
||||
final tor = lib.tor_start(
|
||||
newPort,
|
||||
stateDir.path.toNativeUtf8() as Pointer<Char>,
|
||||
cacheDir.path.toNativeUtf8() as Pointer<Char>,
|
||||
obfs4Port ?? -1,
|
||||
snowflakePort ?? -1,
|
||||
bridgeLines?.toNativeUtf8() as Pointer<Char>? ?? nullptr);
|
||||
|
||||
// Throw an exception if the Tor service fails to start.
|
||||
if (tor.client == nullptr) {
|
||||
throwRustException(lib);
|
||||
}
|
||||
|
||||
return tor;
|
||||
});
|
||||
|
||||
// Set the client pointer and started flag.
|
||||
_clientPtr = Pointer.fromAddress(tor.client.address);
|
||||
_proxyPtr = Pointer.fromAddress(tor.proxy.address);
|
||||
|
||||
// Bootstrap the Tor service.
|
||||
bootstrap();
|
||||
|
||||
// Set the proxy port.
|
||||
_proxyPort = newPort;
|
||||
broadcastState();
|
||||
}
|
||||
|
||||
Future<void> reconfigure(
|
||||
{int? obfs4Port, int? snowflakePort, String? bridgeLines}) async {
|
||||
final lib = rust.NativeLibrary(_lib);
|
||||
|
||||
// Set the state and cache directories.
|
||||
final Directory appSupportDir = await getApplicationSupportDirectory();
|
||||
final stateDir =
|
||||
await Directory('${appSupportDir.path}/tor_state').create();
|
||||
final cacheDir =
|
||||
await Directory('${appSupportDir.path}/tor_cache').create();
|
||||
|
||||
final reconfigured = lib.tor_reconfigure(
|
||||
_clientPtr,
|
||||
stateDir.path.toNativeUtf8() as Pointer<Char>,
|
||||
cacheDir.path.toNativeUtf8() as Pointer<Char>,
|
||||
obfs4Port ?? -1,
|
||||
snowflakePort ?? -1,
|
||||
bridgeLines?.toNativeUtf8() as Pointer<Char>? ?? nullptr);
|
||||
|
||||
if (!reconfigured) {
|
||||
throwRustException(lib);
|
||||
}
|
||||
}
|
||||
|
||||
/// Bootstrap the Tor service.
|
||||
///
|
||||
/// This will bootstrap the Tor service and establish a Tor circuit. This
|
||||
/// function should only be called after the Tor service has been started.
|
||||
///
|
||||
/// This function will block until the Tor service has bootstrapped.
|
||||
///
|
||||
/// Throws an exception if the Tor service fails to bootstrap.
|
||||
///
|
||||
/// Returns void.
|
||||
void bootstrap() {
|
||||
// Load the Tor library.
|
||||
final lib = rust.NativeLibrary(_lib);
|
||||
|
||||
// Bootstrap the Tor service.
|
||||
_bootstrapped = lib.tor_client_bootstrap(_clientPtr);
|
||||
|
||||
// Throw an exception if the Tor service fails to bootstrap.
|
||||
if (!bootstrapped) {
|
||||
throwRustException(lib);
|
||||
}
|
||||
}
|
||||
|
||||
/// Prevent traffic flowing through the proxy
|
||||
void disable() {
|
||||
stop();
|
||||
|
||||
_enabled = false;
|
||||
broadcastState();
|
||||
}
|
||||
|
||||
/// Stops the proxy
|
||||
void stop() {
|
||||
final lib = rust.NativeLibrary(_lib);
|
||||
if (_proxyPtr != nullptr) {
|
||||
lib.tor_proxy_stop(_proxyPtr);
|
||||
_proxyPtr = nullptr;
|
||||
|
||||
_bootstrapped = false;
|
||||
_proxyPort = -1;
|
||||
|
||||
broadcastState();
|
||||
}
|
||||
}
|
||||
|
||||
void setClientDormant(bool dormant) {
|
||||
if (_clientPtr == nullptr || !started || !bootstrapped) {
|
||||
throw ClientNotActive();
|
||||
}
|
||||
|
||||
final lib = rust.NativeLibrary(_lib);
|
||||
lib.tor_client_set_dormant(_clientPtr, dormant);
|
||||
}
|
||||
|
||||
Future<void> isReady() async {
|
||||
return await Future.doWhile(
|
||||
() => Future.delayed(const Duration(seconds: 1)).then((_) {
|
||||
// We are waiting and making absolutely no request unless:
|
||||
// Tor is disabled
|
||||
if (!enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ...or Tor circuit is established
|
||||
if (bootstrapped) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This way we avoid making clearnet req's while Tor is initialising
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
static throwRustException(rust.NativeLibrary lib) {
|
||||
String rustError = lib.tor_last_error_message().cast<Utf8>().toDartString();
|
||||
|
||||
throw _getRustException(rustError);
|
||||
}
|
||||
|
||||
static Exception _getRustException(String rustError) {
|
||||
if (rustError.contains('Unable to bootstrap a working directory')) {
|
||||
return CouldntBootstrapDirectory(rustError: rustError);
|
||||
} else {
|
||||
return Exception(rustError);
|
||||
}
|
||||
}
|
||||
|
||||
void hello() {
|
||||
rust.NativeLibrary(_lib).tor_hello();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import 'package:tor/generated_bindings.dart' as rust;
|
||||
import 'package:tor/tor.dart';
|
||||
|
||||
int getNofileLimit() {
|
||||
return rust.NativeLibrary(load(Tor.libName)).tor_get_nofile_limit();
|
||||
}
|
||||
|
||||
int setNofileLimit(int limit) {
|
||||
return rust.NativeLibrary(load(Tor.libName)).tor_set_nofile_limit(limit);
|
||||
}
|
||||
Reference in New Issue
Block a user