Kotlin Multiplatform support for embedding Tor into your application.
Add dependency
// build.gradle.kts
dependencies {
val vTor = "0.4.7.8"
val vKmpTor = "1.0.0"
implementation("io.matthewnelson.kotlin-components:kmp-tor:$vTor+$vKmpTor")
}
// build.gradle
dependencies {
def vTor = '0.4.7.8'
def vKmpTor = '1.0.0'
implementation "io.matthewnelson.kotlin-components:kmp-tor:$vTor+$vKmpTor"
}
Configuring an Android Project
-
See the Android section of Configuring Gradle to setup things up so the Tor binaries are properly extracted upon app install.
-
By default,
TorService
needs no configuration and runs in the background. For configuring it to run as a Foreground service, see the following:
- See the Sample App
for a basic setup of
TorManager
and yourTorConfig
.
Configuring a Java Project
- See the JavaFX Sample App Gradle Configuration for a basic gradle/dependency configuration.
- See the JavaFx Sample App for a basic setup example.
- Run the JavaFx Sample via
./gradlew :samples:kotlin:javafx:run -PKMP_TARGETS=JVM
from terminal or cmd prompt.- Note: Be sure to run
git submodule update --init
if you haven't yet so git submodules are initialized.
- Note: Be sure to run
Unix Domain Sockets
- ControlPort
- SocksPort
- HiddenServicePort
- For Android, nothing is needed.
- For JVM, you will need to add the following dependency to your Linux distributions:
// build.gradlew.kts
dependencies {
val vTor = "0.4.7.8"
val vKmpTor = "1.0.0"
implementation("io.matthewnelson.kotlin-components:kmp-tor:$vTor+$vKmpTor")
if (isLinuxBuild) {
// Add the Unix Domain Socket support extension
implementation("io.matthewnelson.kotlin-components:kmp-tor-ext-unix-socket:$vKmpTor")
}
}
See the JavaFX Sample App Gradle Configuration
dependencies
block for more info.
If neither TorConfig.Setting.Ports.Control
or TorConfig.Setting.UnixSockets.Control
are expressed in
your config, TorConfig.Setting.UnixSockets.Control
will always be the preferred setting for establishing
a connection to Tor's control port, if support is had (JVM + Linux + extension, or on Android). To
override this behavior, you can express the TorConfig.Setting.Ports.Control
setting when providing your
config at startup.
How to enable unix domain socket support for the SocksPort
and HiddenServicePort
settings:
- Be running on Linux (or Android)
Callbacks (non-kotlin consumers)
- For Java projects (who can't use coroutines), you can "wrap"
TorManager
in an implementation that uses callbacks (ie.CallbackTorManager
).
// build.gradle
dependencies {
def vTor = '0.4.7.8'
def vKmpTor = '1.0.0'
implementation "io.matthewnelson.kotlin-components:kmp-tor:$vTor+$vKmpTor"
// Add the callback extension
implementation "io.matthewnelson.kotlin-components:kmp-tor-ext-callback-manager:$vKmpTor"
// You will also need to add the Kotlin Gradle Plugin, and Coroutines dependency.
// If not Android, you will also need to import the binaries for the platforms you wish to
// support.
}
// Wrapping TorManager instance in its Callback instance (Java)
public class Example1 {
// ..
TorManager instance = TorManager.newInstance(/* ... */);
// Wrap that mug...
CallbackTorManager torManager = new CallbackTorManager(
instance,
uncaughtException -> {
Log.e("MyJavaApp", "Some TorCallback isn't handling an exception...", uncaughtException);
}
);
}
- All requests use coroutines under the hood and are Main thread safe. Results will be dispatched to the supplied callback on the Main thread.
// Multiple callbacks of different styles (Java)
public class Example2 {
// ...
Task startTask = torManager.start(
t -> Log.e(TAG, "Failed to start Tor", t),
startSuccess -> {
Log.d(TAG, "Tor started successfully");
Task restartTask = torManager.restart(
null, // fail silently by omitting failure callback
(TorCallback<Object>) restartSuccess -> {
Log.d(TAG, "Tor restarted successfully");
Task restartTask2 = torManager.restart(
// Use the provided instance that will automatically throw
// the exception, which will pipe it to the handler.
TorCallback.THROW,
new TorCallback<Object>() {
@Override
public void invoke(Object o) {
Log.d(TAG, "Tor restarted successfully");
}
}
);
}
);
}
);
}
- Android (Java):
- JavaFx (Java):
- JavaFx Sample App
- JavaFx Sample Gradle
- Run the sample via
./gradlew :samples:java:javafx:run -PKMP_TARGETS=JVM
from terminal or cmd prompt.- Note: Be sure to run
git submodule update --init
if you haven't yet so git submodules are initialized.
- Note: Be sure to run
This project utilizes git submodules. You will need to initialize them when cloning the repository via:
$ git checkout master
$ git pull
$ git submodule update --init
In order to keep submodules updated when pulling the latest code, run:
$ git pull --recurse-submodules