From 90af5811d7e7ae7df2670d79af4bb9cb57716a2f Mon Sep 17 00:00:00 2001 From: Mygod Date: Mon, 4 Jan 2021 00:42:00 -0500 Subject: [PATCH] Revert "Switch to local UDP DNS resolver (#2635)" This reverts commit 700f4d264c9e0117d95072b89a592d6c550a368b. --- .circleci/config.yml | 5 +- README.md | 5 +- .../com/github/shadowsocks/bg/BaseService.kt | 2 +- .../github/shadowsocks/bg/LocalDnsWorker.kt | 74 ++++++++++--------- .../github/shadowsocks/bg/ProxyInstance.kt | 2 +- .../net/ConcurrentUdpSocketListener.kt | 36 --------- .../shadowsocks/net/UdpSocketListener.kt | 72 ------------------ core/src/main/res/values/arrays.xml | 2 + core/src/main/rust/shadowsocks-rust | 2 +- 9 files changed, 50 insertions(+), 150 deletions(-) delete mode 100644 core/src/main/java/com/github/shadowsocks/net/ConcurrentUdpSocketListener.kt delete mode 100644 core/src/main/java/com/github/shadowsocks/net/UdpSocketListener.kt diff --git a/.circleci/config.yml b/.circleci/config.yml index b274fdb624..6d5e40256f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,10 +7,11 @@ jobs: environment: GRADLE_OPTS: -Dorg.gradle.workers.max=1 -Dorg.gradle.daemon=false -Dkotlin.compiler.execution.strategy="in-process" steps: + - run: rustup toolchain install nightly-2020-12-20 + - run: rustup override set nightly-2020-12-20 + - run: rustup target install armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android - checkout - run: git submodule update --init --recursive - - run: rustup update - - run: cd core/src/main/rust/shadowsocks-rust && rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android - restore_cache: key: jars-{{ checksum "build.gradle.kts" }} - run: diff --git a/README.md b/README.md index a3ea7e628b..12e51f795a 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,9 @@ for Android TV ([beta](https://play.google.com/apps/testing/com.github.shadowsoc * Rust with Android targets installed ```bash - $ cd core/src/main/rust/shadowsocks-rust - $ rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android + $ rustup toolchain install nightly-2020-12-20 + $ rustup override set nightly-2020-12-20 + $ rustup target install armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android ``` ### BUILD 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 3fb103489d..422d8f424f 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/BaseService.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/BaseService.kt @@ -253,7 +253,7 @@ object BaseService { File(Core.deviceStorage.noBackupFilesDir, "stat_udp"), File(configRoot, CONFIG_FILE_UDP), "-u", false) - data.localDns = LocalDnsWorker(this::rawResolver, DataStore.portLocalDns + 1).apply { start() } + data.localDns = LocalDnsWorker(this::rawResolver).apply { start() } } fun startRunner() { diff --git a/core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt b/core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt index 89dc09afab..1c2b87719d 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt @@ -1,6 +1,8 @@ package com.github.shadowsocks.bg -import com.github.shadowsocks.net.ConcurrentUdpSocketListener +import android.net.LocalSocket +import com.github.shadowsocks.Core +import com.github.shadowsocks.net.ConcurrentLocalSocketListener import com.github.shadowsocks.net.DnsResolverCompat import com.github.shadowsocks.utils.readableMessage import kotlinx.coroutines.CancellationException @@ -10,45 +12,47 @@ import kotlinx.coroutines.launch import org.xbill.DNS.Message import org.xbill.DNS.Rcode import timber.log.Timber +import java.io.DataInputStream +import java.io.DataOutputStream +import java.io.File import java.io.IOException -import java.net.SocketAddress -import java.nio.ByteBuffer -import java.nio.channels.DatagramChannel -class LocalDnsWorker(private val resolver: suspend (ByteArray) -> ByteArray, port: Int) : ConcurrentUdpSocketListener( - "LocalDnsThread", port), CoroutineScope { - - override fun handle(channel: DatagramChannel, sender: SocketAddress, query: ByteBuffer) { +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 { - query.flip() - val data = ByteArray(query.remaining()) - query.get(data) - try { - resolver(data) - } catch (e: Exception) { - when (e) { - is TimeoutCancellationException -> Timber.w("Resolving timed out") - is CancellationException -> { - } // ignore - is IOException -> Timber.d(e) - else -> Timber.w(e) - } - try { - DnsResolverCompat.prepareDnsResponse(Message(data)).apply { - header.rcode = Rcode.SERVFAIL - }.toWire() - } catch (_: IOException) { - byteArrayOf() // return empty if cannot parse packet + socket.use { + val input = DataInputStream(socket.inputStream) + val query = try { + ByteArray(input.readUnsignedShort()).also { input.read(it) } + } catch (e: IOException) { // connection early close possibly due to resolving timeout + return@use Timber.d(e) } - }?.let { r -> try { - val response = ByteBuffer.allocate(1024) - response.clear() - response.put(r) - response.flip() - channel.send(response, sender) - } catch (e: IOException) { - Timber.d(e.readableMessage) + resolver(query) + } catch (e: Exception) { + when (e) { + is TimeoutCancellationException -> Timber.w("Resolving timed out") + is CancellationException -> { } // ignore + is IOException -> Timber.d(e) + else -> Timber.w(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 (e: IOException) { + Timber.d(e.readableMessage) + } } } } 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 6038e466fe..3b936f2914 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt @@ -91,7 +91,7 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro }.let { dns -> cmd += arrayListOf( "--dns-addr", "${DataStore.listenAddress}:${DataStore.portLocalDns}", - "--local-dns-addr", "127.0.0.1:${DataStore.portLocalDns + 1}", + "--local-dns-addr", "local_dns_path", "--remote-dns-addr", "${dns.host ?: "0.0.0.0"}:${if (dns.port < 0) 53 else dns.port}") } diff --git a/core/src/main/java/com/github/shadowsocks/net/ConcurrentUdpSocketListener.kt b/core/src/main/java/com/github/shadowsocks/net/ConcurrentUdpSocketListener.kt deleted file mode 100644 index 2daf919a18..0000000000 --- a/core/src/main/java/com/github/shadowsocks/net/ConcurrentUdpSocketListener.kt +++ /dev/null @@ -1,36 +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 kotlinx.coroutines.* -import timber.log.Timber - -abstract class ConcurrentUdpSocketListener(name: String, port: Int) : UdpSocketListener(name, port), - CoroutineScope { - override val coroutineContext = Dispatchers.IO + SupervisorJob() + CoroutineExceptionHandler { _, t -> Timber.w(t) } - - override fun shutdown(scope: CoroutineScope) { - running = false - cancel() - super.shutdown(scope) - coroutineContext[Job]!!.also { job -> scope.launch { job.join() } } - } -} diff --git a/core/src/main/java/com/github/shadowsocks/net/UdpSocketListener.kt b/core/src/main/java/com/github/shadowsocks/net/UdpSocketListener.kt deleted file mode 100644 index 21ffb45937..0000000000 --- a/core/src/main/java/com/github/shadowsocks/net/UdpSocketListener.kt +++ /dev/null @@ -1,72 +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.net - -import android.annotation.SuppressLint -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.sendBlocking -import kotlinx.coroutines.launch -import timber.log.Timber -import java.io.IOException -import java.net.InetSocketAddress -import java.net.SocketAddress -import java.nio.ByteBuffer -import java.nio.channels.DatagramChannel - -abstract class UdpSocketListener(name: String, val port: Int) : Thread(name) { - - private val udpChannel = DatagramChannel.open() - private val closeChannel = Channel(1) - - @Volatile - protected var running = true - - /** - * Inherited class do not need to close input/output streams as they will be closed automatically. - */ - protected abstract fun handle(channel: DatagramChannel, sender: SocketAddress, query: ByteBuffer) - - final override fun run() { - udpChannel.socket().bind(InetSocketAddress(port)) - udpChannel.configureBlocking(true) - udpChannel.use { - while (running) { - try { - val query = ByteBuffer.allocate(1024) - query.clear() - udpChannel.receive(query)?.let { handle(udpChannel, it, query) } - } catch (e: IOException) { - if (running) Timber.w(e) - continue - } - } - } - closeChannel.sendBlocking(Unit) - } - - @SuppressLint("NewApi") - open fun shutdown(scope: CoroutineScope) { - running = false - udpChannel.close() - scope.launch { closeChannel.receive() } - } -} diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index f50e97843c..5aa114c6e7 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -16,6 +16,7 @@ AES-128-GCM AES-256-GCM CHACHA20-IETF-POLY1305 + XCHACHA20-IETF-POLY1305 @@ -34,6 +35,7 @@ aes-128-gcm aes-256-gcm chacha20-ietf-poly1305 + xchacha20-ietf-poly1305 diff --git a/core/src/main/rust/shadowsocks-rust b/core/src/main/rust/shadowsocks-rust index e048bc2f34..3a1054acc5 160000 --- a/core/src/main/rust/shadowsocks-rust +++ b/core/src/main/rust/shadowsocks-rust @@ -1 +1 @@ -Subproject commit e048bc2f343bbed36ed6dea0151d34ceecfce8ca +Subproject commit 3a1054acc54cfc23a1cd232aa0a45b66af4bd612