diff --git a/.circleci/config.yml b/.circleci/config.yml index 1c9c25dba1..2465703dd9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ jobs: build: working_directory: ~/code docker: - - image: circleci/android:api-29-ndk + - image: shadowsocks/android-ndk-go:v1.0 environment: GRADLE_OPTS: -Dorg.gradle.workers.max=1 -Dorg.gradle.daemon=false -Dkotlin.compiler.execution.strategy="in-process" steps: @@ -13,7 +13,7 @@ jobs: key: jars-{{ checksum "build.gradle" }} - run: name: Run Build and Tests - command: ./gradlew assembleDebug check + command: ./gradlew assembleDebug check -PCARGO_PROFILE=debug - save_cache: paths: - ~/.gradle diff --git a/.gitmodules b/.gitmodules index b9e2447a19..954b512529 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "core/src/main/jni/shadowsocks-libev"] - path = core/src/main/jni/shadowsocks-libev - url = https://github.com/shadowsocks/shadowsocks-libev [submodule "core/src/main/jni/badvpn"] path = core/src/main/jni/badvpn url = https://github.com/shadowsocks/badvpn.git @@ -17,19 +14,6 @@ path = core/src/main/jni/redsocks url = https://github.com/shadowsocks/redsocks.git branch = shadowsocks-android -[submodule "core/src/main/jni/mbedtls"] - path = core/src/main/jni/mbedtls - url = https://github.com/ARMmbed/mbedtls -[submodule "core/src/main/jni/pcre"] - path = core/src/main/jni/pcre - url = https://android.googlesource.com/platform/external/pcre -[submodule "core/src/main/jni/libsodium"] - path = core/src/main/jni/libsodium - url = https://github.com/jedisct1/libsodium.git - branch = stable -[submodule "core/src/main/jni/libev"] - path = core/src/main/jni/libev - url = https://git.lighttpd.net/libev.git -[submodule "core/src/main/jni/re2"] - path = core/src/main/jni/re2 - url = https://github.com/google/re2.git +[submodule "core/src/main/rust/shadowsocks-rust"] + path = core/src/main/rust/shadowsocks-rust + url = https://github.com/madeye/shadowsocks-rust diff --git a/README.md b/README.md index 314e956a1c..28de976b1c 100644 --- a/README.md +++ b/README.md @@ -45,14 +45,11 @@ If you are interested in contributing or getting involved with this project, ple diff --git a/build.gradle b/build.gradle index 79f97f2647..b21f490fb8 100644 --- a/build.gradle +++ b/build.gradle @@ -5,12 +5,12 @@ apply plugin: 'com.github.ben-manes.versions' buildscript { ext { javaVersion = JavaVersion.VERSION_1_8 - kotlinVersion = '1.3.61' + kotlinVersion = '1.3.72' minSdkVersion = 21 sdkVersion = 29 compileSdkVersion = 29 lifecycleVersion = '2.2.0' - desugarLibsVersion = '1.0.4' + desugarLibsVersion = '1.0.5' junitVersion = '4.13' androidTestVersion = '1.2.0' androidEspressoVersion = '3.2.0' @@ -25,14 +25,18 @@ buildscript { maven { url 'https://maven.fabric.io/public' } + maven { + url "https://plugins.gradle.org/m2/" + } } dependencies { - classpath 'com.android.tools.build:gradle:4.0.0-alpha09' - classpath 'com.github.ben-manes:gradle-versions-plugin:0.27.0' - classpath 'com.google.android.gms:oss-licenses-plugin:0.9.5' + classpath 'com.android.tools.build:gradle:4.0.0-beta04' + classpath 'com.github.ben-manes:gradle-versions-plugin:0.28.0' + classpath 'com.google.android.gms:oss-licenses-plugin:0.10.2' classpath 'com.google.gms:google-services:4.3.3' - classpath 'com.vanniktech:gradle-maven-publish-plugin:0.9.0' + classpath 'com.vanniktech:gradle-maven-publish-plugin:0.11.1' + classpath 'gradle.plugin.org.mozilla.rust-android-gradle:plugin:0.8.3' classpath 'io.fabric.tools:gradle:1.31.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } diff --git a/core/build.gradle b/core/build.gradle index b15f0542dd..72a927314d 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' +apply plugin: 'org.mozilla.rust-android-gradle.rust-android' android { compileSdkVersion rootProject.compileSdkVersion @@ -50,27 +51,43 @@ androidExtensions { experimental = true } -def coroutinesVersion = '1.3.3' -def roomVersion = '2.2.3' -def workVersion = '2.3.1' +cargo { + module = 'src/main/rust/shadowsocks-rust' + libname = 'sslocal' + targets = ['arm', 'arm64', 'x86', 'x86_64'] + profile = findProperty('CARGO_PROFILE') ?: 'release' + targetIncludes = ["lib${libname}.so"] + extraCargoBuildArguments = ['--bin', 'sslocal'] + features { + noDefaultBut "sodium", "rc4", "aes-cfb", "aes-ctr", "camellia-cfb", "openssl-vendored", "local-flow-stat", "local-dns-relay" + } + exec { spec, toolchain -> + spec.environment("RUSTFLAGS", "-C lto=no -C link-arg=-o -C link-arg=target/${toolchain.target}/$profile/lib${libname}.so") + } +} + +preBuild.dependsOn "cargoBuild" + +def coroutinesVersion = '1.3.5' +def roomVersion = '2.2.5' +def workVersion = '2.3.4' dependencies { api project(':plugin') - api 'androidx.fragment:fragment-ktx:1.2.1' + api 'androidx.fragment:fragment-ktx:1.2.4' api "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" api "androidx.lifecycle:lifecycle-livedata-core-ktx:$lifecycleVersion" - api 'androidx.preference:preference:1.1.0' + api 'androidx.preference:preference:1.1.1' api "androidx.room:room-runtime:$roomVersion" api "androidx.work:work-runtime-ktx:$workVersion" api "androidx.work:work-gcm:$workVersion" api 'com.crashlytics.sdk.android:crashlytics:2.10.1' api 'com.google.android.gms:play-services-oss-licenses:17.0.0' api 'com.google.code.gson:gson:2.8.6' - api 'com.google.firebase:firebase-analytics:17.2.2' - api 'com.google.firebase:firebase-config:19.1.1' - api 'dnsjava:dnsjava:2.1.9' + api 'com.google.firebase:firebase-analytics:17.3.0' + api 'com.google.firebase:firebase-config:19.1.3' + api 'dnsjava:dnsjava:3.0.2' api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" api "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutinesVersion" - api 'org.connectbot.jsocks:jsocks:1.0.0' coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:$desugarLibsVersion" kapt "androidx.room:room-compiler:$roomVersion" testImplementation "junit:junit:$junitVersion" diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro index f2c7cde94e..97f6f95aaa 100644 --- a/core/proguard-rules.pro +++ b/core/proguard-rules.pro @@ -20,8 +20,3 @@ # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile - -# https://issuetracker.google.com/issues/147972078#comment4 --keepclasseswithmembers class * extends androidx.lifecycle.ViewModel { - (); -} diff --git a/core/src/androidTest/java/com/github/shadowsocks/acl/AclMatcherTest.kt b/core/src/androidTest/java/com/github/shadowsocks/acl/AclMatcherTest.kt deleted file mode 100644 index 003c38c47d..0000000000 --- a/core/src/androidTest/java/com/github/shadowsocks/acl/AclMatcherTest.kt +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * * - * Copyright (C) 2020 by Max Lv * - * Copyright (C) 2020 by Mygod Studio * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -package com.github.shadowsocks.acl - -import androidx.test.core.app.ApplicationProvider -import com.github.shadowsocks.Core -import com.github.shadowsocks.utils.parseNumericAddress -import kotlinx.coroutines.runBlocking -import org.junit.Assert -import org.junit.BeforeClass -import org.junit.Test - -class AclMatcherTest { - companion object { - @BeforeClass - @JvmStatic - fun setup() { - Core.app = ApplicationProvider.getApplicationContext() - } - } - - @Test - fun emptyFile() { - runBlocking { - AclMatcher().apply { - init(AclTest.BYPASS_BASE.reader()) - Assert.assertTrue(shouldBypassIpv4(ByteArray(4))) - Assert.assertTrue(shouldBypassIpv6(ByteArray(16))) - Assert.assertNull(shouldBypass("www.google.com")) - } - } - } - - @Test - fun basic() { - runBlocking { - AclMatcher().apply { - init(AclTest.INPUT1.reader()) - Assert.assertTrue(shouldBypassIpv4("0.1.2.3".parseNumericAddress()!!.address)) - Assert.assertFalse(shouldBypassIpv4("1.0.1.2".parseNumericAddress()!!.address)) - Assert.assertTrue(shouldBypassIpv4("1.0.3.2".parseNumericAddress()!!.address)) - Assert.assertTrue(shouldBypassIpv6("::".parseNumericAddress()!!.address)) - Assert.assertFalse(shouldBypassIpv6("2020::2020".parseNumericAddress()!!.address)) - Assert.assertTrue(shouldBypassIpv6("fe80::2020".parseNumericAddress()!!.address)) - Assert.assertTrue(shouldBypass("4tern.com") == false) - Assert.assertTrue(shouldBypass("www.4tern.com") == false) - Assert.assertNull(shouldBypass("www.google.com")) - } - } - } - - @Test - fun bypassList() { - runBlocking { - AclMatcher().apply { - init(AclTest.INPUT2.reader()) - Assert.assertFalse(shouldBypassIpv4("0.1.2.3".parseNumericAddress()!!.address)) - Assert.assertTrue(shouldBypassIpv4("10.0.1.2".parseNumericAddress()!!.address)) - Assert.assertTrue(shouldBypassIpv4("10.10.1.2".parseNumericAddress()!!.address)) - Assert.assertFalse(shouldBypassIpv4("11.0.1.2".parseNumericAddress()!!.address)) - Assert.assertTrue(shouldBypass("chrome.com") == true) - Assert.assertTrue(shouldBypass("about.google") == false) - Assert.assertNull(shouldBypass("www.google.com")) - } - } - } -} diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 6a1cdc3006..a1d1bddea0 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -103,7 +103,6 @@ * - * Copyright (C) 2019 by Mygod Studio * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -package com.github.shadowsocks.acl - -import com.github.shadowsocks.Core -import com.github.shadowsocks.net.Subnet -import java.io.Reader -import java.net.Inet4Address -import java.net.Inet6Address - -class AclMatcher : AutoCloseable { - companion object { - init { - System.loadLibrary("jni-helper") - } - - @JvmStatic private external fun init(): Long - @JvmStatic private external fun close(handle: Long) - - @JvmStatic private external fun addBypassDomain(handle: Long, regex: String): Boolean - @JvmStatic private external fun addProxyDomain(handle: Long, regex: String): Boolean - @JvmStatic private external fun build(handle: Long, memoryLimit: Long): String? - @JvmStatic private external fun matchHost(handle: Long, host: String): Int - } - - class Re2Exception(message: String) : IllegalArgumentException(message) - - private var handle = 0L - override fun close() { - if (handle != 0L) { - close(handle) - handle = 0L - } - } - - private var subnetsIpv4 = emptyList() - private var subnetsIpv6 = emptyList() - private var bypass = false - - suspend fun init(id: String) = init(Acl.getFile(id).bufferedReader()) - suspend fun init(reader: Reader) { - fun Sequence.dedup() = sequence { - val iterator = map { it.toImmutable() }.sortedWith(Subnet.Immutable).iterator() - var current: Subnet.Immutable? = null - while (iterator.hasNext()) { - val next = iterator.next() - if (current?.matches(next) == true) continue - yield(next) - current = next - } - }.toList() - check(handle == 0L) - handle = init() - try { - val (bypass, subnets) = Acl.parse(reader, { - check(addBypassDomain(handle, it)) - }, { - check(addProxyDomain(handle, it)) - }) - build(handle, if (Core.activity.isLowRamDevice) 8 shl 20 else 64 shl 20)?.also { throw Re2Exception(it) } - subnetsIpv4 = subnets.asSequence().filter { it.address is Inet4Address }.dedup() - subnetsIpv6 = subnets.asSequence().filter { it.address is Inet6Address }.dedup() - this.bypass = bypass - } catch (e: Exception) { - close() - throw e - } - } - - private fun quickMatches(subnets: List, ip: ByteArray): Boolean { - val i = subnets.binarySearch(Subnet.Immutable(ip), Subnet.Immutable) - return i >= 0 || i < -1 && subnets[-i - 2].matches(ip) - } - - fun shouldBypassIpv4(ip: ByteArray) = bypass xor quickMatches(subnetsIpv4, ip) - fun shouldBypassIpv6(ip: ByteArray) = bypass xor quickMatches(subnetsIpv6, ip) - fun shouldBypass(host: String) = when (val e = matchHost(handle, host)) { - 0 -> null - 1 -> true - 2 -> false - else -> error("matchHost -> $e") - } -} diff --git a/core/src/main/java/com/github/shadowsocks/bg/BaseService.kt b/core/src/main/java/com/github/shadowsocks/bg/BaseService.kt index e46b56b217..d590386d4f 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/BaseService.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/BaseService.kt @@ -37,6 +37,7 @@ import com.github.shadowsocks.aidl.IShadowsocksService import com.github.shadowsocks.aidl.IShadowsocksServiceCallback import com.github.shadowsocks.aidl.TrafficStats import com.github.shadowsocks.core.R +import com.github.shadowsocks.net.DnsResolverCompat import com.github.shadowsocks.net.HostsFile import com.github.shadowsocks.preference.DataStore import com.github.shadowsocks.utils.* @@ -46,7 +47,6 @@ import java.io.File import java.io.IOException import java.net.URL import java.net.UnknownHostException -import java.util.* /** * This object uses WeakMap to simulate the effects of multi-inheritance. @@ -74,6 +74,7 @@ object BaseService { var processes: GuardedProcessPool? = null var proxy: ProxyInstance? = null var udpFallback: ProxyInstance? = null + var localDns: LocalDnsWorker? = null var notification: ServiceNotification? = null val closeReceiver = broadcastReceiver { _, intent -> @@ -232,7 +233,7 @@ object BaseService { } } - fun buildAdditionalArguments(cmd: ArrayList): ArrayList = cmd + val isVpnService get() = false suspend fun startProcesses(hosts: HostsFile) { val configRoot = (if (Build.VERSION.SDK_INT < 24 || app.getSystemService() @@ -241,12 +242,13 @@ object BaseService { data.proxy!!.start(this, File(Core.deviceStorage.noBackupFilesDir, "stat_main"), File(configRoot, CONFIG_FILE), - if (udpFallback == null) "-u" else null) + if (udpFallback == null) "-U" else null) check(udpFallback?.plugin == null) { "UDP fallback cannot have plugins" } udpFallback?.start(this, File(Core.deviceStorage.noBackupFilesDir, "stat_udp"), File(configRoot, CONFIG_FILE_UDP), - "-U") + "-u", false) + data.localDns = LocalDnsWorker(this::rawResolver).apply { start() } } fun startRunner() { @@ -260,6 +262,8 @@ object BaseService { close(scope) data.processes = null } + data.localDns?.shutdown(scope) + data.localDns = null } fun stopRunner(restart: Boolean = false, msg: String? = null) { @@ -309,6 +313,7 @@ object BaseService { suspend fun preInit() { } suspend fun getActiveNetwork() = if (Build.VERSION.SDK_INT >= 23) Core.connectivity.activeNetwork else null suspend fun resolver(host: String) = DnsResolverCompat.resolveOnActiveNetwork(host) + suspend fun rawResolver(query: ByteArray) = DnsResolverCompat.resolveRawOnActiveNetwork(query) suspend fun openConnection(url: URL) = url.openConnection() fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { diff --git a/core/src/main/java/com/github/shadowsocks/bg/Executable.kt b/core/src/main/java/com/github/shadowsocks/bg/Executable.kt index 01c97419b4..0e6136d6c2 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/Executable.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/Executable.kt @@ -31,7 +31,7 @@ import java.io.IOException object Executable { const val REDSOCKS = "libredsocks.so" - const val SS_LOCAL = "libss-local.so" + const val SS_LOCAL = "libsslocal.so" const val TUN2SOCKS = "libtun2socks.so" private val EXECUTABLES = setOf(SS_LOCAL, REDSOCKS, TUN2SOCKS) diff --git a/core/src/main/java/com/github/shadowsocks/bg/LocalDnsService.kt b/core/src/main/java/com/github/shadowsocks/bg/LocalDnsService.kt deleted file mode 100644 index f5979c5e71..0000000000 --- a/core/src/main/java/com/github/shadowsocks/bg/LocalDnsService.kt +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * * - * Copyright (C) 2017 by Max Lv * - * Copyright (C) 2017 by Mygod Studio * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -package com.github.shadowsocks.bg - -import com.github.shadowsocks.acl.Acl -import com.github.shadowsocks.acl.AclMatcher -import com.github.shadowsocks.net.HostsFile -import com.github.shadowsocks.net.LocalDnsServer -import com.github.shadowsocks.net.Socks5Endpoint -import com.github.shadowsocks.preference.DataStore -import kotlinx.coroutines.CoroutineScope -import java.net.InetSocketAddress -import java.net.URI -import java.net.URISyntaxException -import java.util.* - -object LocalDnsService { - private val servers = WeakHashMap() - - interface Interface : BaseService.Interface { - override suspend fun startProcesses(hosts: HostsFile) { - super.startProcesses(hosts) - val profile = data.proxy!!.profile - val dns = try { - URI("dns://${profile.remoteDns}") - } catch (e: URISyntaxException) { - throw BaseService.ExpectedExceptionWrapper(e) - } - LocalDnsServer(this::resolver, - Socks5Endpoint(dns.host, if (dns.port < 0) 53 else dns.port), - DataStore.proxyAddress, - hosts, - !profile.udpdns, - if (profile.route == Acl.ALL) null else object { - suspend fun createAcl() = AclMatcher().apply { init(profile.route) } - }::createAcl).also { - servers[this] = it - }.start(InetSocketAddress(DataStore.listenAddress, DataStore.portLocalDns)) - } - - override fun killProcesses(scope: CoroutineScope) { - servers.remove(this)?.shutdown(scope) - super.killProcesses(scope) - } - } -} diff --git a/core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt b/core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt new file mode 100644 index 0000000000..3c7cd82cbe --- /dev/null +++ b/core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt @@ -0,0 +1,56 @@ +package com.github.shadowsocks.bg + +import android.net.LocalSocket +import android.util.Log +import com.crashlytics.android.Crashlytics +import com.github.shadowsocks.Core +import com.github.shadowsocks.net.ConcurrentLocalSocketListener +import com.github.shadowsocks.net.DnsResolverCompat +import com.github.shadowsocks.utils.printLog +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.TimeoutCancellationException +import kotlinx.coroutines.launch +import org.xbill.DNS.Message +import org.xbill.DNS.Rcode +import java.io.DataInputStream +import java.io.DataOutputStream +import java.io.File +import java.io.IOException + +class LocalDnsWorker(private val resolver: suspend (ByteArray) -> ByteArray) : ConcurrentLocalSocketListener( + "LocalDnsThread", File(Core.deviceStorage.noBackupFilesDir, "local_dns_path")), CoroutineScope { + override fun acceptInternal(socket: LocalSocket) = error("big no no") + override fun accept(socket: LocalSocket) { + launch { + socket.use { + val input = DataInputStream(socket.inputStream) + val query = ByteArray(input.readUnsignedShort()) + input.read(query) + try { + resolver(query) + } catch (e: Exception) { + when (e) { + is TimeoutCancellationException -> Crashlytics.log(Log.WARN, name, "Resolving timed out") + is CancellationException -> { } // ignore + is IOException -> Crashlytics.log(Log.WARN, name, e.message) + else -> printLog(e) + } + try { + DnsResolverCompat.prepareDnsResponse(Message(query)).apply { + header.rcode = Rcode.SERVFAIL + }.toWire() + } catch (_: IOException) { + byteArrayOf() // return empty if cannot parse packet + } + }?.let { response -> + try { + val output = DataOutputStream(socket.outputStream) + output.writeShort(response.size) + output.write(response) + } catch (_: IOException) { } // connection early close possibly due to resolving timeout + } + } + } + } +} diff --git a/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt b/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt index 488bc8ace4..6d17ad09bb 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt @@ -26,6 +26,7 @@ import com.github.shadowsocks.Core import com.github.shadowsocks.acl.Acl import com.github.shadowsocks.acl.AclSyncer import com.github.shadowsocks.database.Profile +import com.github.shadowsocks.net.DnsResolverCompat import com.github.shadowsocks.net.HostsFile import com.github.shadowsocks.plugin.PluginConfiguration import com.github.shadowsocks.plugin.PluginManager @@ -109,32 +110,40 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro * Sensitive shadowsocks configuration file requires extra protection. It may be stored in encrypted storage or * device storage, depending on which is currently available. */ - fun start(service: BaseService.Interface, stat: File, configFile: File, extraFlag: String? = null) { + fun start(service: BaseService.Interface, stat: File, configFile: File, extraFlag: String? = null, + dnsRelay: Boolean = true) { trafficMonitor = TrafficMonitor(stat) this.configFile = configFile val config = profile.toJson() - plugin?.let { (path, opts) -> config.put("plugin", path).put("plugin_opts", opts.toString()) } + val vpnFlags = if (service.isVpnService) ";V" else "" + plugin?.let { (path, opts) -> config.put("plugin", path).put("plugin_opts", opts.toString() + vpnFlags) } + config.put("local_address", DataStore.listenAddress) + config.put("local_port", DataStore.portProxy) configFile.writeText(config.toString()) - val cmd = service.buildAdditionalArguments(arrayListOf( + val dns = try { + URI("dns://${profile.remoteDns}") + } catch (e: URISyntaxException) { + throw BaseService.ExpectedExceptionWrapper(e) + } + + val cmd = arrayListOf( File((service as Context).applicationInfo.nativeLibraryDir, Executable.SS_LOCAL).absolutePath, - "-b", DataStore.listenAddress, - "-l", DataStore.portProxy.toString(), - "-t", "600", - "-S", stat.absolutePath, - "-c", configFile.absolutePath)) + "--stat-path", stat.absolutePath, + "-c", configFile.absolutePath) + if (service.isVpnService) cmd += arrayListOf("--vpn") if (extraFlag != null) cmd.add(extraFlag) + if (dnsRelay) cmd += arrayListOf( + "--dns-relay", "${DataStore.listenAddress}:${DataStore.portLocalDns}", + "--remote-dns", "${dns.host}:${if (dns.port < 0) 53 else dns.port}") if (route != Acl.ALL) { cmd += "--acl" cmd += Acl.getFile(route).absolutePath } - // for UDP profile, it's only going to operate in UDP relay mode-only so this flag has no effect - if (profile.route == Acl.ALL) cmd += "-D" - - if (DataStore.tcpFastOpen) cmd += "--fast-open" + // if (DataStore.tcpFastOpen) cmd += "--fast-open" service.data.processes!!.start(cmd) } diff --git a/core/src/main/java/com/github/shadowsocks/bg/TransproxyService.kt b/core/src/main/java/com/github/shadowsocks/bg/TransproxyService.kt index d3b6ff4325..ff30cf5329 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/TransproxyService.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/TransproxyService.kt @@ -27,7 +27,7 @@ import com.github.shadowsocks.net.HostsFile import com.github.shadowsocks.preference.DataStore import java.io.File -class TransproxyService : Service(), LocalDnsService.Interface { +class TransproxyService : Service(), BaseService.Interface { override val data = BaseService.Data(this) override val tag: String get() = "ShadowsocksTransproxyService" override fun createNotification(profileName: String): ServiceNotification = @@ -35,7 +35,7 @@ class TransproxyService : Service(), LocalDnsService.Interface { override fun onBind(intent: Intent) = super.onBind(intent) override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int = - super.onStartCommand(intent, flags, startId) + super.onStartCommand(intent, flags, startId) private fun startRedsocksDaemon() { File(Core.deviceStorage.noBackupFilesDir, "redsocks.conf").writeText("""base { diff --git a/core/src/main/java/com/github/shadowsocks/bg/VpnService.kt b/core/src/main/java/com/github/shadowsocks/bg/VpnService.kt index 1b238241f4..b529492668 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/VpnService.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/VpnService.kt @@ -34,26 +34,18 @@ import com.github.shadowsocks.Core import com.github.shadowsocks.VpnRequestActivity import com.github.shadowsocks.acl.Acl import com.github.shadowsocks.core.R -import com.github.shadowsocks.net.ConcurrentLocalSocketListener -import com.github.shadowsocks.net.DefaultNetworkListener -import com.github.shadowsocks.net.HostsFile -import com.github.shadowsocks.net.Subnet +import com.github.shadowsocks.net.* import com.github.shadowsocks.preference.DataStore import com.github.shadowsocks.utils.Key import com.github.shadowsocks.utils.closeQuietly import com.github.shadowsocks.utils.int import com.github.shadowsocks.utils.printLog -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import java.io.File -import java.io.FileDescriptor -import java.io.IOException +import kotlinx.coroutines.* +import java.io.* import java.net.URL -import java.util.* import android.net.VpnService as BaseVpnService -class VpnService : BaseVpnService(), LocalDnsService.Interface { +class VpnService : BaseVpnService(), BaseService.Interface { companion object { private const val VPN_MTU = 1500 private const val PRIVATE_VLAN4_CLIENT = "172.19.0.1" @@ -115,7 +107,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { override fun onBind(intent: Intent) = when (intent.action) { SERVICE_INTERFACE -> super.onBind(intent) - else -> super.onBind(intent) + else -> super.onBind(intent) } override fun onRevoke() = stopRunner() @@ -134,7 +126,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { if (DataStore.serviceMode == Key.modeVpn) { if (prepare(this) != null) { startActivity(Intent(this, VpnRequestActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) - } else return super.onStartCommand(intent, flags, startId) + } else return super.onStartCommand(intent, flags, startId) } stopRunner() return Service.START_NOT_STICKY @@ -143,6 +135,10 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { override suspend fun preInit() = DefaultNetworkListener.start(this) { underlyingNetwork = it } override suspend fun getActiveNetwork() = DefaultNetworkListener.get() override suspend fun resolver(host: String) = DnsResolverCompat.resolve(DefaultNetworkListener.get(), host) + override suspend fun rawResolver(query: ByteArray) = + // no need to listen for network here as this is only used for forwarding local DNS queries. + // retries should be attempted by client. + DnsResolverCompat.resolveRaw(underlyingNetwork ?: throw IOException("no network"), query) override suspend fun openConnection(url: URL) = DefaultNetworkListener.get().openConnection(url) override suspend fun startProcesses(hosts: HostsFile) { @@ -151,10 +147,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { sendFd(startVpn()) } - override fun buildAdditionalArguments(cmd: ArrayList): ArrayList { - cmd += "-V" - return cmd - } + override val isVpnService get() = true private suspend fun startVpn(): FileDescriptor { val profile = data.proxy!!.profile diff --git a/core/src/main/java/com/github/shadowsocks/net/ChannelMonitor.kt b/core/src/main/java/com/github/shadowsocks/net/ChannelMonitor.kt deleted file mode 100644 index fa8d7a989c..0000000000 --- a/core/src/main/java/com/github/shadowsocks/net/ChannelMonitor.kt +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * * - * Copyright (C) 2019 by Max Lv * - * Copyright (C) 2019 by Mygod Studio * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -package com.github.shadowsocks.net - -import android.os.Build -import com.github.shadowsocks.utils.printLog -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.sendBlocking -import java.io.IOException -import java.nio.ByteBuffer -import java.nio.channels.* - -class ChannelMonitor : Thread("ChannelMonitor") { - private data class Registration(val channel: SelectableChannel, - val ops: Int, - val listener: (SelectionKey) -> Unit) { - val result = CompletableDeferred() - } - - private val selector = Selector.open() - private val registrationPipe = Pipe.open() - private val pendingRegistrations = Channel(Channel.UNLIMITED) - private val closeChannel = Channel(1) - @Volatile - private var running = true - - private fun registerInternal(channel: SelectableChannel, ops: Int, block: (SelectionKey) -> Unit) = - channel.register(selector, ops, block) - - init { - registrationPipe.source().apply { - configureBlocking(false) - registerInternal(this, SelectionKey.OP_READ) { - val junk = ByteBuffer.allocateDirect(1) - while (read(junk) > 0) { - pendingRegistrations.poll()!!.apply { - try { - result.complete(registerInternal(channel, ops, listener)) - } catch (e: Exception) { - result.completeExceptionally(e) - } - } - junk.clear() - } - } - } - start() - } - - /** - * Prevent NetworkOnMainThreadException because people enable strict mode for no reasons. - */ - private suspend fun WritableByteChannel.writeCompat(src: ByteBuffer) = - if (Build.VERSION.SDK_INT <= 23) withContext(Dispatchers.Default) { write(src) } else write(src) - - suspend fun register(channel: SelectableChannel, ops: Int, block: (SelectionKey) -> Unit): SelectionKey { - val registration = Registration(channel, ops, block) - pendingRegistrations.send(registration) - ByteBuffer.allocateDirect(1).also { junk -> - loop@ while (running) when (registrationPipe.sink().writeCompat(junk)) { - 0 -> kotlinx.coroutines.yield() - 1 -> break@loop - else -> throw IOException("Failed to register in the channel") - } - } - if (!running) throw CancellationException() - return registration.result.await() - } - - suspend fun wait(channel: SelectableChannel, ops: Int) = CompletableDeferred().run { - register(channel, ops) { - if (it.isValid) try { - it.interestOps(0) // stop listening - } catch (_: CancelledKeyException) { } - complete(it) - } - await() - } - - override fun run() { - while (running) { - val num = try { - selector.select() - } catch (e: Exception) { - printLog(e) - continue - } - if (num <= 0) continue - val iterator = selector.selectedKeys().iterator() - while (iterator.hasNext()) { - val key = iterator.next() - iterator.remove() - (key.attachment() as (SelectionKey) -> Unit)(key) - } - } - closeChannel.sendBlocking(Unit) - } - - fun close(scope: CoroutineScope) { - running = false - selector.wakeup() - scope.launch { - closeChannel.receive() - selector.keys().forEach { it.channel().close() } - selector.close() - } - } -} diff --git a/core/src/main/java/com/github/shadowsocks/bg/DnsResolverCompat.kt b/core/src/main/java/com/github/shadowsocks/net/DnsResolverCompat.kt similarity index 68% rename from core/src/main/java/com/github/shadowsocks/bg/DnsResolverCompat.kt rename to core/src/main/java/com/github/shadowsocks/net/DnsResolverCompat.kt index c4790ad4dc..25568313b6 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/DnsResolverCompat.kt +++ b/core/src/main/java/com/github/shadowsocks/net/DnsResolverCompat.kt @@ -18,7 +18,7 @@ * * *******************************************************************************/ -package com.github.shadowsocks.bg +package com.github.shadowsocks.net import android.annotation.SuppressLint import android.annotation.TargetApi @@ -36,8 +36,11 @@ import com.github.shadowsocks.utils.int import com.github.shadowsocks.utils.parseNumericAddress import com.github.shadowsocks.utils.printLog import kotlinx.coroutines.* +import org.xbill.DNS.* import java.io.FileDescriptor import java.io.IOException +import java.net.Inet4Address +import java.net.Inet6Address import java.net.InetAddress import java.util.concurrent.Executor import java.util.concurrent.Executors @@ -94,6 +97,22 @@ sealed class DnsResolverCompat { override fun bindSocket(network: Network, socket: FileDescriptor) = instance.bindSocket(network, socket) override suspend fun resolve(network: Network, host: String) = instance.resolve(network, host) override suspend fun resolveOnActiveNetwork(host: String) = instance.resolveOnActiveNetwork(host) + override suspend fun resolveRaw(network: Network, query: ByteArray) = instance.resolveRaw(network, query) + override suspend fun resolveRawOnActiveNetwork(query: ByteArray) = instance.resolveRawOnActiveNetwork(query) + + // additional platform-independent DNS helpers + + /** + * TTL returned from localResolver is set to 120. Android API does not provide TTL, + * so we suppose Android apps should not care about TTL either. + */ + private const val TTL = 120L + + fun prepareDnsResponse(request: Message) = Message(request.header.id).apply { + header.setFlag(Flags.QR.toInt()) // this is a response + if (request.header.getFlag(Flags.RD.toInt())) header.setFlag(Flags.RD.toInt()) + request.question?.also { addRecord(it, Section.QUESTION) } + } } @Throws(IOException::class) @@ -102,6 +121,8 @@ sealed class DnsResolverCompat { Os.connect(fd, address, port) abstract suspend fun resolve(network: Network, host: String): Array abstract suspend fun resolveOnActiveNetwork(host: String): Array + abstract suspend fun resolveRaw(network: Network, query: ByteArray): ByteArray + abstract suspend fun resolveRawOnActiveNetwork(query: ByteArray): ByteArray @SuppressLint("PrivateApi") private open class DnsResolverCompat21 : DnsResolverCompat() { @@ -138,6 +159,40 @@ sealed class DnsResolverCompat { GlobalScope.async(unboundedIO) { network.getAllByName(host) }.await() override suspend fun resolveOnActiveNetwork(host: String) = GlobalScope.async(unboundedIO) { InetAddress.getAllByName(host) }.await() + + private suspend fun resolveRaw(query: ByteArray, + hostResolver: suspend (String) -> Array): ByteArray { + val request = try { + Message(query) + } catch (e: IOException) { + throw UnsupportedOperationException(e) // unrecognized packet + } + when (val opcode = request.header.opcode) { + Opcode.QUERY -> { } + else -> throw UnsupportedOperationException("Unsupported opcode $opcode") + } + val question = request.question + val isIpv6 = when (val type = question?.type) { + Type.A -> false + Type.AAAA -> true + else -> throw UnsupportedOperationException("Unsupported query type $type") + } + val host = question.name.canonicalize().toString(true) + return prepareDnsResponse(request).apply { + header.setFlag(Flags.RA.toInt()) // recursion available + for (address in hostResolver(host).asIterable().run { + if (isIpv6) filterIsInstance() else filterIsInstance() + }) addRecord(when (address) { + is Inet4Address -> ARecord(question.name, DClass.IN, TTL, address) + is Inet6Address -> AAAARecord(question.name, DClass.IN, TTL, address) + else -> error("Unsupported address $address") + }, Section.ANSWER) + }.toWire() + } + override suspend fun resolveRaw(network: Network, query: ByteArray) = + resolveRaw(query) { resolve(network, it) } + override suspend fun resolveRawOnActiveNetwork(query: ByteArray) = + resolveRaw(query, this::resolveOnActiveNetwork) } @TargetApi(23) @@ -154,6 +209,8 @@ sealed class DnsResolverCompat { override fun bindSocket(network: Network, socket: FileDescriptor) = network.bindSocket(socket) + private val activeNetwork get() = Core.connectivity.activeNetwork ?: throw IOException("no network") + override suspend fun resolve(network: Network, host: String): Array { return suspendCancellableCoroutine { cont -> val signal = CancellationSignal() @@ -167,9 +224,19 @@ sealed class DnsResolverCompat { }) } } + override suspend fun resolveOnActiveNetwork(host: String) = resolve(activeNetwork, host) - override suspend fun resolveOnActiveNetwork(host: String): Array { - return resolve(Core.connectivity.activeNetwork ?: return emptyArray(), host) + override suspend fun resolveRaw(network: Network, query: ByteArray): ByteArray { + return suspendCancellableCoroutine { cont -> + val signal = CancellationSignal() + cont.invokeOnCancellation { signal.cancel() } + DnsResolver.getInstance().rawQuery(network, query, DnsResolver.FLAG_NO_RETRY, this, + signal, object : DnsResolver.Callback { + override fun onAnswer(answer: ByteArray, rcode: Int) = cont.resume(answer) + override fun onError(error: DnsResolver.DnsException) = cont.resumeWithException(IOException(error)) + }) + } } + override suspend fun resolveRawOnActiveNetwork(query: ByteArray) = resolveRaw(activeNetwork, query) } } diff --git a/core/src/main/java/com/github/shadowsocks/net/LocalDnsServer.kt b/core/src/main/java/com/github/shadowsocks/net/LocalDnsServer.kt deleted file mode 100644 index 9bfc5aa2d2..0000000000 --- a/core/src/main/java/com/github/shadowsocks/net/LocalDnsServer.kt +++ /dev/null @@ -1,213 +0,0 @@ -/******************************************************************************* - * * - * Copyright (C) 2019 by Max Lv * - * Copyright (C) 2019 by Mygod Studio * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -package com.github.shadowsocks.net - -import android.util.Log -import com.crashlytics.android.Crashlytics -import com.github.shadowsocks.acl.AclMatcher -import com.github.shadowsocks.bg.BaseService -import com.github.shadowsocks.utils.printLog -import kotlinx.coroutines.* -import org.xbill.DNS.* -import java.io.IOException -import java.net.* -import java.nio.ByteBuffer -import java.nio.channels.DatagramChannel -import java.nio.channels.SelectionKey -import java.nio.channels.SocketChannel - -/** - * A simple DNS conditional forwarder. - * - * No cache is provided as localResolver may change from time to time. We expect DNS clients to do cache themselves. - * - * Based on: - * https://github.com/bitcoinj/httpseed/blob/809dd7ad9280f4bc98a356c1ffb3d627bf6c7ec5/src/main/kotlin/dns.kt - * https://github.com/shadowsocks/overture/tree/874f22613c334a3b78e40155a55479b7b69fee04 - */ -class LocalDnsServer(private val localResolver: suspend (String) -> Array, - private val remoteDns: Socks5Endpoint, - private val proxy: SocketAddress, - private val hosts: HostsFile, - /** - * Forward UDP queries to TCP. - */ - private val tcp: Boolean = false, - aclSpawn: (suspend () -> AclMatcher)? = null) : CoroutineScope { - companion object { - private const val TAG = "LocalDnsServer" - private const val TIMEOUT = 10_000L - /** - * TTL returned from localResolver is set to 120. Android API does not provide TTL, - * so we suppose Android apps should not care about TTL either. - */ - private const val TTL = 120L - private const val UDP_PACKET_SIZE = 512 - - private fun prepareDnsResponse(request: Message) = Message(request.header.id).apply { - header.setFlag(Flags.QR.toInt()) // this is a response - if (request.header.getFlag(Flags.RD.toInt())) header.setFlag(Flags.RD.toInt()) - request.question?.also { addRecord(it, Section.QUESTION) } - } - - private fun cookDnsResponse(request: Message, results: Iterable) = - ByteBuffer.wrap(prepareDnsResponse(request).apply { - header.setFlag(Flags.RA.toInt()) // recursion available - for (address in results) addRecord(when (address) { - is Inet4Address -> ARecord(question.name, DClass.IN, TTL, address) - is Inet6Address -> AAAARecord(question.name, DClass.IN, TTL, address) - else -> error("Unsupported address $address") - }, Section.ANSWER) - }.toWire()) - } - - private val monitor = ChannelMonitor() - - override val coroutineContext = SupervisorJob() + CoroutineExceptionHandler { _, t -> - if (t is IOException) Crashlytics.log(Log.WARN, TAG, t.message) else printLog(t) - } - private val acl = aclSpawn?.let { async { it() } } - - suspend fun start(listen: SocketAddress) = DatagramChannel.open().run { - configureBlocking(false) - try { - socket().bind(listen) - } catch (e: BindException) { - throw BaseService.ExpectedExceptionWrapper(e) - } - monitor.register(this, SelectionKey.OP_READ) { handlePacket(this) } - } - - private fun handlePacket(channel: DatagramChannel) { - val buffer = ByteBuffer.allocateDirect(UDP_PACKET_SIZE) - val source = channel.receive(buffer)!! - buffer.flip() - launch { - val reply = resolve(buffer) - while (channel.send(reply, source) <= 0) monitor.wait(channel, SelectionKey.OP_WRITE) - } - } - - private suspend fun resolve(packet: ByteBuffer): ByteBuffer { - val request = try { - Message(packet) - } catch (e: IOException) { // we cannot parse the message, do not attempt to handle it at all - Crashlytics.log(Log.WARN, TAG, e.message) - return forward(packet) - } - return supervisorScope { - val remote = async { withTimeout(TIMEOUT) { forward(packet) } } - try { - if (request.header.opcode != Opcode.QUERY) return@supervisorScope remote.await() - val question = request.question - val isIpv6 = when (question?.type) { - Type.A -> false - Type.AAAA -> true - else -> return@supervisorScope remote.await() - } - val host = question.name.canonicalize().toString(true) - val hostsResults = hosts.resolve(host) - if (hostsResults.isNotEmpty()) { - remote.cancel() - return@supervisorScope cookDnsResponse(request, hostsResults.run { - if (isIpv6) filterIsInstance() else filterIsInstance() - }) - } - val acl = acl?.await() ?: return@supervisorScope remote.await() - val useLocal = when (acl.shouldBypass(host)) { - true -> true.also { remote.cancel() } - false -> return@supervisorScope remote.await() - null -> false - } - val localResults = try { - withTimeout(TIMEOUT) { localResolver(host) } - } catch (_: TimeoutCancellationException) { - Crashlytics.log(Log.WARN, TAG, "Local resolving timed out, falling back to remote resolving") - return@supervisorScope remote.await() - } catch (_: UnknownHostException) { - return@supervisorScope remote.await() - } - if (isIpv6) { - val filtered = localResults.filterIsInstance() - if (useLocal) return@supervisorScope cookDnsResponse(request, filtered) - if (filtered.any { acl.shouldBypassIpv6(it.address) }) { - remote.cancel() - cookDnsResponse(request, filtered) - } else remote.await() - } else { - val filtered = localResults.filterIsInstance() - if (useLocal) return@supervisorScope cookDnsResponse(request, filtered) - if (filtered.any { acl.shouldBypassIpv4(it.address) }) { - remote.cancel() - cookDnsResponse(request, filtered) - } else remote.await() - } - } catch (e: Exception) { - remote.cancel() - when (e) { - is TimeoutCancellationException -> Crashlytics.log(Log.WARN, TAG, "Remote resolving timed out") - is CancellationException -> { } // ignore - is IOException -> Crashlytics.log(Log.WARN, TAG, e.message) - else -> printLog(e) - } - ByteBuffer.wrap(prepareDnsResponse(request).apply { - header.rcode = Rcode.SERVFAIL - }.toWire()) - } - } - } - - private suspend fun forward(packet: ByteBuffer): ByteBuffer { - packet.position(0) // the packet might have been parsed, reset to beginning - return if (tcp) SocketChannel.open().use { channel -> - channel.configureBlocking(false) - channel.connect(proxy) - val wrapped = remoteDns.tcpWrap(packet) - while (!channel.finishConnect()) monitor.wait(channel, SelectionKey.OP_CONNECT) - while (channel.write(wrapped) >= 0 && wrapped.hasRemaining()) monitor.wait(channel, SelectionKey.OP_WRITE) - val result = remoteDns.tcpReceiveBuffer(UDP_PACKET_SIZE) - remoteDns.tcpUnwrap(result, channel::read) { monitor.wait(channel, SelectionKey.OP_READ) } - result - } else DatagramChannel.open().use { channel -> - channel.configureBlocking(false) - monitor.wait(channel, SelectionKey.OP_WRITE) - check(channel.send(remoteDns.udpWrap(packet), proxy) > 0) - val result = remoteDns.udpReceiveBuffer(UDP_PACKET_SIZE) - while (isActive) { - monitor.wait(channel, SelectionKey.OP_READ) - if (channel.receive(result) == proxy) break - result.clear() - } - result.flip() - remoteDns.udpUnwrap(result) - result - } - } - - fun shutdown(scope: CoroutineScope) { - cancel() - monitor.close(scope) - scope.launch { - this@LocalDnsServer.coroutineContext[Job]!!.join() - acl?.also { it.await().close() } - } - } -} diff --git a/core/src/main/java/com/github/shadowsocks/net/Socks5Endpoint.kt b/core/src/main/java/com/github/shadowsocks/net/Socks5Endpoint.kt deleted file mode 100644 index f30b98a4d9..0000000000 --- a/core/src/main/java/com/github/shadowsocks/net/Socks5Endpoint.kt +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * * - * Copyright (C) 2019 by Max Lv * - * Copyright (C) 2019 by Mygod Studio * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -package com.github.shadowsocks.net - -import com.github.shadowsocks.utils.parseNumericAddress -import net.sourceforge.jsocks.Socks4Message -import net.sourceforge.jsocks.Socks5Message -import java.io.EOFException -import java.io.IOException -import java.net.Inet4Address -import java.net.Inet6Address -import java.nio.ByteBuffer -import kotlin.math.max - -class Socks5Endpoint(host: String, port: Int) { - private val dest = host.parseNumericAddress().let { numeric -> - val bytes = numeric?.address ?: host.toByteArray().apply { check(size < 256) { "Hostname too long" } } - val type = when (numeric) { - null -> Socks5Message.SOCKS_ATYP_DOMAINNAME - is Inet4Address -> Socks5Message.SOCKS_ATYP_IPV4 - is Inet6Address -> Socks5Message.SOCKS_ATYP_IPV6 - else -> error("Unsupported address type $numeric") - } - ByteBuffer.allocate(bytes.size + (if (numeric == null) 1 else 0) + 3).apply { - put(type.toByte()) - if (numeric == null) put(bytes.size.toByte()) - put(bytes) - putShort(port.toShort()) - } - }.array() - private val headerReserved = max(3 + 3 + 16, 3 + dest.size) - - fun tcpWrap(message: ByteBuffer): ByteBuffer { - check(message.remaining() < 65536) { "TCP message too large" } - return ByteBuffer.allocateDirect(8 + dest.size + message.remaining()).apply { - put(Socks5Message.SOCKS_VERSION.toByte()) - put(1) // nmethods - put(0) // no authentication required - // header - put(Socks5Message.SOCKS_VERSION.toByte()) - put(Socks4Message.REQUEST_CONNECT.toByte()) - put(0) // reserved - put(dest) - // data - putShort(message.remaining().toShort()) - put(message) - flip() - } - } - fun tcpReceiveBuffer(size: Int) = ByteBuffer.allocateDirect(headerReserved + 4 + size) - suspend fun tcpUnwrap(buffer: ByteBuffer, reader: (ByteBuffer) -> Int, wait: suspend () -> Unit) { - suspend fun readBytes(till: Int) { - if (buffer.position() >= till) return - while (reader(buffer) >= 0 && buffer.position() < till) wait() - if (buffer.position() < till) throw EOFException("${buffer.position()} < $till") - } - suspend fun read(index: Int): Byte { - readBytes(index + 1) - return buffer[index] - } - if (read(0) != Socks5Message.SOCKS_VERSION.toByte()) throw IOException("Unsupported SOCKS version ${buffer[0]}") - if (read(1) != 0.toByte()) throw IOException("Unsupported authentication ${buffer[1]}") - if (read(2) != Socks5Message.SOCKS_VERSION.toByte()) throw IOException("Unsupported SOCKS version ${buffer[2]}") - if (read(3) != 0.toByte()) throw IOException("SOCKS5 server returned error ${buffer[3]}") - val dataOffset = when (val type = read(5)) { - Socks5Message.SOCKS_ATYP_IPV4.toByte() -> 4 - Socks5Message.SOCKS_ATYP_DOMAINNAME.toByte() -> 1 + read(6) - Socks5Message.SOCKS_ATYP_IPV6.toByte() -> 16 - else -> throw IOException("Unsupported address type $type") - } + 8 - readBytes(dataOffset + 2) - buffer.limit(buffer.position()) // store old position to update mark - buffer.position(dataOffset) - val dataLength = buffer.short.toUShort().toInt() - val end = buffer.position() + dataLength - if (end > buffer.capacity()) throw IOException( - "Buffer too small to contain the message: $dataLength > ${buffer.capacity() - buffer.position()}") - buffer.mark() - buffer.position(buffer.limit()) // restore old position - buffer.limit(end) - readBytes(buffer.limit()) - buffer.reset() - } - - private fun ByteBuffer.tryPosition(newPosition: Int) { - if (limit() < newPosition) throw EOFException("${limit()} < $newPosition") - position(newPosition) - } - - fun udpWrap(packet: ByteBuffer) = ByteBuffer.allocateDirect(3 + dest.size + packet.remaining()).apply { - // header - putShort(0) // reserved - put(0) // fragment number - put(dest) - // data - put(packet) - flip() - } - fun udpReceiveBuffer(size: Int) = ByteBuffer.allocateDirect(headerReserved + size) - fun udpUnwrap(packet: ByteBuffer) { - packet.tryPosition(3) - packet.tryPosition(6 + when (val type = packet.get()) { - Socks5Message.SOCKS_ATYP_IPV4.toByte() -> 4 - Socks5Message.SOCKS_ATYP_DOMAINNAME.toByte() -> 1 + packet.get() - Socks5Message.SOCKS_ATYP_IPV6.toByte() -> 16 - else -> throw IOException("Unsupported address type $type") - }) - packet.mark() - } -} diff --git a/core/src/main/java/com/github/shadowsocks/subscription/SubscriptionService.kt b/core/src/main/java/com/github/shadowsocks/subscription/SubscriptionService.kt index 5778a376b2..5b39b0b75a 100644 --- a/core/src/main/java/com/github/shadowsocks/subscription/SubscriptionService.kt +++ b/core/src/main/java/com/github/shadowsocks/subscription/SubscriptionService.kt @@ -24,8 +24,6 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.app.Service -import android.content.BroadcastReceiver -import android.content.Context import android.content.Intent import android.content.IntentFilter import android.os.IBinder @@ -35,7 +33,6 @@ import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat import androidx.lifecycle.MutableLiveData -import com.crashlytics.android.Crashlytics import com.github.shadowsocks.Core import com.github.shadowsocks.Core.app import com.github.shadowsocks.core.R diff --git a/core/src/main/java/com/github/shadowsocks/utils/Utils.kt b/core/src/main/java/com/github/shadowsocks/utils/Utils.kt index d0582dc49d..69c3b45a8d 100644 --- a/core/src/main/java/com/github/shadowsocks/utils/Utils.kt +++ b/core/src/main/java/com/github/shadowsocks/utils/Utils.kt @@ -70,7 +70,7 @@ fun FileDescriptor.closeQuietly() = try { Os.close(this) } catch (_: ErrnoException) { } -private val parseNumericAddress by lazy @SuppressLint("DiscouragedPrivateApi") { +private val parseNumericAddress by lazy @SuppressLint("SoonBlockedPrivateApi") { InetAddress::class.java.getDeclaredMethod("parseNumericAddress", String::class.java).apply { isAccessible = true } diff --git a/core/src/main/jni/Android.mk b/core/src/main/jni/Android.mk index f8549e58c6..9fb93e07f6 100755 --- a/core/src/main/jni/Android.mk +++ b/core/src/main/jni/Android.mk @@ -18,93 +18,6 @@ ROOT_PATH := $(LOCAL_PATH) BUILD_SHARED_EXECUTABLE := $(LOCAL_PATH)/build-shared-executable.mk -######################################################## -## libsodium -######################################################## - -include $(CLEAR_VARS) - -SODIUM_SOURCE := \ - crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c \ - crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c \ - crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c \ - crypto_core/ed25519/ref10/ed25519_ref10.c \ - crypto_core/hchacha20/core_hchacha20.c \ - crypto_core/salsa/ref/core_salsa_ref.c \ - crypto_generichash/blake2b/ref/blake2b-compress-ref.c \ - crypto_generichash/blake2b/ref/blake2b-ref.c \ - crypto_generichash/blake2b/ref/generichash_blake2b.c \ - crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \ - crypto_onetimeauth/poly1305/donna/poly1305_donna.c \ - crypto_pwhash/crypto_pwhash.c \ - crypto_pwhash/argon2/argon2-core.c \ - crypto_pwhash/argon2/argon2.c \ - crypto_pwhash/argon2/argon2-encoding.c \ - crypto_pwhash/argon2/argon2-fill-block-ref.c \ - crypto_pwhash/argon2/blake2b-long.c \ - crypto_pwhash/argon2/pwhash_argon2i.c \ - crypto_scalarmult/curve25519/scalarmult_curve25519.c \ - crypto_scalarmult/curve25519/ref10/x25519_ref10.c \ - crypto_stream/chacha20/stream_chacha20.c \ - crypto_stream/chacha20/ref/chacha20_ref.c \ - crypto_stream/salsa20/stream_salsa20.c \ - crypto_stream/salsa20/ref/salsa20_ref.c \ - crypto_verify/sodium/verify.c \ - randombytes/randombytes.c \ - randombytes/sysrandom/randombytes_sysrandom.c \ - sodium/core.c \ - sodium/runtime.c \ - sodium/utils.c \ - sodium/version.c - -LOCAL_MODULE := sodium -LOCAL_CFLAGS += -I$(LOCAL_PATH)/libsodium/src/libsodium/include \ - -I$(LOCAL_PATH)/include \ - -I$(LOCAL_PATH)/include/sodium \ - -I$(LOCAL_PATH)/libsodium/src/libsodium/include/sodium \ - -DPACKAGE_NAME=\"libsodium\" -DPACKAGE_TARNAME=\"libsodium\" \ - -DPACKAGE_VERSION=\"1.0.15\" -DPACKAGE_STRING=\"libsodium-1.0.15\" \ - -DPACKAGE_BUGREPORT=\"https://github.com/jedisct1/libsodium/issues\" \ - -DPACKAGE_URL=\"https://github.com/jedisct1/libsodium\" \ - -DPACKAGE=\"libsodium\" -DVERSION=\"1.0.15\" \ - -DHAVE_PTHREAD=1 \ - -DSTDC_HEADERS=1 \ - -DHAVE_SYS_TYPES_H=1 \ - -DHAVE_SYS_STAT_H=1 \ - -DHAVE_STDLIB_H=1 \ - -DHAVE_STRING_H=1 \ - -DHAVE_MEMORY_H=1 \ - -DHAVE_STRINGS_H=1 \ - -DHAVE_INTTYPES_H=1 \ - -DHAVE_STDINT_H=1 \ - -DHAVE_UNISTD_H=1 \ - -D__EXTENSIONS__=1 \ - -D_ALL_SOURCE=1 \ - -D_GNU_SOURCE=1 \ - -D_POSIX_PTHREAD_SEMANTICS=1 \ - -D_TANDEM_SOURCE=1 \ - -DHAVE_DLFCN_H=1 \ - -DLT_OBJDIR=\".libs/\" \ - -DHAVE_SYS_MMAN_H=1 \ - -DNATIVE_LITTLE_ENDIAN=1 \ - -DASM_HIDE_SYMBOL=.hidden \ - -DHAVE_WEAK_SYMBOLS=1 \ - -DHAVE_ATOMIC_OPS=1 \ - -DHAVE_ARC4RANDOM=1 \ - -DHAVE_ARC4RANDOM_BUF=1 \ - -DHAVE_MMAP=1 \ - -DHAVE_MLOCK=1 \ - -DHAVE_MADVISE=1 \ - -DHAVE_MPROTECT=1 \ - -DHAVE_NANOSLEEP=1 \ - -DHAVE_POSIX_MEMALIGN=1 \ - -DHAVE_GETPID=1 \ - -DCONFIGURED=1 - -LOCAL_SRC_FILES := $(addprefix libsodium/src/libsodium/,$(SODIUM_SOURCE)) - -include $(BUILD_STATIC_LIBRARY) - ######################################################## ## libevent ######################################################## @@ -138,87 +51,6 @@ LOCAL_SRC_FILES := $(addprefix libancillary/, $(ANCILLARY_SOURCE)) include $(BUILD_STATIC_LIBRARY) -######################################################## -## libbloom -######################################################## - -include $(CLEAR_VARS) - -BLOOM_SOURCE := bloom.c murmur2/MurmurHash2.c - -LOCAL_MODULE := libbloom -LOCAL_CFLAGS += -I$(LOCAL_PATH)/shadowsocks-libev/libbloom \ - -I$(LOCAL_PATH)/shadowsocks-libev/libbloom/murmur2 - -LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libbloom/, $(BLOOM_SOURCE)) - -include $(BUILD_STATIC_LIBRARY) - -######################################################## -## libipset -######################################################## - -include $(CLEAR_VARS) - -bdd_src = bdd/assignments.c bdd/basics.c bdd/bdd-iterator.c bdd/expanded.c \ - bdd/reachable.c bdd/read.c bdd/write.c -map_src = map/allocation.c map/inspection.c map/ipv4_map.c map/ipv6_map.c \ - map/storage.c -set_src = set/allocation.c set/inspection.c set/ipv4_set.c set/ipv6_set.c \ - set/iterator.c set/storage.c - -IPSET_SOURCE := general.c $(bdd_src) $(map_src) $(set_src) - -LOCAL_MODULE := libipset -LOCAL_CFLAGS += -I$(LOCAL_PATH)/shadowsocks-libev/libipset/include \ - -I$(LOCAL_PATH)/shadowsocks-libev/libcork/include - -LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libipset/src/libipset/,$(IPSET_SOURCE)) - -include $(BUILD_STATIC_LIBRARY) - -######################################################## -## libcork -######################################################## - -include $(CLEAR_VARS) - -cli_src := cli/commands.c -core_src := core/allocator.c core/error.c core/gc.c \ - core/hash.c core/ip-address.c core/mempool.c \ - core/timestamp.c core/u128.c -ds_src := ds/array.c ds/bitset.c ds/buffer.c ds/dllist.c \ - ds/file-stream.c ds/hash-table.c ds/managed-buffer.c \ - ds/ring-buffer.c ds/slice.c -posix_src := posix/directory-walker.c posix/env.c posix/exec.c \ - posix/files.c posix/process.c posix/subprocess.c -pthreads_src := pthreads/thread.c - -CORK_SOURCE := $(cli_src) $(core_src) $(ds_src) $(posix_src) $(pthreads_src) - -LOCAL_MODULE := libcork -LOCAL_CFLAGS += -I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \ - -DCORK_API=CORK_LOCAL - -LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libcork/src/libcork/,$(CORK_SOURCE)) - -include $(BUILD_STATIC_LIBRARY) - -######################################################## -## libev -######################################################## - -include $(CLEAR_VARS) - -LOCAL_MODULE := libev -LOCAL_CFLAGS += -DNDEBUG -DHAVE_CONFIG_H \ - -I$(LOCAL_PATH)/include/libev -LOCAL_SRC_FILES := \ - libev/ev.c \ - libev/event.c - -include $(BUILD_STATIC_LIBRARY) - ######################################################## ## redsocks ######################################################## @@ -233,7 +65,7 @@ REDSOCKS_SOURCES := base.c http-connect.c \ LOCAL_STATIC_LIBRARIES := libevent LOCAL_MODULE := redsocks -LOCAL_SRC_FILES := $(addprefix redsocks/, $(REDSOCKS_SOURCES)) +LOCAL_SRC_FILES := $(addprefix redsocks/, $(REDSOCKS_SOURCES)) LOCAL_CFLAGS := -std=gnu99 -DUSE_IPTABLES \ -I$(LOCAL_PATH)/redsocks \ -I$(LOCAL_PATH)/libevent/include \ @@ -241,76 +73,6 @@ LOCAL_CFLAGS := -std=gnu99 -DUSE_IPTABLES \ include $(BUILD_SHARED_EXECUTABLE) -######################################################## -## shadowsocks-libev local -######################################################## - -include $(CLEAR_VARS) - -SHADOWSOCKS_SOURCES := local.c \ - cache.c udprelay.c utils.c netutils.c json.c jconf.c \ - acl.c http.c tls.c rule.c \ - crypto.c aead.c stream.c base64.c \ - plugin.c ppbloom.c \ - android.c - -LOCAL_MODULE := ss-local -LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES)) -LOCAL_CFLAGS := -Wall -fno-strict-aliasing -DMODULE_LOCAL \ - -DUSE_CRYPTO_MBEDTLS -DHAVE_CONFIG_H \ - -DCONNECT_IN_PROGRESS=EINPROGRESS \ - -I$(LOCAL_PATH)/include/shadowsocks-libev \ - -I$(LOCAL_PATH)/include \ - -I$(LOCAL_PATH)/libancillary \ - -I$(LOCAL_PATH)/mbedtls/include \ - -I$(LOCAL_PATH)/pcre \ - -I$(LOCAL_PATH)/libsodium/src/libsodium/include \ - -I$(LOCAL_PATH)/libsodium/src/libsodium/include/sodium \ - -I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \ - -I$(LOCAL_PATH)/shadowsocks-libev/libipset/include \ - -I$(LOCAL_PATH)/shadowsocks-libev/libbloom \ - -I$(LOCAL_PATH)/libev - -LOCAL_STATIC_LIBRARIES := libev libmbedtls libipset libcork libbloom \ - libsodium libancillary libpcre - -LOCAL_LDLIBS := -llog - -include $(BUILD_SHARED_EXECUTABLE) - -######################################################## -## jni-helper -######################################################## - -include $(CLEAR_VARS) - -LOCAL_MODULE:= jni-helper - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/re2 - -LOCAL_CFLAGS := -std=c++17 - -LOCAL_SRC_FILES := jni-helper.cpp \ - $(LOCAL_PATH)/re2/re2/bitstate.cc \ - $(LOCAL_PATH)/re2/re2/compile.cc \ - $(LOCAL_PATH)/re2/re2/dfa.cc \ - $(LOCAL_PATH)/re2/re2/nfa.cc \ - $(LOCAL_PATH)/re2/re2/onepass.cc \ - $(LOCAL_PATH)/re2/re2/parse.cc \ - $(LOCAL_PATH)/re2/re2/perl_groups.cc \ - $(LOCAL_PATH)/re2/re2/prog.cc \ - $(LOCAL_PATH)/re2/re2/re2.cc \ - $(LOCAL_PATH)/re2/re2/regexp.cc \ - $(LOCAL_PATH)/re2/re2/simplify.cc \ - $(LOCAL_PATH)/re2/re2/stringpiece.cc \ - $(LOCAL_PATH)/re2/re2/tostring.cc \ - $(LOCAL_PATH)/re2/re2/unicode_casefold.cc \ - $(LOCAL_PATH)/re2/re2/unicode_groups.cc \ - $(LOCAL_PATH)/re2/util/rune.cc \ - $(LOCAL_PATH)/re2/util/strutil.cc - -include $(BUILD_SHARED_LIBRARY) - ######################################################## ## tun2socks ######################################################## @@ -404,57 +166,3 @@ LOCAL_LDLIBS := -ldl -llog LOCAL_SRC_FILES := $(addprefix badvpn/, $(TUN2SOCKS_SOURCES)) include $(BUILD_SHARED_EXECUTABLE) - -######################################################## -## mbed TLS -######################################################## - -include $(CLEAR_VARS) - -LOCAL_MODULE := mbedtls - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/mbedtls/include - -MBEDTLS_SOURCES := $(wildcard $(LOCAL_PATH)/mbedtls/library/*.c) - -LOCAL_SRC_FILES := $(MBEDTLS_SOURCES:$(LOCAL_PATH)/%=%) - -include $(BUILD_STATIC_LIBRARY) - -######################################################## -## pcre -######################################################## - -include $(CLEAR_VARS) - -LOCAL_MODULE := pcre - -LOCAL_CFLAGS += -DHAVE_CONFIG_H - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/pcre/dist $(LOCAL_PATH)/pcre - -libpcre_src_files := \ - dist/pcre_byte_order.c \ - dist/pcre_compile.c \ - dist/pcre_config.c \ - dist/pcre_dfa_exec.c \ - dist/pcre_exec.c \ - dist/pcre_fullinfo.c \ - dist/pcre_get.c \ - dist/pcre_globals.c \ - dist/pcre_jit_compile.c \ - dist/pcre_maketables.c \ - dist/pcre_newline.c \ - dist/pcre_ord2utf8.c \ - dist/pcre_refcount.c \ - dist/pcre_string_utils.c \ - dist/pcre_study.c \ - dist/pcre_tables.c \ - dist/pcre_ucd.c \ - dist/pcre_valid_utf8.c \ - dist/pcre_version.c \ - dist/pcre_xclass.c - -LOCAL_SRC_FILES := $(addprefix pcre/, $(libpcre_src_files)) $(LOCAL_PATH)/patch/pcre/pcre_chartables.c - -include $(BUILD_STATIC_LIBRARY) diff --git a/core/src/main/jni/include/libev/config.h b/core/src/main/jni/include/libev/config.h deleted file mode 100644 index 5c46ab0fa1..0000000000 --- a/core/src/main/jni/include/libev/config.h +++ /dev/null @@ -1,126 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the `clock_gettime' function. */ -/* #undef HAVE_CLOCK_GETTIME */ - -/* Define to 1 to use the syscall interface for clock_gettime */ -#define HAVE_CLOCK_SYSCALL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the `epoll_ctl' function. */ -#define HAVE_EPOLL_CTL 1 - -/* Define to 1 if you have the `eventfd' function. */ -#define HAVE_EVENTFD 1 - -/* Define to 1 if the floor function is available */ -#define HAVE_FLOOR 1 - -/* Define to 1 if you have the `inotify_init' function. */ -#define HAVE_INOTIFY_INIT 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `kqueue' function. */ -/* #undef HAVE_KQUEUE */ - -/* Define to 1 if you have the `rt' library (-lrt). */ -/* #undef HAVE_LIBRT */ - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `nanosleep' function. */ -#define HAVE_NANOSLEEP 1 - -/* Define to 1 if you have the `poll' function. */ -#define HAVE_POLL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_POLL_H 1 - -/* Define to 1 if you have the `port_create' function. */ -/* #undef HAVE_PORT_CREATE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PORT_H */ - -/* Define to 1 if you have the `select' function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the `signalfd' function. */ -#define HAVE_SIGNALFD 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_EPOLL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_EVENTFD_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_EVENT_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_INOTIFY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SIGNALFD_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "libev" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "4.11" diff --git a/core/src/main/jni/include/pdnsd/config.h b/core/src/main/jni/include/pdnsd/config.h deleted file mode 100644 index 3740beae73..0000000000 --- a/core/src/main/jni/include/pdnsd/config.h +++ /dev/null @@ -1,437 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.in by autoheader. */ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -/* ONLY EDIT acconfig.h, NEVER config.h or config.h.in! - * config.h MAY BE OVERWRITTEN BY make, config.h.in by autoheader! */ - -/* Define your Target here. Currently defined are TARGET_LINUX (any - * architecture), TARGET_BSD (experimental; tested on FreeBSD, hopefully - * works for other BSD variants) and TARGET_CYGWIN. */ -#define TARGET TARGET_LINUX - -/* change the #undef to #define if you do not want to compile with special - * ISDN support for Linux. Note that the ISDN support will not compile ok on - * unpatched kernerls earlier than 2.2.12 (if you did apply newer isdn patches, - * it may work fine). This is not on by default because it will cause compile - * problems on some systems */ -/* #undef ISDN_SUPPORT */ - -/* The following regulates the IP Protocol support. Supported types are IPv4 - * and IPv6 (aka IPng). You may enable either or both of these protocols. - * Enabling in this context means that support for the respective protocol - * will be in the binary. When running the binary, one of the protocols may - * be activated via command line switches. Note that activating both IPv4 and - * IPv6 is pointless (and will not work because two UDP and two TCP threads - * will be started that concur for ports). Because of that, it is not allowed. - * When pdnsd runs with IPv6 activated it should be able to service queries - * from IPv6 as well as from IPv4 hosts, provided that you host is configured - * properly. - * For each of the protocols there are two options: ENABLE_IPV4 and ENABLE_IPV6 - * control whether support for the respective protocol is available in the - * binary. DEFAULT_IPV4 selects which protocol is enabled on pdnsd - * startup by default. 1 means IPv4, while 0 means IPv6. If support for - * a protocol was included in the executable, you can specify command line - * parameters to activate or deactivate that protocol (the options are -4 and - * -6), but it makes more sense to use the run_ipv4=on/off option in the - * configuration file. - * Make your choice. Note that IPv6 support is experimental in pdnsd. - * In normal operation, you will currently only need IPv4. */ -#define ENABLE_IPV4 1 -#define DEFAULT_IPV4 1 -#undef ENABLE_IPV6 - -/* In all pdnsd versions before 1.0.6, DNS queries were always done over - * TCP. Now, you have the choice. You can control that behaviour using - * the -m command line switch, and you can give a preset here. There - * are 3 different modes: - * UDP_ONLY: This is undoubtedly the fastest query method, because - * no TCP negotiation needs to be done. - * TCP_ONLY: This is slower than uo, but generally more secure - * against DNS spoofing. Note that some name servers on the - * internet do not support TCP queries, notably dnscache. - * TCP_UDP: TCP, then UDP. If the TCP query fails with a "connection refused"- - * error or times out, the query is retried using UDP. - * UDP_TCP: UDP, then TCP. If the UDP reply is truncated (i.e. the tc flag is set), - * the query is retried using TCP. */ -#define M_PRESET TCP_ONLY - -/* In addition to choosing the presets, you may also completely disable - * one of the protocols (TCP for preset UDP_ONLY and UDP for preset TCP_ONLY). - * This saves some executable space. */ -/* #undef NO_UDP_QUERIES */ -/* #undef NO_TCP_QUERIES */ - -/* With the following option, you can disable the TCP server functionality - * of pdnsd. Nearly no program does TCP queries, so you probably can do - * this safely and save some executable space and one thread. - * You also can turn off the TCP server at runtime with the --notcp option. */ -/* #undef NO_TCP_SERVER */ - -/* By undefining the following, you can disable the UDP source address - * discovery code. This is not recommended, but you may need it when - * running into compilation problems. */ -#define SRC_ADDR_DISC 1 - -/* NO_POLL specifies not to use poll(2), but select(2) instead. If you are - * unsure about what this means, just leave this as it is.*/ -/* #undef NO_POLL */ - -/* Define this for "hard" RFC 2181 compliance: this RFC states that - * implementations should discard answers whose RR sets have multiple - * different time stamps. While correct answers are generated, incorrect - * ones are normally tolerated and corrected. Full RFC compliance is - * however only achieved by deactivating this behaviour and thus being - * intolerant. */ -/* #undef RFC2181_ME_HARDER */ - -/* Define this to the device you want to use for getting random numbers. - * Leave this undefined if you wand to use the standard C library random - * function, which basically should be sufficient. - * Linux and FreeBSD have two random number devices: /dev/random and - * /dev/urandom. /dev/urandom might be less secure in some cases, but - * should still be more than sufficient. The use of /dev/random is - * discouraged, as reading from this device blocks when new random bits - * need to be gathered. */ -/* #undef RANDOM_DEVICE */ -#define R_DEFAULT 1 -/* #undef R_RANDOM */ -/* #undef R_ARC4RANDOM */ -/*#define RANDOM_DEVICE "/dev/urandom"*/ - -/* Designate which database manager to use for cacheing. - * default: native; others: gdbm */ -#define CACHE_DBM DBM_NATIVE - -#define CONFDIR "/data/data/com.github.shadowsocks" - -#define CACHEDIR "/data/data/com.github.shadowsocks" - -#define TEMPDIR "/data/data/com.github.shadowsocks/cache"; - -/* This is for various debugging facilities that produce debug output and - * double-check some values. You can enable debug messages with the -g option. - * Normally, you can switch this off safely by setting the number after DEBUG - * to 0. This will increase speed (although only marginally), save space - * in the executable (only about 12kB) and some stack space per thread - * (which may be significant if you have many threads running simultaneously). - * However, it may be an aid when debugging config files. - * The only defined debug levels by now are in the range 0 - 9. - * Define this to 9 if you want hex dumps of all the queries and replies pdnsd - * receives (you must also call pdnsd with -v9 to actually see the hex dumps). - * When in doubt, leave it defined to 1. */ -#define DEBUG 1 - -/* This defines the default verbosity of informational messages you will get. - This has nothing to to with the debug option (-g), but may be set with -v - option. 0 is for normal operation, up to 3 for debugging. - Unlike the debug messages, these messages will also be written to the syslog.*/ -#define VERBOSITY 0 - -/* Redefine this if you want another hash size. - * The number of hash buckets is computed as power of two (1< and it should be used (not on Ultrix). - */ -#define HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the `asprintf' function. */ -#define HAVE_ASPRINTF 1 - -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -/* #undef HAVE_DOPRNT */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `getline' function. */ -#if defined(__aarch64__) || defined(__x86_64__) -#define HAVE_GETLINE 1 -#endif - -/* Define to 1 if you have the `getpwnam_r' function. */ -//#define HAVE_GETPWNAM_R 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the `inet_ntop' function. */ -#define HAVE_INET_NTOP 1 - -/* Define to 1 if you have the `inet_pton' function. */ -#define HAVE_INET_PTON 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#define HAVE_LIBPTHREAD 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mempcpy' function. */ -//#define HAVE_MEMPCPY 1 - -/* Define to 1 if you have the `mkfifo' function. */ -#define HAVE_MKFIFO 1 - -/* Define to 1 if you have the `nanosleep' function. */ -#define HAVE_NANOSLEEP 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NET_IF_H 1 - -/* Define to 1 if you have the `poll' function. */ -#define HAVE_POLL 1 - -/* Define to 1 if you have the `select' function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if the system has the type `socklen_t'. */ -#define HAVE_SOCKLEN_T 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `stpcpy' function. */ -#if defined(__aarch64__) || defined(__x86_64__) -#define HAVE_STPCPY 1 -#endif - -/* Define to 1 if you have the `stpncpy' function. */ -//#define HAVE_STPNCPY 1 - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcpy' function. */ -/* #undef HAVE_STRLCPY */ - -/* Define to 1 if you have the `strndup' function. */ -#define HAVE_STRNDUP 1 - -/* Define to 1 if the system has the type `struct ifreq'. */ -#define HAVE_STRUCT_IFREQ 1 - -/* Define to 1 if the system has the type `struct in6_addr'. */ -#define HAVE_STRUCT_IN6_ADDR 1 - -/* Define to 1 if the system has the type `struct in_pktinfo'. */ -#define HAVE_STRUCT_IN_PKTINFO 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYSLOG_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_POLL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have that is POSIX.1 compatible. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the `uname' function. */ -#define HAVE_UNAME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `vasprintf' function. */ -#define HAVE_VASPRINTF 1 - -/* Define to 1 if you have the `vprintf' function. */ -#define HAVE_VPRINTF 1 - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at runtime. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -/* #undef STACK_DIRECTION */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Define to 1 if your declares `struct tm'. */ -/* #undef TM_IN_SYS_TIME */ - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif - - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `int' if does not define. */ -/* #undef pid_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ diff --git a/core/src/main/jni/include/shadowsocks-libev/config.h b/core/src/main/jni/include/shadowsocks-libev/config.h deleted file mode 100644 index 8594fa0dbe..0000000000 --- a/core/src/main/jni/include/shadowsocks-libev/config.h +++ /dev/null @@ -1,428 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -/* #undef AC_APPLE_UNIVERSAL_BUILD */ - -/* errno for incomplete non-blocking connect(2) */ -#define CONNECT_IN_PROGRESS EINPROGRESS - -/* Override libev default fd conversion macro. */ -/* #undef EV_FD_TO_WIN32_HANDLE */ - -/* Override libev default fd close macro. */ -/* #undef EV_WIN32_CLOSE_FD */ - -/* Override libev default handle conversion macro. */ -/* #undef EV_WIN32_HANDLE_TO_FD */ - -/* Reset max file descriptor size. */ -/* #undef FD_SETSIZE */ - -/* Define to 1 if you have the header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the `CCCryptorCreateWithMode' function. */ -/* #undef HAVE_CCCRYPTORCREATEWITHMODE */ - -/* Define to 1 if you have the `clock_gettime' function. */ -/* #undef HAVE_CLOCK_GETTIME */ - -/* Define to 1 to use the syscall interface for clock_gettime */ -/* #undef HAVE_CLOCK_SYSCALL */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_COMMONCRYPTO_COMMONCRYPTO_H */ - -/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you - don't. */ -#define HAVE_DECL_INET_NTOP 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LINUX_TCP_H 1 - -/* Define to 1 if you have the `epoll_ctl' function. */ -/* #undef HAVE_EPOLL_CTL */ - -/* Define to 1 if you have the `eventfd' function. */ -/* #undef HAVE_EVENTFD */ - -/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */ -/* #undef HAVE_EVP_ENCRYPTINIT_EX */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if the floor function is available */ -#define HAVE_FLOOR 1 - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK 1 - -/* Define to 1 if you have the `getpwnam_r' function. */ -#define HAVE_GETPWNAM_R 1 - -/* Define to 1 if you have the `inet_ntop' function. */ -/* #undef HAVE_INET_NTOP */ - -/* Define to 1 if you have the `inotify_init' function. */ -/* #undef HAVE_INOTIFY_INIT */ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Enable IPv6 support in libudns */ -#define HAVE_IPv6 1 - -/* Define to 1 if you have the `kqueue' function. */ -#define HAVE_KQUEUE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LANGINFO_H 1 - -/* Define to 1 if you have the `rt' library (-lrt). */ -/* #undef HAVE_LIBRT */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINUX_IF_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINUX_NETFILTER_IPV4_H */ - -/* Define to 1 if you have the header - file. */ -/* #undef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have the `malloc' function. */ -#define HAVE_MALLOC 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the `nanosleep' function. */ -#define HAVE_NANOSLEEP 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NET_IF_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_ENGINE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_ERR_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_EVP_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_PEM_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_RAND_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_RSA_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_SHA_H */ - -/* Define to 1 if you have the `poll' function. */ -#define HAVE_POLL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_POLL_H 1 - -/* Define to 1 if you have the `port_create' function. */ -/* #undef HAVE_PORT_CREATE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PORT_H */ - -/* Have PTHREAD_PRIO_INHERIT. */ -#define HAVE_PTHREAD_PRIO_INHERIT 1 - -/* Define to 1 if you have the `RAND_pseudo_bytes' function. */ -/* #undef HAVE_RAND_PSEUDO_BYTES */ - -/* Define to 1 if you have the 'select' function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the `setresuid' function. */ -/* #undef HAVE_SETRESUID */ - -/* Define to 1 if you have the `setreuid' function. */ -#define HAVE_SETREUID 1 - -/* Define to 1 if you have the `setrlimit' function. */ -#define HAVE_SETRLIMIT 1 - -/* Define to 1 if you have the `signalfd' function. */ -/* #undef HAVE_SIGNALFD */ - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_EPOLL_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_EVENTFD_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_EVENT_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_INOTIFY_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SIGNALFD_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have that is POSIX.1 compatible. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `vfork' function. */ -#define HAVE_VFORK 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_VFORK_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WINSOCK2_H */ - -/* Define to 1 if `fork' works. */ -#define HAVE_WORKING_FORK 1 - -/* Define to 1 if `vfork' works. */ -#define HAVE_WORKING_VFORK 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WS2TCPIP_H */ - -/* have zlib compression support */ -/* #undef HAVE_ZLIB */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ZLIB_H */ - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#define LT_OBJDIR ".libs/" - -/* Define to 1 if assertions should be disabled. */ -/* #undef NDEBUG */ - -/* Name of package */ -#define PACKAGE "shadowsocks-libev" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "max.c.lv@gmail.com" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "shadowsocks-libev" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "shadowsocks-libev 2.4.8" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "shadowsocks-libev" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "2.4.8" - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -/* #undef PTHREAD_CREATE_JOINABLE */ - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to the type of arg 1 for `select'. */ -#define SELECT_TYPE_ARG1 int - -/* Define to the type of args 2, 3 and 4 for `select'. */ -#define SELECT_TYPE_ARG234 (fd_set *) - -/* Define to the type of arg 5 for `select'. */ -#define SELECT_TYPE_ARG5 (struct timeval *) - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* If the compiler supports a TLS storage class define it to that here */ -#define TLS __thread - -/* Use Apple CommonCrypto library */ -/* #undef USE_CRYPTO_APPLECC */ - -/* Use mbed TLS library */ -#define USE_CRYPTO_MBEDTLS 1 - -/* Use OpenSSL library */ -/* #undef USE_CRYPTO_OPENSSL */ - -/* Use PolarSSL library */ -/* #undef USE_CRYPTO_POLARSSL */ - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif - - -/* Version number of package */ -#define VERSION "2.4.8" - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif -#endif - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define for Solaris 2.5.1 so the uint8_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT8_T */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `int' if does not define. */ -/* #undef pid_t */ - -/* Define to the equivalent of the C99 'restrict' keyword, or to - nothing if this is not supported. Do not define if restrict is - supported directly. */ -#define restrict __restrict -/* Work around a bug in Sun C++: it does not support _Restrict or - __restrict__, even though the corresponding Sun C compiler ends up with - "#define restrict _Restrict" or "#define restrict __restrict__" in the - previous line. Perhaps some future version of Sun C++ will work with - restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ -#if defined __SUNPRO_CC && !defined __RESTRICT -# define _Restrict -# define __restrict__ -#endif - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define to `int' if does not define. */ -/* #undef ssize_t */ - -/* Define to the type of an unsigned integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint16_t */ - -/* Define to the type of an unsigned integer type of width exactly 8 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint8_t */ - -/* Define as `fork' if `vfork' does not work. */ -/* #undef vfork */ - -/* Define to 1 if you have the header file. */ -#define HAVE_PCRE_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PCRE_PCRE_H */ diff --git a/core/src/main/jni/include/sodium/version.h b/core/src/main/jni/include/sodium/version.h deleted file mode 100644 index b95c40b523..0000000000 --- a/core/src/main/jni/include/sodium/version.h +++ /dev/null @@ -1,29 +0,0 @@ - -#ifndef sodium_version_H -#define sodium_version_H - -#include "export.h" - -#define SODIUM_VERSION_STRING "1.0.7" - -#define SODIUM_LIBRARY_VERSION_MAJOR 9 -#define SODIUM_LIBRARY_VERSION_MINOR 0 - -#ifdef __cplusplus -extern "C" { -#endif - -SODIUM_EXPORT -const char *sodium_version_string(void); - -SODIUM_EXPORT -int sodium_library_version_major(void); - -SODIUM_EXPORT -int sodium_library_version_minor(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/src/main/jni/jni-helper.cpp b/core/src/main/jni/jni-helper.cpp deleted file mode 100644 index 60936bbb04..0000000000 --- a/core/src/main/jni/jni-helper.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * * - * Copyright (C) 2019 by Max Lv * - * Copyright (C) 2019 by Mygod Studio * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include - -#include "jni.h" -#include "re2/re2.h" - -using namespace std; - -struct AclMatcher { - stringstream bypassDomainsBuilder, proxyDomainsBuilder; - RE2 *bypassDomains, *proxyDomains; - - ~AclMatcher() { - if (bypassDomains) delete bypassDomains; - if (proxyDomains) delete proxyDomains; - } -}; - -bool addDomain(JNIEnv *env, stringstream &domains, jstring regex) { - const char *regexChars = env->GetStringUTFChars(regex, nullptr); - if (regexChars == nullptr) return false; - if (domains.rdbuf()->in_avail()) domains << '|'; - domains << regexChars; - env->ReleaseStringUTFChars(regex, regexChars); - return true; -} - -const char *buildRE2(stringstream &domains, RE2 *&out, const RE2::Options &options) { - if (domains.rdbuf()->in_avail()) { - out = new RE2(domains.str(), options); - domains.clear(); - if (!out->ok()) return out->error().c_str(); - } else { - delete out; - out = nullptr; - } - return nullptr; -} - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -extern "C" { -JNIEXPORT jlong JNICALL Java_com_github_shadowsocks_acl_AclMatcher_init(JNIEnv *env, jclass clazz) { - return reinterpret_cast(new AclMatcher()); -} - -JNIEXPORT void JNICALL -Java_com_github_shadowsocks_acl_AclMatcher_close(JNIEnv *env, jclass clazz, jlong handle) { - delete reinterpret_cast(handle); -} - -JNIEXPORT jboolean JNICALL -Java_com_github_shadowsocks_acl_AclMatcher_addBypassDomain(JNIEnv *env, jclass clazz, jlong handle, - jstring regex) { - return static_cast(handle && - ::addDomain(env, reinterpret_cast(handle)->bypassDomainsBuilder, regex)); -} - -JNIEXPORT jboolean JNICALL -Java_com_github_shadowsocks_acl_AclMatcher_addProxyDomain(JNIEnv *env, jclass clazz, jlong handle, - jstring regex) { - return static_cast(handle && - ::addDomain(env, reinterpret_cast(handle)->proxyDomainsBuilder, regex)); -} - -JNIEXPORT jstring JNICALL -Java_com_github_shadowsocks_acl_AclMatcher_build(JNIEnv *env, jclass clazz, jlong handle, - jlong memory_limit) { - if (!handle) return env->NewStringUTF("AclMatcher closed"); - auto matcher = reinterpret_cast(handle); - RE2::Options options; - options.set_max_mem(memory_limit); - options.set_never_capture(true); - const char *e = ::buildRE2(matcher->bypassDomainsBuilder, matcher->bypassDomains, options); - if (e) return env->NewStringUTF(e); - e = ::buildRE2(matcher->proxyDomainsBuilder, matcher->proxyDomains, options); - if (e) return env->NewStringUTF(e); - return nullptr; -} - -JNIEXPORT jint JNICALL -Java_com_github_shadowsocks_acl_AclMatcher_matchHost(JNIEnv *env, jclass clazz, jlong handle, - jstring host) { - if (!handle) return -1; - auto matcher = reinterpret_cast(handle); - const char *hostChars = env->GetStringUTFChars(host, nullptr); - jint result = 0; - if (matcher->bypassDomains && RE2::PartialMatch(hostChars, *matcher->bypassDomains)) result = 1; - else if (matcher->proxyDomains && RE2::PartialMatch(hostChars, *matcher->proxyDomains)) result = 2; - env->ReleaseStringUTFChars(host, hostChars); - return result; -} -} diff --git a/core/src/main/jni/libev b/core/src/main/jni/libev deleted file mode 160000 index 31ca40b7a1..0000000000 --- a/core/src/main/jni/libev +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 31ca40b7a18ed424213a4ecba0d57706ed3e56a0 diff --git a/core/src/main/jni/libsodium b/core/src/main/jni/libsodium deleted file mode 160000 index b732443c44..0000000000 --- a/core/src/main/jni/libsodium +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b732443c442239c2e0184820e9b23cca0de0828c diff --git a/core/src/main/jni/mbedtls b/core/src/main/jni/mbedtls deleted file mode 160000 index 9f4f8eec93..0000000000 --- a/core/src/main/jni/mbedtls +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9f4f8eec93dd1f32d78e0bcceddbef0ca570e66f diff --git a/core/src/main/jni/patch/pcre/pcre_chartables.c b/core/src/main/jni/patch/pcre/pcre_chartables.c deleted file mode 100644 index 1e20ec29d0..0000000000 --- a/core/src/main/jni/patch/pcre/pcre_chartables.c +++ /dev/null @@ -1,198 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* This file contains character tables that are used when no external tables -are passed to PCRE by the application that calls it. The tables are used only -for characters whose code values are less than 256. - -This is a default version of the tables that assumes ASCII encoding. A program -called dftables (which is distributed with PCRE) can be used to build -alternative versions of this file. This is necessary if you are running in an -EBCDIC environment, or if you want to default to a different encoding, for -example ISO-8859-1. When dftables is run, it creates these tables in the -current locale. If PCRE is configured with --enable-rebuild-chartables, this -happens automatically. - -The following #includes are present because without them gcc 4.x may remove the -array definition from the final binary if PCRE is built into a static library -and dead code stripping is activated. This leads to link errors. Pulling in the -header ensures that the array gets flagged as "someone outside this compilation -unit might reference this" and so it will always be supplied to the linker. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre_internal.h" - -const pcre_uint8 PRIV(default_tables)[] = { - -/* This table is a lower casing table. */ - - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122, 91, 92, 93, 94, 95, - 96, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122,123,124,125,126,127, - 128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151, - 152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167, - 168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183, - 184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215, - 216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231, - 232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255, - -/* This table is a case flipping table. */ - - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122, 91, 92, 93, 94, 95, - 96, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90,123,124,125,126,127, - 128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151, - 152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167, - 168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183, - 184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215, - 216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231, - 232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247, - 248,249,250,251,252,253,254,255, - -/* This table contains bit maps for various character classes. Each map is 32 -bytes long and the bits run from the least significant end of each byte. The -classes that have their own maps are: space, xdigit, digit, upper, lower, word, -graph, print, punct, and cntrl. Other classes are built from combinations. */ - - 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, - 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, - 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - -/* This table identifies various classes of character by individual bits: - 0x01 white space character - 0x02 letter - 0x04 decimal digit - 0x08 hexadecimal digit - 0x10 alphanumeric or '_' - 0x80 regular expression metacharacter or binary zero -*/ - - 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ - 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ - 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ - 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ - 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ - 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ - 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ - 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ - 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ - 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ - -/* End of pcre_chartables.c */ diff --git a/core/src/main/jni/pcre b/core/src/main/jni/pcre deleted file mode 160000 index 222bbf4b3f..0000000000 --- a/core/src/main/jni/pcre +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 222bbf4b3fb8e13c21686803e47e31aa3e4ad130 diff --git a/core/src/main/jni/re2 b/core/src/main/jni/re2 deleted file mode 160000 index bb8e777557..0000000000 --- a/core/src/main/jni/re2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bb8e777557ddbdeabdedea4f23613c5021ffd7b1 diff --git a/core/src/main/jni/shadowsocks-libev b/core/src/main/jni/shadowsocks-libev deleted file mode 160000 index 6b5025bf74..0000000000 --- a/core/src/main/jni/shadowsocks-libev +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6b5025bf741cff93212ba048353eb3d2c02b5c46 diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 62398ca903..37d0095104 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -1,6 +1,7 @@ + PLAIN RC4-MD5 AES-128-CFB AES-192-CFB @@ -23,6 +24,7 @@ + plain rc4-md5 aes-128-cfb aes-192-cfb @@ -212,4 +214,4 @@ vpn transproxy - \ No newline at end of file + diff --git a/core/src/main/rust/shadowsocks-rust b/core/src/main/rust/shadowsocks-rust new file mode 160000 index 0000000000..246b6c48bc --- /dev/null +++ b/core/src/main/rust/shadowsocks-rust @@ -0,0 +1 @@ +Subproject commit 246b6c48bce6d4a83af046bd3feb4843f772b9d2 diff --git a/detekt.yml b/detekt.yml index 235590d0ca..4874946f52 100644 --- a/detekt.yml +++ b/detekt.yml @@ -1,4 +1,4 @@ -# https://github.com/arturbosch/detekt/blob/1.5.0/detekt-cli/src/main/resources/default-detekt-config.yml +# https://github.com/arturbosch/detekt/blob/1.7.1/detekt-cli/src/main/resources/default-detekt-config.yml comments: active: false @@ -12,6 +12,7 @@ complexity: active: true threshold: 10 includeStaticDeclarations: false + includePrivateDeclarations: false ComplexMethod: active: true threshold: 15 @@ -21,7 +22,7 @@ complexity: nestingFunctions: run,let,apply,with,also,use,forEach,isNotNull,ifNull LabeledExpression: active: false - ignoredLabels: "" + ignoredLabels: '' LargeClass: active: true threshold: 600 @@ -30,8 +31,10 @@ complexity: threshold: 60 LongParameterList: active: true - threshold: 6 + functionThreshold: 6 + constructorThreshold: 7 ignoreDefaultParameters: true + ignoreDataClasses: true MethodOverloading: active: false NestedBlockDepth: @@ -39,14 +42,14 @@ complexity: threshold: 4 StringLiteralDuplication: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' threshold: 3 ignoreAnnotation: true excludeStringsWithLessThan5Characters: true ignoreStringsRegex: '$^' TooManyFunctions: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' thresholdInFiles: 11 thresholdInClasses: 11 thresholdInInterfaces: 11 @@ -67,7 +70,7 @@ empty-blocks: active: true EmptyCatchBlock: active: true - allowedExceptionNameRegex: "^(_|(ignore|expected).*)" + allowedExceptionNameRegex: '^(_|(ignore|expected).*)' EmptyClassBlock: active: true EmptyDefaultConstructor: @@ -91,6 +94,8 @@ empty-blocks: active: true EmptySecondaryConstructor: active: true + EmptyTryBlock: + active: true EmptyWhenBlock: active: true EmptyWhileBlock: @@ -115,7 +120,7 @@ exceptions: SwallowedException: active: true ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException' - allowedExceptionNameRegex: "^(_|(ignore|expected).*)" + allowedExceptionNameRegex: '^(_|(ignore|expected).*)' ThrowingExceptionFromFinally: active: false ThrowingExceptionInMain: @@ -127,7 +132,7 @@ exceptions: active: true TooGenericExceptionCaught: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' exceptionNames: - ArrayIndexOutOfBoundsException - Error @@ -137,7 +142,7 @@ exceptions: - IndexOutOfBoundsException - RuntimeException - Throwable - allowedExceptionNameRegex: "^(_|(ignore|expected).*)" + allowedExceptionNameRegex: '^(_|(ignore|expected).*)' TooGenericExceptionThrown: active: true exceptionNames: @@ -166,6 +171,7 @@ formatting: FinalNewline: active: true autoCorrect: true + insertFinalNewLine: true ImportOrdering: active: false Indentation: @@ -253,37 +259,37 @@ naming: ClassNaming: active: true classPattern: '[A-Z$][a-zA-Z0-9$]*' - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' ConstructorParameterNaming: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' parameterPattern: '[a-z][A-Za-z0-9]*' privateParameterPattern: '[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' ignoreOverridden: true EnumNaming: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*' ForbiddenClassName: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' forbiddenName: '' FunctionMaxLength: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' maximumFunctionNameLength: 30 FunctionMinLength: active: false FunctionNaming: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$' excludeClassPattern: '$^' ignoreOverridden: true FunctionParameterNaming: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' parameterPattern: '[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' ignoreOverridden: true @@ -292,33 +298,34 @@ naming: rootPackage: '' MatchingDeclarationName: active: true + mustBeFirst: true MemberNameEqualsClassName: active: false ObjectPropertyNaming: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' constantPattern: '[A-Za-z][_A-Za-z0-9]*' propertyPattern: '[A-Za-z][_A-Za-z0-9]*' privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' PackageNaming: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$' TopLevelPropertyNaming: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' constantPattern: '[A-Z][_A-Z0-9]*' propertyPattern: '[A-Za-z][_A-Za-z0-9]*' privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' VariableMaxLength: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' maximumVariableNameLength: 64 VariableMinLength: active: false VariableNaming: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' variablePattern: '[a-z][A-Za-z0-9]*' privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' @@ -330,10 +337,10 @@ performance: active: true ForEachOnRange: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' SpreadOperator: active: true - excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + excludes: '**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt' UnnecessaryTemporaryInstantiation: active: true @@ -402,11 +409,11 @@ style: ForbiddenComment: active: true values: 'TODO:,FIXME:,STOPSHIP:' - allowedPatterns: "" + allowedPatterns: '' ForbiddenImport: active: true - imports: '' - forbiddenPatterns: "" + imports: [] + forbiddenPatterns: '' ForbiddenMethodCall: active: true methods: '' @@ -421,7 +428,7 @@ style: active: true ignoreOverridableFunction: true excludedFunctions: 'describeContents' - excludeAnnotatedFunction: "dagger.Provides" + excludeAnnotatedFunction: 'dagger.Provides' LibraryCodeMustSpecifyReturnType: active: true LoopWithTooManyJumpStatements: @@ -477,8 +484,7 @@ style: UnderscoresInNumericLiterals: active: false UnnecessaryAbstractClass: - active: true - excludeAnnotatedClasses: "dagger.Module" + active: false UnnecessaryAnnotationUseSiteTarget: active: true UnnecessaryApply: @@ -497,7 +503,7 @@ style: active: true UnusedPrivateMember: active: true - allowedNames: "(_|ignored|expected|serialVersionUID)" + allowedNames: '(_|ignored|expected|serialVersionUID)' UseArrayLiteralsInAnnotations: active: true UseCheckOrError: diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4e1cc9db6b..6623300beb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew.bat b/gradlew.bat index 24467a141f..9109989e3c 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" diff --git a/mobile/build.gradle b/mobile/build.gradle index 2a33042c93..890d5064ab 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -66,12 +66,12 @@ dependencies { implementation 'androidx.browser:browser:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4' implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion" - implementation 'com.google.android.gms:play-services-vision:19.0.0' - implementation 'com.google.firebase:firebase-ads:18.3.0' + implementation 'com.google.android.gms:play-services-vision:20.0.0' + implementation 'com.google.firebase:firebase-ads:19.1.0' implementation 'com.google.zxing:core:3.4.0' implementation 'com.takisoft.preferencex:preferencex-simplemenu:1.1.0' implementation 'com.twofortyfouram:android-plugin-api-for-locale:1.0.4' - implementation 'me.zhanghai.android.fastscroll:library:1.1.0' + implementation 'me.zhanghai.android.fastscroll:library:1.1.2' implementation 'xyz.belvi.mobilevision:barcodescanner:2.0.3' testImplementation "junit:junit:$junitVersion" androidTestImplementation "androidx.test:runner:$androidTestVersion" diff --git a/mobile/src/main/java/com/github/shadowsocks/AdsManager.kt b/mobile/src/main/java/com/github/shadowsocks/AdsManager.kt new file mode 100644 index 0000000000..4ebb8fa8b8 --- /dev/null +++ b/mobile/src/main/java/com/github/shadowsocks/AdsManager.kt @@ -0,0 +1,41 @@ +/******************************************************************************* + * * + * Copyright (C) 2020 by Max Lv * + * Copyright (C) 2020 by Mygod Studio * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +package com.github.shadowsocks + +import android.content.Context +import com.google.android.gms.ads.AdLoader +import com.google.android.gms.ads.AdRequest +import com.google.android.gms.ads.MobileAds +import com.google.android.gms.ads.RequestConfiguration + +internal object AdsManager { + init { + MobileAds.setRequestConfiguration(RequestConfiguration.Builder().apply { + setTestDeviceIds(listOf( + "B08FC1764A7B250E91EA9D0D5EBEB208", "7509D18EB8AF82F915874FEF53877A64", + "F58907F28184A828DD0DB6F8E38189C6", "FE983F496D7C5C1878AA163D9420CA97")) + }.build()) + } + + fun load(context: Context?, setup: AdLoader.Builder.() -> Unit) = + AdLoader.Builder(context, "ca-app-pub-3283768469187309/8632513739").apply(setup).build() + .loadAd(AdRequest.Builder().build()) +} diff --git a/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt b/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt index 76a9e2e64b..7e8efe9487 100644 --- a/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt +++ b/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt @@ -91,25 +91,17 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() { val portTransproxy = findPreference(Key.portTransproxy)!! portTransproxy.setOnBindEditTextListener(EditTextPreferenceModifiers.Port) val onServiceModeChange = Preference.OnPreferenceChangeListener { _, newValue -> - val (enabledLocalDns, enabledTransproxy) = when (newValue as String?) { - Key.modeProxy -> Pair(false, false) - Key.modeVpn -> Pair(true, false) - Key.modeTransproxy -> Pair(true, true) - else -> throw IllegalArgumentException("newValue: $newValue") - } - hosts.isEnabled = enabledLocalDns - portLocalDns.isEnabled = enabledLocalDns - portTransproxy.isEnabled = enabledTransproxy + portTransproxy.isEnabled = newValue as String? == Key.modeTransproxy true } val listener: (BaseService.State) -> Unit = { val stopped = it == BaseService.State.Stopped tfo.isEnabled = stopped + hosts.isEnabled = stopped serviceMode.isEnabled = stopped portProxy.isEnabled = stopped + portLocalDns.isEnabled = stopped if (stopped) onServiceModeChange.onPreferenceChange(null, DataStore.serviceMode) else { - hosts.isEnabled = false - portLocalDns.isEnabled = false portTransproxy.isEnabled = false } } diff --git a/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt b/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt index 8071e97e77..838e932568 100644 --- a/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt +++ b/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt @@ -177,7 +177,7 @@ class ProfileConfigFragment : PreferenceFragmentCompat(), DataStore.dirty = true true } catch (exc: RuntimeException) { - Snackbar.make(view!!, exc.readableMessage, Snackbar.LENGTH_LONG).show() + Snackbar.make(requireView(), exc.readableMessage, Snackbar.LENGTH_LONG).show() false } @@ -217,7 +217,9 @@ class ProfileConfigFragment : PreferenceFragmentCompat(), plugin.value = pluginConfiguration.selected pluginConfigure.isEnabled = selected !is NoPlugin pluginConfigure.text = pluginConfiguration.getOptions().toString() - if (!selected.trusted) Snackbar.make(view!!, R.string.plugin_untrusted, Snackbar.LENGTH_LONG).show() + if (!selected.trusted) { + Snackbar.make(requireView(), R.string.plugin_untrusted, Snackbar.LENGTH_LONG).show() + } } REQUEST_CODE_PLUGIN_CONFIGURE -> when (resultCode) { Activity.RESULT_OK -> { diff --git a/mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt b/mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt index 26af06fc24..d6a2c00dd9 100644 --- a/mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt +++ b/mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt @@ -59,8 +59,6 @@ import com.github.shadowsocks.utils.readableMessage import com.github.shadowsocks.widget.ListHolderListener import com.github.shadowsocks.widget.MainListListener import com.github.shadowsocks.widget.UndoSnackbarManager -import com.google.android.gms.ads.AdLoader -import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.VideoOptions import com.google.android.gms.ads.formats.NativeAdOptions import com.google.android.gms.ads.formats.UnifiedNativeAd @@ -249,7 +247,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { if (adHost != null || !item.isSponsored) return if (nativeAdView == null) { nativeAdView = layoutInflater.inflate(R.layout.ad_unified, adContainer, false) as UnifiedNativeAdView - AdLoader.Builder(context, "ca-app-pub-3283768469187309/8632513739").apply { + AdsManager.load(context) { forUnifiedNativeAd { unifiedNativeAd -> // You must call destroy on old ads when you are done with them, // otherwise you will have a memory leak. @@ -262,12 +260,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { setStartMuted(true) }.build()) }.build()) - }.build().loadAd(AdRequest.Builder().apply { - addTestDevice("B08FC1764A7B250E91EA9D0D5EBEB208") - addTestDevice("7509D18EB8AF82F915874FEF53877A64") - addTestDevice("F58907F28184A828DD0DB6F8E38189C6") - addTestDevice("FE983F496D7C5C1878AA163D9420CA97") - }.build()) + } } else if (nativeAd != null) populateUnifiedNativeAdView(nativeAd!!, nativeAdView!!) } diff --git a/mobile/src/main/java/com/github/shadowsocks/subscription/SubscriptionFragment.kt b/mobile/src/main/java/com/github/shadowsocks/subscription/SubscriptionFragment.kt index 786ed0585a..72171b241b 100644 --- a/mobile/src/main/java/com/github/shadowsocks/subscription/SubscriptionFragment.kt +++ b/mobile/src/main/java/com/github/shadowsocks/subscription/SubscriptionFragment.kt @@ -220,7 +220,7 @@ class SubscriptionFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener toolbar.setTitle(R.string.subscriptions) toolbar.inflateMenu(R.menu.subscription_menu) toolbar.setOnMenuItemClickListener(this) - SubscriptionService.idle.observe(this) { + SubscriptionService.idle.observe(viewLifecycleOwner) { toolbar.menu.findItem(R.id.action_update_subscription).isEnabled = it } val activity = activity as MainActivity diff --git a/mobile/src/main/res/raw/about.html b/mobile/src/main/res/raw/about.html index f67992340e..2bd462d24b 100644 --- a/mobile/src/main/res/raw/about.html +++ b/mobile/src/main/res/raw/about.html @@ -20,14 +20,11 @@

Open Source Licenses

diff --git a/plugin/build.gradle b/plugin/build.gradle index 458c1d27bb..b1aae874ff 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -47,7 +47,7 @@ mavenPublish { dependencies { api 'androidx.core:core-ktx:1.2.0' - api 'androidx.drawerlayout:drawerlayout:1.1.0-alpha03' // https://android-developers.googleblog.com/2019/07/android-q-beta-5-update.html + api 'androidx.drawerlayout:drawerlayout:1.1.0-beta01' // https://android-developers.googleblog.com/2019/07/android-q-beta-5-update.html api 'com.google.android.material:material:1.1.0' api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" testImplementation "junit:junit:$junitVersion" diff --git a/plugin/src/main/java/com/github/shadowsocks/plugin/AlertDialogFragment.kt b/plugin/src/main/java/com/github/shadowsocks/plugin/AlertDialogFragment.kt index fcf7a55807..67571adae2 100644 --- a/plugin/src/main/java/com/github/shadowsocks/plugin/AlertDialogFragment.kt +++ b/plugin/src/main/java/com/github/shadowsocks/plugin/AlertDialogFragment.kt @@ -41,7 +41,7 @@ abstract class AlertDialogFragment : } protected abstract fun AlertDialog.Builder.prepare(listener: DialogInterface.OnClickListener) - protected val arg by lazy { arguments!!.getParcelable(KEY_ARG)!! } + protected val arg by lazy { requireArguments().getParcelable(KEY_ARG)!! } protected open fun ret(which: Int): Ret? = null fun withArg(arg: Arg) = apply { arguments = Bundle().apply { putParcelable(KEY_ARG, arg) } } diff --git a/tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt b/tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt index d2b990aad3..ab5e5a1be2 100644 --- a/tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt +++ b/tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt @@ -76,15 +76,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragmentCompat(), ShadowsocksCo private lateinit var portLocalDns: EditTextPreference private lateinit var portTransproxy: EditTextPreference private val onServiceModeChange = Preference.OnPreferenceChangeListener { _, newValue -> - val (enabledLocalDns, enabledTransproxy) = when (newValue as String?) { - Key.modeProxy -> Pair(false, false) - Key.modeVpn -> Pair(true, false) - Key.modeTransproxy -> Pair(true, true) - else -> throw IllegalArgumentException("newValue: $newValue") - } - hosts.isEnabled = enabledLocalDns - portLocalDns.isEnabled = enabledLocalDns - portTransproxy.isEnabled = enabledTransproxy + portTransproxy.isEnabled = newValue as String? == Key.modeTransproxy true } private val tester by viewModels() @@ -125,11 +117,12 @@ class MainPreferenceFragment : LeanbackPreferenceFragmentCompat(), ShadowsocksCo val stopped = state == BaseService.State.Stopped controlImport.isEnabled = stopped tfo.isEnabled = stopped + hosts.isEnabled = stopped serviceMode.isEnabled = stopped shareOverLan.isEnabled = stopped portProxy.isEnabled = stopped + portLocalDns.isEnabled = stopped if (stopped) onServiceModeChange.onPreferenceChange(null, DataStore.serviceMode) else { - portLocalDns.isEnabled = false portTransproxy.isEnabled = false } }