diff --git a/README.md b/README.md
index 72f1b1fa9..ddfe32c7b 100644
--- a/README.md
+++ b/README.md
@@ -83,8 +83,6 @@ GPLv3
kotlin: APL 2.0
material: APL 2.0
gson: APL 2.0
- dnsjava: BSD
- jsocks: LGPL 2.1
preferencex-simplemenu: APL 2.0
android-plugin-api-for-locale: APL 2.0
qrgen: APL 2.0
diff --git a/core/build.gradle b/core/build.gradle
index d96630615..14b98c8a4 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -78,9 +78,7 @@ dependencies {
api "androidx.work:work-runtime-ktx:2.7.1"
api "androidx.work:work-multiprocess:2.7.1"
api 'com.google.code.gson:gson:2.9.0'
- api 'dnsjava:dnsjava:3.5.0'
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1"
- implementation 'com.github.ssrlive:jsocks:v1.0.1'
implementation 'androidx.core:core-ktx:1.7.0'
kapt "androidx.room:room-compiler:2.4.2"
}
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 d3c4e077b..000000000
--- a/core/src/main/java/com/github/shadowsocks/bg/LocalDnsService.kt
+++ /dev/null
@@ -1,66 +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.WeakHashMap
-
-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/SsrVpnService.kt b/core/src/main/java/com/github/shadowsocks/bg/SsrVpnService.kt
index 709cfa30f..8dbbd5ab7 100644
--- a/core/src/main/java/com/github/shadowsocks/bg/SsrVpnService.kt
+++ b/core/src/main/java/com/github/shadowsocks/bg/SsrVpnService.kt
@@ -48,13 +48,15 @@ import java.io.File
import java.io.FileDescriptor
import java.io.IOException
-class SsrVpnService : VpnService(), LocalDnsService.Interface {
+class SsrVpnService : VpnService(), BaseService.Interface {
companion object {
private const val VPN_MTU = 1500
- private const val PRIVATE_VLAN4_CLIENT = "172.19.0.1"
- private const val PRIVATE_VLAN4_ROUTER = "172.19.0.2"
+ private const val PRIVATE_VLAN4_CLIENT = "172.19.0.2"
+ private const val PRIVATE_VLAN4_ROUTER = "172.19.0.1"
+ private const val PRIVATE_VLAN4_PREFIX_LENGTH = 30
private const val PRIVATE_VLAN6_CLIENT = "fdfe:dcba:9876::1"
private const val PRIVATE_VLAN6_ROUTER = "fdfe:dcba:9876::2"
+ private const val PRIVATE_VLAN6_PREFIX_LENGTH = 126
}
inner class NullConnectionException : NullPointerException(), BaseService.ExpectedException {
@@ -84,7 +86,7 @@ class SsrVpnService : VpnService(), 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()
@@ -105,7 +107,9 @@ class SsrVpnService : VpnService(), 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
@@ -126,10 +130,10 @@ class SsrVpnService : VpnService(), LocalDnsService.Interface {
.setConfigureIntent(Core.configureIntent(this))
.setSession(profile.formattedName)
.setMtu(VPN_MTU)
- .addAddress(PRIVATE_VLAN4_CLIENT, 30)
+ .addAddress(PRIVATE_VLAN4_CLIENT, PRIVATE_VLAN4_PREFIX_LENGTH)
.addDnsServer(PRIVATE_VLAN4_ROUTER)
- if (profile.ipv6) builder.addAddress(PRIVATE_VLAN6_CLIENT, 126)
+ if (profile.ipv6) builder.addAddress(PRIVATE_VLAN6_CLIENT, PRIVATE_VLAN6_PREFIX_LENGTH)
if (profile.proxyApps) {
val me = packageName
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 9bfc5aa2d..000000000
--- 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 f30b98a4d..000000000
--- 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/preference/DataStore.kt b/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt
index 13e9bbc61..e1861ef11 100644
--- a/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt
+++ b/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt
@@ -72,9 +72,6 @@ object DataStore : OnPreferenceDataStoreChangeListener {
get() = getLocalPort(Key.portProxy, 1080)
set(value) = publicStore.putString(Key.portProxy, value.toString())
val proxyAddress get() = InetSocketAddress("127.0.0.1", portProxy)
- var portLocalDns: Int
- get() = getLocalPort(Key.portLocalDns, 5450)
- set(value) = publicStore.putString(Key.portLocalDns, value.toString())
var portTransproxy: Int
get() = getLocalPort(Key.portTransproxy, 8200)
set(value) = publicStore.putString(Key.portTransproxy, value.toString())
@@ -96,7 +93,6 @@ object DataStore : OnPreferenceDataStoreChangeListener {
persistAcrossReboot
if (publicStore.getBoolean(Key.tfo) == null) publicStore.putBoolean(Key.tfo, tcpFastOpen)
if (publicStore.getString(Key.portProxy) == null) portProxy = portProxy
- if (publicStore.getString(Key.portLocalDns) == null) portLocalDns = portLocalDns
if (publicStore.getString(Key.portTransproxy) == null) portTransproxy = portTransproxy
}
diff --git a/core/src/main/java/com/github/shadowsocks/utils/Constants.kt b/core/src/main/java/com/github/shadowsocks/utils/Constants.kt
index 04e5d42d3..a8093b2b9 100644
--- a/core/src/main/java/com/github/shadowsocks/utils/Constants.kt
+++ b/core/src/main/java/com/github/shadowsocks/utils/Constants.kt
@@ -40,7 +40,6 @@ object Key {
const val modeVpn = "vpn"
const val shareOverLan = "shareOverLan"
const val portProxy = "portProxy"
- const val portLocalDns = "portLocalDns"
const val portTransproxy = "portTransproxy"
const val route = "route"
diff --git a/core/src/main/res/values-es/strings.xml b/core/src/main/res/values-es/strings.xml
index 8f72ea795..255d67e03 100644
--- a/core/src/main/res/values-es/strings.xml
+++ b/core/src/main/res/values-es/strings.xml
@@ -145,7 +145,6 @@ Recibido: \t%4$s\t↓\t%2$s"
"Sólo Proxy"
"VPN"
"Puerto proxy SOCKS5"
- "Puerto DNS local"
"Servicio Proxy"
"Servicio Transproxy"
"Permiso denegado al crear servicio VPN"
diff --git a/core/src/main/res/values-fa/strings.xml b/core/src/main/res/values-fa/strings.xml
index 183e1d6e8..2cc8c1621 100644
--- a/core/src/main/res/values-fa/strings.xml
+++ b/core/src/main/res/values-fa/strings.xml
@@ -139,7 +139,6 @@
"ویپیان"
"ترانسپروکسی"
"پورت پروکسی SOCKS5"
- "پورت دیاناس محلی"
"پورت ترانسپروکسی"
"سرویس پروکسی"
"سرویس ترانسپروکسی"
diff --git a/core/src/main/res/values-fr/strings.xml b/core/src/main/res/values-fr/strings.xml
index dd400de07..dbc38ac32 100644
--- a/core/src/main/res/values-fr/strings.xml
+++ b/core/src/main/res/values-fr/strings.xml
@@ -151,7 +151,6 @@ Reçu : \t\t\t%4$s\t↓\t%2$s"
"Mode Service"
"Proxy seul"
"Port proxy SOCKS5"
- "Port DNS local"
"Port Transproxy"
"Service Proxy"
"Service Transproxy"
diff --git a/core/src/main/res/values-ja/strings.xml b/core/src/main/res/values-ja/strings.xml
index 5bd153c1b..f8e916b51 100644
--- a/core/src/main/res/values-ja/strings.xml
+++ b/core/src/main/res/values-ja/strings.xml
@@ -163,7 +163,6 @@
"プロキシのみ"
"トランスプロキシ"
"SOCKS5プロキシポート"
- "ローカルDNSポート"
"トランスプロキシポート"
"プロキシサービス"
"トランスプロキシサービス"
diff --git a/core/src/main/res/values-ru/strings.xml b/core/src/main/res/values-ru/strings.xml
index ecaa964a5..6e06a289c 100644
--- a/core/src/main/res/values-ru/strings.xml
+++ b/core/src/main/res/values-ru/strings.xml
@@ -156,7 +156,6 @@
"Только прокси"
"Прозрачный прокси"
"Порт SOCKS5 прокси"
- "Локальный порт DNS"
"Порт прозрачного прокси"
"Служба прокси"
"Служба прозрачный прокси"
diff --git a/core/src/main/res/values-tr/strings.xml b/core/src/main/res/values-tr/strings.xml
index 0b5c6e336..cd5fcd5cd 100644
--- a/core/src/main/res/values-tr/strings.xml
+++ b/core/src/main/res/values-tr/strings.xml
@@ -155,7 +155,6 @@
"Servis modu"
"Sadece proxy"
"SOCKS5 proxy portu"
- "Yerel DNS portu"
"Transproxy portu"
"Proxy Servisi"
"Transproxy Servisi"
diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml
index 956966560..4619b4b00 100644
--- a/core/src/main/res/values-zh-rCN/strings.xml
+++ b/core/src/main/res/values-zh-rCN/strings.xml
@@ -12,7 +12,6 @@
"透明代理"
"通过局域网分享"
"SOCKS5 代理端口"
- "本地 DNS 端口"
"透明代理端口"
"远程 DNS"
diff --git a/core/src/main/res/values-zh-rTW/strings.xml b/core/src/main/res/values-zh-rTW/strings.xml
index 14a86eaf4..f624cf383 100644
--- a/core/src/main/res/values-zh-rTW/strings.xml
+++ b/core/src/main/res/values-zh-rTW/strings.xml
@@ -162,7 +162,6 @@
"仅代理"
"透明代理"
"SOCKS5 代理連接埠"
- "本地 DNS 連接埠"
"透明代理連接埠"
"代理服務"
"透明代理服務"
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index c37a5ca47..2b2915074 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -12,7 +12,6 @@
Transproxy
Share over LAN
SOCKS5 proxy port
- Local DNS port
Transproxy port
Remote DNS
diff --git a/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt b/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
index 4e4bb1604..41f439743 100644
--- a/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
+++ b/mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
@@ -86,8 +86,6 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
val shareOverLan = findPreference(Key.shareOverLan)!!
val portProxy = findPreference(Key.portProxy)!!
portProxy.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
- val portLocalDns = findPreference(Key.portLocalDns)!!
- portLocalDns.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
val portTransproxy = findPreference(Key.portTransproxy)!!
portTransproxy.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
val onServiceModeChange = Preference.OnPreferenceChangeListener { _, newValue ->
@@ -97,7 +95,6 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
else -> throw IllegalArgumentException("newValue: $newValue")
}
hosts.isEnabled = enabledLocalDns
- portLocalDns.isEnabled = enabledLocalDns
portTransproxy.isEnabled = enabledTransproxy
true
}
@@ -110,7 +107,6 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
// FIXME: *serviceMode* is something I wrote at will, please double-check it.
if (stopped) onServiceModeChange.onPreferenceChange(serviceMode, DataStore.serviceMode) else {
hosts.isEnabled = false
- portLocalDns.isEnabled = false
portTransproxy.isEnabled = false
}
}
diff --git a/mobile/src/main/res/raw/about.html b/mobile/src/main/res/raw/about.html
index e62e352aa..6d5d988f0 100644
--- a/mobile/src/main/res/raw/about.html
+++ b/mobile/src/main/res/raw/about.html
@@ -31,8 +31,6 @@ Open Source Licenses
kotlin: APL 2.0
material: APL 2.0
gson: APL 2.0
- dnsjava: BSD
- jsocks: LGPL 2.1
preferencex-simplemenu: APL 2.0
android-plugin-api-for-locale: APL 2.0
qrgen: APL 2.0
diff --git a/mobile/src/main/res/xml/pref_global.xml b/mobile/src/main/res/xml/pref_global.xml
index 13a5a3406..628dafde0 100644
--- a/mobile/src/main/res/xml/pref_global.xml
+++ b/mobile/src/main/res/xml/pref_global.xml
@@ -43,11 +43,6 @@
app:key="portProxy"
app:title="@string/port_proxy"
app:useSimpleSummaryProvider="true" />
-
val (enabledLocalDns, enabledTransproxy) = when (newValue as String?) {
@@ -81,7 +80,6 @@ class MainPreferenceFragment : LeanbackPreferenceFragmentCompat(), ShadowsocksCo
else -> throw IllegalArgumentException("newValue: $newValue")
}
hosts.isEnabled = enabledLocalDns
- portLocalDns.isEnabled = enabledLocalDns
portTransproxy.isEnabled = enabledTransproxy
true
}
@@ -127,7 +125,6 @@ class MainPreferenceFragment : LeanbackPreferenceFragmentCompat(), ShadowsocksCo
shareOverLan.isEnabled = stopped
portProxy.isEnabled = stopped
if (stopped) onServiceModeChange.onPreferenceChange(null, DataStore.serviceMode) else {
- portLocalDns.isEnabled = false
portTransproxy.isEnabled = false
}
}
@@ -181,8 +178,6 @@ class MainPreferenceFragment : LeanbackPreferenceFragmentCompat(), ShadowsocksCo
shareOverLan = findPreference(Key.shareOverLan)!!
portProxy = findPreference(Key.portProxy)!!
portProxy.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
- portLocalDns = findPreference(Key.portLocalDns)!!
- portLocalDns.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
portTransproxy = findPreference(Key.portTransproxy)!!
portTransproxy.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
serviceMode.onPreferenceChangeListener = onServiceModeChange
diff --git a/tv/src/main/res/xml/pref_main.xml b/tv/src/main/res/xml/pref_main.xml
index c5552df06..b0df22f96 100644
--- a/tv/src/main/res/xml/pref_main.xml
+++ b/tv/src/main/res/xml/pref_main.xml
@@ -47,10 +47,6 @@
app:key="portProxy"
app:title="@string/port_proxy"
app:useSimpleSummaryProvider="true"/>
-