diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 648f57f..c7adabe 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,8 +1,10 @@ + diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..a5f05cd --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 37a7509..39c65f6 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/app/build.gradle b/app/build.gradle index 5326171..3e72e09 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,25 +1,34 @@ apply plugin: 'com.android.application' - apply plugin: 'kotlin-android' - apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { applicationId "io.github.chronosx88.yggdrasil" minSdkVersion 21 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + signingConfigs { + release { + + storeFile file(KEYSTORE_FILE_PATH) + storePassword System.getenv("KEYSTORE_PASSWORD") + keyAlias System.getenv("KEY_ALIAS") + keyPassword System.getenv("KEY_PASSWORD") + } + } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.release } } + ndkVersion "21.2.6472646" } dependencies { @@ -34,5 +43,5 @@ dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0-RC2' implementation 'com.google.android.material:material:1.1.0-alpha09' implementation 'org.hjson:hjson:3.0.0' - implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.google.code.gson:gson:2.8.6' } diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt index 0982a45..8babf04 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt @@ -18,9 +18,9 @@ fun createNativeYggConfig(config: Config): NodeConfig { nativeConfig.adminListen = config.adminListen nativeConfig.encryptionPrivateKey = config.encryptionPrivateKey nativeConfig.encryptionPublicKey = config.encryptionPublicKey - nativeConfig.ifMTU = config.ifMTU + //nativeConfig.ifMTU = config.ifMTU nativeConfig.ifName = config.ifName - nativeConfig.ifTAPMode = config.ifTAPMode + //nativeConfig.ifTAPMode = config.ifTAPMode nativeConfig.nodeInfoPrivacy = config.nodeInfoPrivacy nativeConfig.signingPrivateKey = config.signingPrivateKey nativeConfig.signingPublicKey = config.signingPublicKey diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt index 1f9be37..7f81082 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt @@ -15,11 +15,16 @@ import java.io.FileInputStream import java.io.FileOutputStream import java.io.InputStream import java.io.OutputStream +import java.nio.ByteBuffer import kotlin.coroutines.CoroutineContext import kotlin.experimental.or class YggdrasilTunService : VpnService() { + + /** Maximum packet size is constrained by the MTU, which is given as a signed short. */ + private val MAX_PACKET_SIZE = Short.MAX_VALUE.toInt() + companion object { private var isRunning: Boolean = false } @@ -56,7 +61,11 @@ class YggdrasilTunService : VpnService() { tunInterface = builder .addAddress(address, 7) + .addRoute("10.0.0.0", 8) + .addRoute("172.16.0.0", 12) + .addRoute("192.168.0.0", 16) .addRoute("0200::", 7) + .setMtu(MAX_PACKET_SIZE) .establish() tunInputStream = FileInputStream(tunInterface!!.fileDescriptor) @@ -75,11 +84,30 @@ class YggdrasilTunService : VpnService() { } private fun fixConfig(config: MutableMap): MutableMap { + val peers = arrayListOf(); + peers.add("tcp://194.177.21.156:5066") + peers.add("tcp://46.151.26.194:60575") + peers.add("tcp://188.226.125.64:54321") + val whiteList = arrayListOf() + whiteList.add("") + val blackList = arrayListOf() + blackList.add("") + config["Peers"] = peers config["Listen"] = "" config["AdminListen"] = "tcp://localhost:9001" - config["IfName"] = "dummy" - (config["SessionFirewall"] as MutableMap)["Enable"] = true - (config["SwitchOptions"] as MutableMap)["MaxTotalQueueSize"] = 1048576 + config["IfName"] = "tun0" + //config["EncryptionPublicKey"] = "b15633cf66e63a04f03e9d1a5b2ac6411af819cde9e74175cf574d5599b1296c" + //config["EncryptionPrivateKey"] = "a39e2da3ccbb5afc3854574a2e3823e881d2d720754d6fdc877f57b252d3b521" + //config["SigningPublicKey"] = "4f248483c094aea370fba86f1630ba5099cb230aa1337ab6ef6ff0b132be2c2b" + //config["SigningPrivateKey"] = "e4d56eb2e15e25d9098731e39d661a80c523f31d38b71cbd0ad25a5cde745eac4f248483c094aea370fba86f1630ba5099cb230aa1337ab6ef6ff0b132be2c2b" + (config["SessionFirewall"] as MutableMap)["Enable"] = false + //(config["SessionFirewall"] as MutableMap)["AllowFromDirect"] = true + //(config["SessionFirewall"] as MutableMap)["AllowFromRemote"] = true + //(config["SessionFirewall"] as MutableMap)["AlwaysAllowOutbound"] = true + //(config["SessionFirewall"] as MutableMap)["WhitelistEncryptionPublicKeys"] = whiteList + //(config["SessionFirewall"] as MutableMap)["BlacklistEncryptionPublicKeys"] = blackList + + (config["SwitchOptions"] as MutableMap)["MaxTotalQueueSize"] = 4194304 if (config["AutoStart"] == null) { val tmpMap = emptyMap().toMutableMap() tmpMap["WiFi"] = false @@ -91,10 +119,20 @@ class YggdrasilTunService : VpnService() { private fun readPacketsFromTun() { if(tunInputStream != null) { - val buffer = ByteArray(1024) - tunInputStream!!.read(buffer) - if (!isBufferEmpty(buffer)) { - yggConduitEndpoint.send(buffer) + var packet: ByteArray = ByteArray(MAX_PACKET_SIZE) + // Read the outgoing packet from the input stream. + var length = tunInputStream!!.read(packet) + + //System.out.println("packet size:"+packet.size+" "+byteArrayToHex(packet)) + //System.out.println("buffer size:"+buffer.array().size+" "+byteArrayToHex(buffer.array())) + if (length > 0) { + // Ignore control messages, which start with zero. + if (packet.get(0).compareTo(0)!=0) { + var buffer = ByteBuffer.allocate(length); + buffer.put(packet, 0, length) + buffer.limit(length) + yggConduitEndpoint.send(buffer.array()) + } } } } @@ -110,9 +148,7 @@ class YggdrasilTunService : VpnService() { private fun writePacketsToTun() { if(tunOutputStream != null) { val buffer = yggConduitEndpoint.recv() - if (!isBufferEmpty(buffer)) { - tunOutputStream!!.write(buffer) - } + tunOutputStream!!.write(buffer) } } diff --git a/build.gradle b/build.gradle index 438d280..03ed29e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.41' + ext.kotlin_version = '1.3.72' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' + classpath 'com.android.tools.build:gradle:4.0.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle.properties b/gradle.properties index 3d8ce0c..fa71096 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,3 +15,4 @@ org.gradle.jvmargs=-Xmx1536m kotlin.code.style=official android.useAndroidX=true android.enableJetifier=true +KEYSTORE_FILE_PATH=/home/vadym/keystore/yggdrasil.jks diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index adb9915..a12bfeb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Aug 20 15:25:37 MSK 2019 +#Tue Jun 09 01:07:00 PDT 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/settings.gradle b/settings.gradle index 7ba48be..abf2a33 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,2 @@ +include ':yggdrasil.aar' include ':app', ':yggdrasil' diff --git a/yggdrasil.aar/build.gradle b/yggdrasil.aar/build.gradle new file mode 100644 index 0000000..2785576 --- /dev/null +++ b/yggdrasil.aar/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('yggdrasil.aar')) \ No newline at end of file diff --git a/yggdrasil.aar/yggdrasil.aar b/yggdrasil.aar/yggdrasil.aar new file mode 100644 index 0000000..2179b72 Binary files /dev/null and b/yggdrasil.aar/yggdrasil.aar differ