do proper code formatting
automate code formatting with a contrib/format.sh
This commit is contained in:
parent
3c897be2d4
commit
76a9337f16
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
flutter format .
|
||||
cd lokinet_lib/android && gradle spotlessApply
|
|
@ -2,71 +2,95 @@ group "io.oxen.lokinet_lib"
|
|||
version "1.0-SNAPSHOT"
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = "1.3.50"
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
ext.kotlin_version = "1.3.50"
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:3.5.0"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:3.5.0"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "com.diffplug.spotless:spotless-plugin-gradle:5.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "com.diffplug.spotless"
|
||||
apply plugin: "com.android.library"
|
||||
apply plugin: "kotlin-android"
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
spotless {
|
||||
java {
|
||||
target "$projectDir/src/main/java/**/*.java"
|
||||
importOrder() // standard import order
|
||||
removeUnusedImports()
|
||||
googleJavaFormat()
|
||||
prettier()
|
||||
}
|
||||
groovyGradle {
|
||||
importOrder()
|
||||
target '*.gradle' // default target of groovyGradle
|
||||
greclipse()
|
||||
}
|
||||
|
||||
ndkVersion '21.3.6528147'
|
||||
sourceSets {
|
||||
main.java.srcDirs += "src/main/java"
|
||||
main.java.srcDirs += "src/main/kotlin"
|
||||
main.jniLibs.srcDirs += "src/main/jniLibs"
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
}
|
||||
lintOptions {
|
||||
disable "InvalidPackage"
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlin {
|
||||
target "$projectDir/src/main/kotlin/**/*.kt"
|
||||
ktfmt() // has its own section below
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
|
||||
ndkVersion '21.3.6528147'
|
||||
sourceSets {
|
||||
main.java.srcDirs += "src/main/java"
|
||||
main.java.srcDirs += "src/main/kotlin"
|
||||
main.jniLibs.srcDirs += "src/main/jniLibs"
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
}
|
||||
lintOptions {
|
||||
disable "InvalidPackage"
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
}
|
||||
|
||||
task cleanNativeLibs(type: Delete) {
|
||||
delete "$projectDir/../external/loki-network/build-android"
|
||||
delete "$projectDir/../external/loki-network/build-android"
|
||||
}
|
||||
|
||||
task compileNativeLibs(type: Exec) {
|
||||
workingDir "$projectDir/../external/loki-network"
|
||||
environment "NDK", project.android.ndkDirectory
|
||||
executable "./contrib/android.sh"
|
||||
workingDir "$projectDir/../external/loki-network"
|
||||
environment "NDK", project.android.ndkDirectory
|
||||
executable "./contrib/android.sh"
|
||||
}
|
||||
|
||||
task ensureNativeLibs(type: Copy) {
|
||||
from("$projectDir/../external/loki-network/") {
|
||||
include 'lokinet-jni-*/*/*.so'
|
||||
eachFile { fcd ->
|
||||
fcd.relativePath = new RelativePath(true, fcd.relativePath.segments.drop(1))
|
||||
}
|
||||
}
|
||||
into "$projectDir/src/main/jniLibs/"
|
||||
from("$projectDir/../external/loki-network/") {
|
||||
include 'lokinet-jni-*/*/*.so'
|
||||
eachFile { fcd ->
|
||||
fcd.relativePath = new RelativePath(true, fcd.relativePath.segments.drop(1))
|
||||
}
|
||||
}
|
||||
into "$projectDir/src/main/jniLibs/"
|
||||
}
|
||||
|
||||
ensureNativeLibs.dependsOn compileNativeLibs
|
||||
|
|
|
@ -2,13 +2,13 @@ package network.loki.lokinet;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class LokinetConfig
|
||||
{
|
||||
public class LokinetConfig {
|
||||
static {
|
||||
System.loadLibrary("lokinet-android");
|
||||
}
|
||||
|
||||
private static native ByteBuffer Obtain(String dataDir);
|
||||
|
||||
private static native void Free(ByteBuffer buf);
|
||||
|
||||
/*** load config file from disk */
|
||||
|
@ -16,23 +16,18 @@ public class LokinetConfig
|
|||
/*** save chages to disk */
|
||||
public native boolean Save();
|
||||
|
||||
|
||||
/** override default config value before loading from config file */
|
||||
public native void AddDefaultValue(String section, String key, String value);
|
||||
|
||||
|
||||
private final ByteBuffer impl;
|
||||
|
||||
public LokinetConfig(String dataDir)
|
||||
{
|
||||
public LokinetConfig(String dataDir) {
|
||||
impl = Obtain(dataDir);
|
||||
if(impl == null)
|
||||
throw new RuntimeException("cannot obtain config from "+dataDir);
|
||||
if (impl == null) throw new RuntimeException("cannot obtain config from " + dataDir);
|
||||
}
|
||||
|
||||
public void finalize()
|
||||
{
|
||||
if (impl != null)
|
||||
{
|
||||
public void finalize() {
|
||||
if (impl != null) {
|
||||
Free(impl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,198 +6,229 @@ import android.os.Binder;
|
|||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class LokinetDaemon extends VpnService {
|
||||
|
||||
public static final String ACTION_CONNECT = "network.loki.lokinet.START";
|
||||
public static final String ACTION_DISCONNECT = "network.loki.lokinet.STOP";
|
||||
public static final String LOG_TAG = "LokinetDaemon";
|
||||
public static final String MESSAGE_CHANNEL = "LOKINET_DAEMON";
|
||||
public static final String EXIT_NODE = "EXIT_NODE";
|
||||
public static final String UPSTREAM_DNS = "UPSTREAM_DNS";
|
||||
public static final String ACTION_CONNECT = "network.loki.lokinet.START";
|
||||
public static final String ACTION_DISCONNECT = "network.loki.lokinet.STOP";
|
||||
public static final String LOG_TAG = "LokinetDaemon";
|
||||
public static final String MESSAGE_CHANNEL = "LOKINET_DAEMON";
|
||||
public static final String EXIT_NODE = "EXIT_NODE";
|
||||
public static final String UPSTREAM_DNS = "UPSTREAM_DNS";
|
||||
|
||||
private static final String DEFAULT_EXIT_NODE = "exit.loki";
|
||||
private static final String DEFAULT_UPSTREAM_DNS = "9.9.9.9";
|
||||
|
||||
private static final String DEFAULT_EXIT_NODE = "exit.loki";
|
||||
private static final String DEFAULT_UPSTREAM_DNS = "9.9.9.9";
|
||||
static {
|
||||
System.loadLibrary("lokinet-android");
|
||||
}
|
||||
|
||||
static {
|
||||
System.loadLibrary("lokinet-android");
|
||||
private static native ByteBuffer Obtain();
|
||||
|
||||
private static native void Free(ByteBuffer buf);
|
||||
|
||||
public native boolean Configure(LokinetConfig config);
|
||||
|
||||
public native int Mainloop();
|
||||
|
||||
public native boolean IsRunning();
|
||||
|
||||
public native String DumpStatus();
|
||||
|
||||
public native boolean Stop();
|
||||
|
||||
public native void InjectVPNFD();
|
||||
|
||||
public native int GetUDPSocket();
|
||||
|
||||
private static native String DetectFreeRange();
|
||||
|
||||
ByteBuffer impl = null;
|
||||
ParcelFileDescriptor iface;
|
||||
int m_FD = -1;
|
||||
int m_UDPSocket = -1;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startID) {
|
||||
Log.d(LOG_TAG, "onStartCommand()");
|
||||
|
||||
if (intent.getAction().equals(ACTION_DISCONNECT)) {
|
||||
disconnect();
|
||||
return START_NOT_STICKY;
|
||||
} else {
|
||||
ArrayList<ConfigValue> configVals = new ArrayList<ConfigValue>();
|
||||
String exitNode = intent.getStringExtra(EXIT_NODE);
|
||||
|
||||
if (exitNode == null || exitNode.isEmpty()) {
|
||||
exitNode = DEFAULT_EXIT_NODE;
|
||||
Log.e(LOG_TAG, "No exit-node configured! Proceeding with default.");
|
||||
}
|
||||
|
||||
Log.e(LOG_TAG, "Using " + exitNode + " as exit-node.");
|
||||
configVals.add(new ConfigValue("network", "exit-node", exitNode));
|
||||
|
||||
String upstreamDNS = intent.getStringExtra(UPSTREAM_DNS);
|
||||
|
||||
if (upstreamDNS == null || upstreamDNS.isEmpty()) {
|
||||
upstreamDNS = DEFAULT_UPSTREAM_DNS;
|
||||
Log.e(LOG_TAG, "No upstream DNS configured! Proceeding with default.");
|
||||
}
|
||||
|
||||
Log.e(LOG_TAG, "Using " + upstreamDNS + " as upstream DNS.");
|
||||
configVals.add(new ConfigValue("dns", "upstream", upstreamDNS));
|
||||
|
||||
// set log leve to info
|
||||
configVals.add(new ConfigValue("logging", "level", "info"));
|
||||
|
||||
boolean connectedSucessfully = connect(configVals);
|
||||
if (connectedSucessfully) return START_STICKY;
|
||||
else return START_NOT_STICKY;
|
||||
}
|
||||
}
|
||||
|
||||
private class ConfigValue {
|
||||
final String Section;
|
||||
final String Key;
|
||||
final String Value;
|
||||
|
||||
public ConfigValue(String section, String key, String value) {
|
||||
Section = section;
|
||||
Key = key;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
private static native ByteBuffer Obtain();
|
||||
|
||||
private static native void Free(ByteBuffer buf);
|
||||
|
||||
public native boolean Configure(LokinetConfig config);
|
||||
|
||||
public native int Mainloop();
|
||||
|
||||
public native boolean IsRunning();
|
||||
|
||||
public native String DumpStatus();
|
||||
|
||||
public native boolean Stop();
|
||||
|
||||
public native void InjectVPNFD();
|
||||
|
||||
public native int GetUDPSocket();
|
||||
|
||||
private static native String DetectFreeRange();
|
||||
|
||||
ByteBuffer impl = null;
|
||||
ParcelFileDescriptor iface;
|
||||
int m_FD = -1;
|
||||
int m_UDPSocket = -1;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
public boolean Valid() {
|
||||
if (Section == null || Key == null || Value == null) return false;
|
||||
if (Section.isEmpty() || Key.isEmpty() || Value.isEmpty()) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disconnect();
|
||||
}
|
||||
private boolean connect(ArrayList<ConfigValue> configVals) {
|
||||
if (!IsRunning()) {
|
||||
if (impl != null) {
|
||||
Free(impl);
|
||||
impl = null;
|
||||
}
|
||||
impl = Obtain();
|
||||
if (impl == null) {
|
||||
Log.e(LOG_TAG, "got nullptr when creating llarp::Context in jni");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startID) {
|
||||
Log.d(LOG_TAG, "onStartCommand()");
|
||||
String dataDir = getFilesDir().toString();
|
||||
LokinetConfig config;
|
||||
try {
|
||||
config = new LokinetConfig(dataDir);
|
||||
} catch (RuntimeException ex) {
|
||||
Log.e(LOG_TAG, ex.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(ACTION_DISCONNECT)) {
|
||||
disconnect();
|
||||
return START_NOT_STICKY;
|
||||
} else {
|
||||
String exitNode = intent.getStringExtra(EXIT_NODE);
|
||||
String ourRange = DetectFreeRange();
|
||||
|
||||
if (exitNode == null || exitNode.isEmpty()) {
|
||||
exitNode = DEFAULT_EXIT_NODE;
|
||||
Log.e(LOG_TAG, "No exit-node configured! Proceeding with default.");
|
||||
}
|
||||
if (ourRange.isEmpty()) {
|
||||
Log.e(LOG_TAG, "cannot detect free range");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.e(LOG_TAG, "Using " + exitNode + " as exit-node.");
|
||||
String upstreamDNS = DEFAULT_UPSTREAM_DNS;
|
||||
|
||||
String upstreamDNS = intent.getStringExtra(UPSTREAM_DNS);
|
||||
|
||||
if (upstreamDNS == null || upstreamDNS.isEmpty()) {
|
||||
upstreamDNS = DEFAULT_UPSTREAM_DNS;
|
||||
Log.e(LOG_TAG, "No upstream DNS configured! Proceeding with default.");
|
||||
}
|
||||
|
||||
Log.e(LOG_TAG, "Using " + upstreamDNS + " as upstream DNS.");
|
||||
|
||||
|
||||
boolean connectedSucessfully = connect(exitNode, upstreamDNS);
|
||||
if (connectedSucessfully)
|
||||
return START_STICKY;
|
||||
else
|
||||
return START_NOT_STICKY;
|
||||
// set up config values
|
||||
if (configVals != null) {
|
||||
for (ConfigValue conf : configVals) {
|
||||
if (conf.Valid()) {
|
||||
config.AddDefaultValue(conf.Section, conf.Key, conf.Value);
|
||||
if (conf.Section.equals("dns") && conf.Key.equals("upstream")) upstreamDNS = conf.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean connect(String exitNode, String upstreamDNS) {
|
||||
if (!IsRunning()) {
|
||||
if (impl != null) {
|
||||
Free(impl);
|
||||
impl = null;
|
||||
}
|
||||
impl = Obtain();
|
||||
if (impl == null) {
|
||||
Log.e(LOG_TAG, "got nullptr when creating llarp::Context in jni");
|
||||
return false;
|
||||
}
|
||||
if (!config.Load()) {
|
||||
Log.e(
|
||||
LOG_TAG,
|
||||
"failed to load (or create) config file at: "
|
||||
+ dataDir
|
||||
+ "/loki.network.loki.lokinet.ini");
|
||||
return false;
|
||||
}
|
||||
|
||||
String dataDir = getFilesDir().toString();
|
||||
LokinetConfig config;
|
||||
try {
|
||||
config = new LokinetConfig(dataDir);
|
||||
} catch (RuntimeException ex) {
|
||||
Log.e(LOG_TAG, ex.toString());
|
||||
return false;
|
||||
}
|
||||
VpnService.Builder builder = new VpnService.Builder();
|
||||
|
||||
String ourRange = DetectFreeRange();
|
||||
builder.setMtu(1500);
|
||||
|
||||
if (ourRange.isEmpty()) {
|
||||
Log.e(LOG_TAG, "cannot detect free range");
|
||||
return false;
|
||||
}
|
||||
String[] parts = ourRange.split("/");
|
||||
String ourIP = parts[0];
|
||||
int ourMask = Integer.parseInt(parts[1]);
|
||||
|
||||
// set up config values
|
||||
config.AddDefaultValue("network", "exit-node", exitNode);
|
||||
config.AddDefaultValue("network", "ifaddr", ourRange);
|
||||
config.AddDefaultValue("dns", "upstream", upstreamDNS);
|
||||
builder.addAddress(ourIP, ourMask);
|
||||
builder.addRoute("0.0.0.0", 0);
|
||||
builder.addDnsServer(upstreamDNS);
|
||||
builder.setSession("Lokinet");
|
||||
builder.setConfigureIntent(null);
|
||||
|
||||
iface = builder.establish();
|
||||
if (iface == null) {
|
||||
Log.e(LOG_TAG, "VPN Interface from builder.establish() came back null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!config.Load()) {
|
||||
Log.e(LOG_TAG, "failed to load (or create) config file at: " + dataDir + "/loki.network.loki.lokinet.ini");
|
||||
return false;
|
||||
}
|
||||
m_FD = iface.detachFd();
|
||||
|
||||
VpnService.Builder builder = new VpnService.Builder();
|
||||
|
||||
builder.setMtu(1500);
|
||||
|
||||
String[] parts = ourRange.split("/");
|
||||
String ourIP = parts[0];
|
||||
int ourMask = Integer.parseInt(parts[1]);
|
||||
|
||||
builder.addAddress(ourIP, ourMask);
|
||||
builder.addRoute("0.0.0.0", 0);
|
||||
builder.addDnsServer(upstreamDNS);
|
||||
builder.setSession("Lokinet");
|
||||
builder.setConfigureIntent(null);
|
||||
|
||||
iface = builder.establish();
|
||||
if (iface == null) {
|
||||
Log.e(LOG_TAG, "VPN Interface from builder.establish() came back null");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_FD = iface.detachFd();
|
||||
|
||||
InjectVPNFD();
|
||||
new Thread(() -> {
|
||||
InjectVPNFD();
|
||||
new Thread(
|
||||
() -> {
|
||||
Configure(config);
|
||||
m_UDPSocket = GetUDPSocket();
|
||||
protect(m_UDPSocket);
|
||||
Mainloop();
|
||||
}).start();
|
||||
})
|
||||
.start();
|
||||
|
||||
Log.d(LOG_TAG, "started successfully!");
|
||||
} else {
|
||||
Log.d(LOG_TAG, "already running");
|
||||
}
|
||||
return true;
|
||||
Log.d(LOG_TAG, "started successfully!");
|
||||
} else {
|
||||
Log.d(LOG_TAG, "already running");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void disconnect() {
|
||||
if (IsRunning()) {
|
||||
Stop();
|
||||
}
|
||||
// if (impl != null) {
|
||||
// Free(impl);
|
||||
// impl = null;
|
||||
// }
|
||||
private void disconnect() {
|
||||
if (IsRunning()) {
|
||||
Stop();
|
||||
}
|
||||
// if (impl != null) {
|
||||
// Free(impl);
|
||||
// impl = null;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for clients to access. Because we know this service always
|
||||
* runs in the same process as its clients, we don't need to deal with
|
||||
* IPC.
|
||||
*/
|
||||
public class LocalBinder extends Binder {
|
||||
public LokinetDaemon getService() {
|
||||
return LokinetDaemon.this;
|
||||
}
|
||||
/**
|
||||
* Class for clients to access. Because we know this service always runs in the same process as
|
||||
* its clients, we don't need to deal with IPC.
|
||||
*/
|
||||
public class LocalBinder extends Binder {
|
||||
public LokinetDaemon getService() {
|
||||
return LokinetDaemon.this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
private final IBinder mBinder = new LocalBinder();
|
||||
private final IBinder mBinder = new LocalBinder();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue