Commit ef1bd7d7 authored by Mygod's avatar Mygod

Ensure hosts results are used

Fixes #2412.
parent e9dc275f
...@@ -38,9 +38,7 @@ import kotlinx.coroutines.Dispatchers ...@@ -38,9 +38,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.net.HttpURLConnection import java.net.*
import java.net.URL
import java.net.UnknownHostException
import java.security.MessageDigest import java.security.MessageDigest
/** /**
...@@ -87,16 +85,24 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro ...@@ -87,16 +85,24 @@ 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 // it's hard to resolve DNS on a specific interface so we'll do it here
if (profile.host.parseNumericAddress() == null) { if (profile.host.parseNumericAddress() == null) {
// if fails/null, use IPv4 only, otherwise pick a random IPv4/IPv6 address profile.host = hosts.resolve(profile.host).run {
val network = service.getActiveNetwork() ?: throw UnknownHostException() if (isEmpty()) try {
val hasIpv4 = DnsResolverCompat.haveIpv4(network) service.resolver(profile.host).firstOrNull()
val hasIpv6 = DnsResolverCompat.haveIpv6(network) } catch (_: IOException) {
if (!hasIpv4 && !hasIpv6) throw UnknownHostException() null
profile.host = (hosts.resolve(profile.host, hasIpv6).firstOrNull() ?: try { } else {
service.resolver(profile.host).firstOrNull() val network = service.getActiveNetwork() ?: throw UnknownHostException()
} catch (_: IOException) { val hasIpv4 = DnsResolverCompat.haveIpv4(network)
null val hasIpv6 = DnsResolverCompat.haveIpv6(network)
})?.hostAddress ?: throw UnknownHostException() firstOrNull {
when (it) {
is Inet4Address -> hasIpv4
is Inet6Address -> hasIpv6
else -> error(it)
}
}
}
}?.hostAddress ?: throw UnknownHostException()
} }
} }
......
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
package com.github.shadowsocks.net package com.github.shadowsocks.net
import com.github.shadowsocks.utils.parseNumericAddress import com.github.shadowsocks.utils.parseNumericAddress
import java.net.Inet4Address
import java.net.Inet6Address
import java.net.InetAddress import java.net.InetAddress
class HostsFile(input: String = "") { class HostsFile(input: String = "") {
...@@ -36,9 +34,5 @@ class HostsFile(input: String = "") { ...@@ -36,9 +34,5 @@ class HostsFile(input: String = "") {
} }
val configuredHostnames get() = map.size val configuredHostnames get() = map.size
fun resolve(hostname: String, isIpv6: Boolean): List<InetAddress> { fun resolve(hostname: String) = map[hostname]?.shuffled() ?: emptyList()
return (map[hostname] ?: return emptyList()).run {
if (isIpv6) filterIsInstance<Inet6Address>() else filterIsInstance<Inet4Address>()
}.shuffled()
}
} }
...@@ -124,10 +124,12 @@ class LocalDnsServer(private val localResolver: suspend (String) -> Array<InetAd ...@@ -124,10 +124,12 @@ class LocalDnsServer(private val localResolver: suspend (String) -> Array<InetAd
else -> return@supervisorScope remote.await() else -> return@supervisorScope remote.await()
} }
val host = question.name.canonicalize().toString(true) val host = question.name.canonicalize().toString(true)
val hostsResults = hosts.resolve(host, isIpv6) val hostsResults = hosts.resolve(host)
if (hostsResults.isNotEmpty()) { if (hostsResults.isNotEmpty()) {
remote.cancel() remote.cancel()
return@supervisorScope cookDnsResponse(request, hostsResults) return@supervisorScope cookDnsResponse(request, hostsResults.run {
if (isIpv6) filterIsInstance<Inet6Address>() else filterIsInstance<Inet4Address>()
})
} }
val acl = acl?.await() ?: return@supervisorScope remote.await() val acl = acl?.await() ?: return@supervisorScope remote.await()
val useLocal = when (acl.shouldBypass(host)) { val useLocal = when (acl.shouldBypass(host)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment