Skip to content

Commit

Permalink
Deprecate hosts (#2502)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mygod authored Apr 21, 2020
1 parent 198434e commit 141a307
Show file tree
Hide file tree
Showing 14 changed files with 19 additions and 284 deletions.
12 changes: 4 additions & 8 deletions core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ 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.Action
import com.github.shadowsocks.utils.Key
import com.github.shadowsocks.utils.broadcastReceiver
import com.github.shadowsocks.utils.readableMessage
import com.google.firebase.analytics.FirebaseAnalytics
Expand Down Expand Up @@ -239,7 +237,7 @@ object BaseService {

val isVpnService get() = false

suspend fun startProcesses(hosts: HostsFile) {
suspend fun startProcesses() {
val configRoot = (if (Build.VERSION.SDK_INT < 24 || app.getSystemService<UserManager>()
?.isUserUnlocked != false) app else Core.deviceStorage).noBackupFilesDir
val udpFallback = data.udpFallback
Expand Down Expand Up @@ -315,7 +313,6 @@ object BaseService {
listOfNotNull(data.proxy, data.udpFallback).forEach { it.trafficMonitor?.persistStats(it.profile.id) }

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()
Expand Down Expand Up @@ -355,9 +352,8 @@ object BaseService {
try {
Executable.killAll() // clean up old processes
preInit()
val hosts = HostsFile(DataStore.publicStore.getString(Key.hosts) ?: "")
proxy.init(this@Interface, hosts)
data.udpFallback?.init(this@Interface, hosts)
proxy.init(this@Interface)
data.udpFallback?.init(this@Interface)
if (profile.route == Acl.CUSTOM_RULES) try {
withContext(Dispatchers.IO) {
Acl.customRules.flatten(10, this@Interface::openConnection).also {
Expand All @@ -372,7 +368,7 @@ object BaseService {
Timber.w(it)
stopRunner(false, it.readableMessage)
}
startProcesses(hosts)
startProcesses()

proxy.scheduleUpdate()
data.udpFallback?.scheduleUpdate()
Expand Down
25 changes: 5 additions & 20 deletions core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ 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
import com.github.shadowsocks.preference.DataStore
Expand All @@ -52,7 +50,7 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
val plugin by lazy { PluginManager.init(PluginConfiguration(profile.plugin ?: "")) }
private var scheduleConfigUpdate = false

suspend fun init(service: BaseService.Interface, hosts: HostsFile) {
suspend fun init(service: BaseService.Interface) {
if (profile.isSponsored) {
scheduleConfigUpdate = true
val mdg = MessageDigest.getInstance("SHA-1")
Expand Down Expand Up @@ -86,23 +84,10 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro

// it's hard to resolve DNS on a specific interface so we'll do it here
if (profile.host.parseNumericAddress() == null) {
profile.host = hosts.resolve(profile.host).run {
if (isEmpty()) try {
service.resolver(profile.host).firstOrNull()
} catch (_: IOException) {
null
} else {
val network = service.getActiveNetwork() ?: throw UnknownHostException()
val hasIpv4 = DnsResolverCompat.haveIpv4(network)
val hasIpv6 = DnsResolverCompat.haveIpv6(network)
firstOrNull {
when (it) {
is Inet4Address -> hasIpv4
is Inet6Address -> hasIpv6
else -> error(it)
}
}
}
profile.host = try {
service.resolver(profile.host).firstOrNull()
} catch (_: IOException) {
null
}?.hostAddress ?: throw UnknownHostException()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ package com.github.shadowsocks.bg
import android.app.Service
import android.content.Intent
import com.github.shadowsocks.Core
import com.github.shadowsocks.net.HostsFile
import com.github.shadowsocks.preference.DataStore
import java.io.File

Expand Down Expand Up @@ -57,9 +56,9 @@ redsocks {
File(applicationInfo.nativeLibraryDir, Executable.REDSOCKS).absolutePath, "-c", "redsocks.conf"))
}

override suspend fun startProcesses(hosts: HostsFile) {
override suspend fun startProcesses() {
startRedsocksDaemon()
super.startProcesses(hosts)
super.startProcesses()
}

override fun onDestroy() {
Expand Down
10 changes: 6 additions & 4 deletions core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ 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.*
import com.github.shadowsocks.net.ConcurrentLocalSocketListener
import com.github.shadowsocks.net.DefaultNetworkListener
import com.github.shadowsocks.net.DnsResolverCompat
import com.github.shadowsocks.net.Subnet
import com.github.shadowsocks.preference.DataStore
import com.github.shadowsocks.utils.Key
import com.github.shadowsocks.utils.closeQuietly
Expand Down Expand Up @@ -137,17 +140,16 @@ class VpnService : BaseVpnService(), BaseService.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) {
override suspend fun startProcesses() {
worker = ProtectWorker().apply { start() }
super.startProcesses(hosts)
super.startProcesses()
sendFd(startVpn())
}

Expand Down
40 changes: 0 additions & 40 deletions core/src/main/java/com/github/shadowsocks/net/DnsResolverCompat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,10 @@ import android.os.CancellationSignal
import android.os.Looper
import android.system.ErrnoException
import android.system.Os
import android.system.OsConstants
import com.github.shadowsocks.Core
import com.github.shadowsocks.utils.closeQuietly
import com.github.shadowsocks.utils.int
import com.github.shadowsocks.utils.parseNumericAddress
import kotlinx.coroutines.*
import org.xbill.DNS.*
import timber.log.Timber
import java.io.FileDescriptor
import java.io.IOException
import java.net.Inet4Address
Expand All @@ -58,42 +54,6 @@ sealed class DnsResolverCompat {
}
}

/**
* Based on: https://android.googlesource.com/platform/frameworks/base/+/9f97f97/core/java/android/net/util/DnsUtils.java#341
*/
private val address4 = "8.8.8.8".parseNumericAddress()!!
private val address6 = "2000::".parseNumericAddress()!!
suspend fun haveIpv4(network: Network) = checkConnectivity(network, OsConstants.AF_INET, address4)
suspend fun haveIpv6(network: Network) = checkConnectivity(network, OsConstants.AF_INET6, address6)
private suspend fun checkConnectivity(network: Network, domain: Int, addr: InetAddress) = try {
val socket = Os.socket(domain, OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP)
try {
instance.bindSocket(network, socket)
instance.connectUdp(socket, addr)
} finally {
socket.closeQuietly()
}
true
} catch (e: IOException) {
if ((e.cause as? ErrnoException)?.errno == OsConstants.EPERM) checkConnectivity(network, addr) else false
} catch (_: ErrnoException) {
false
} catch (e: ReflectiveOperationException) {
check(Build.VERSION.SDK_INT < 23)
Timber.w(e)
checkConnectivity(network, addr)
}
private fun checkConnectivity(network: Network, addr: InetAddress): Boolean {
return Core.connectivity.getLinkProperties(network)?.routes?.any {
try {
it.matches(addr)
} catch (e: RuntimeException) {
Timber.w(e)
false
}
} == true
}

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)
Expand Down
38 changes: 0 additions & 38 deletions core/src/main/java/com/github/shadowsocks/net/HostsFile.kt

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ object Key {

const val dirty = "profileDirty"

const val hosts = "hosts"
const val assetUpdateTime = "assetUpdateTime"

// TV specific values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

package com.github.shadowsocks

import android.app.Activity
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.View
Expand All @@ -30,24 +28,14 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import com.github.shadowsocks.bg.BaseService
import com.github.shadowsocks.plugin.showAllowingStateLoss
import com.github.shadowsocks.preference.BrowsableEditTextPreferenceDialogFragment
import com.github.shadowsocks.preference.DataStore
import com.github.shadowsocks.preference.EditTextPreferenceModifiers
import com.github.shadowsocks.preference.HostsSummaryProvider
import com.github.shadowsocks.utils.DirectBoot
import com.github.shadowsocks.utils.Key
import com.github.shadowsocks.utils.readableMessage
import com.github.shadowsocks.utils.remove
import com.github.shadowsocks.widget.MainListListener

class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
companion object {
private const val REQUEST_BROWSE = 1
}

private val hosts by lazy { findPreference<EditTextPreference>(Key.hosts)!! }

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
preferenceManager.preferenceDataStore = DataStore.publicStore
DataStore.initGlobal()
Expand All @@ -63,8 +51,6 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
true
} else canToggleLocked.remove()

hosts.setOnBindEditTextListener(EditTextPreferenceModifiers.Monospace)
hosts.summaryProvider = HostsSummaryProvider
val serviceMode = findPreference<Preference>(Key.serviceMode)!!
val portProxy = findPreference<EditTextPreference>(Key.portProxy)!!
portProxy.setOnBindEditTextListener(EditTextPreferenceModifiers.Port)
Expand All @@ -78,7 +64,6 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
}
val listener: (BaseService.State) -> Unit = {
val stopped = it == BaseService.State.Stopped
hosts.isEnabled = stopped
serviceMode.isEnabled = stopped
portProxy.isEnabled = stopped
portLocalDns.isEnabled = stopped
Expand All @@ -96,29 +81,6 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
listView.setOnApplyWindowInsetsListener(MainListListener)
}

override fun onDisplayPreferenceDialog(preference: Preference?) {
if (preference == hosts) BrowsableEditTextPreferenceDialogFragment().apply {
setKey(hosts.key)
setTargetFragment(this@GlobalSettingsPreferenceFragment, REQUEST_BROWSE)
}.showAllowingStateLoss(parentFragmentManager, hosts.key) else super.onDisplayPreferenceDialog(preference)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_BROWSE -> {
if (resultCode != Activity.RESULT_OK) return
val activity = activity as MainActivity
try {
// we read and persist all its content here to avoid content URL permission issues
hosts.text = activity.contentResolver.openInputStream(data!!.data!!)!!.bufferedReader().readText()
} catch (e: Exception) {
activity.snackbar(e.readableMessage).show()
}
}
else -> super.onActivityResult(requestCode, resultCode, data)
}
}

override fun onDestroy() {
MainActivity.stateListener = null
super.onDestroy()
Expand Down
Loading

0 comments on commit 141a307

Please sign in to comment.