Skip to content

Commit

Permalink
Ensure hosts results are used
Browse files Browse the repository at this point in the history
Fixes #2412.
  • Loading branch information
Mygod committed Jan 19, 2020
1 parent e9dc275 commit ef1bd7d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 22 deletions.
32 changes: 19 additions & 13 deletions core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.IOException
import java.net.HttpURLConnection
import java.net.URL
import java.net.UnknownHostException
import java.net.*
import java.security.MessageDigest

/**
Expand Down Expand Up @@ -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
if (profile.host.parseNumericAddress() == null) {
// if fails/null, use IPv4 only, otherwise pick a random IPv4/IPv6 address
val network = service.getActiveNetwork() ?: throw UnknownHostException()
val hasIpv4 = DnsResolverCompat.haveIpv4(network)
val hasIpv6 = DnsResolverCompat.haveIpv6(network)
if (!hasIpv4 && !hasIpv6) throw UnknownHostException()
profile.host = (hosts.resolve(profile.host, hasIpv6).firstOrNull() ?: try {
service.resolver(profile.host).firstOrNull()
} catch (_: IOException) {
null
})?.hostAddress ?: throw UnknownHostException()
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)
}
}
}
}?.hostAddress ?: throw UnknownHostException()
}
}

Expand Down
8 changes: 1 addition & 7 deletions core/src/main/java/com/github/shadowsocks/net/HostsFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
package com.github.shadowsocks.net

import com.github.shadowsocks.utils.parseNumericAddress
import java.net.Inet4Address
import java.net.Inet6Address
import java.net.InetAddress

class HostsFile(input: String = "") {
Expand All @@ -36,9 +34,5 @@ class HostsFile(input: String = "") {
}

val configuredHostnames get() = map.size
fun resolve(hostname: String, isIpv6: Boolean): List<InetAddress> {
return (map[hostname] ?: return emptyList()).run {
if (isIpv6) filterIsInstance<Inet6Address>() else filterIsInstance<Inet4Address>()
}.shuffled()
}
fun resolve(hostname: String) = map[hostname]?.shuffled() ?: emptyList()
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,12 @@ class LocalDnsServer(private val localResolver: suspend (String) -> Array<InetAd
else -> return@supervisorScope remote.await()
}
val host = question.name.canonicalize().toString(true)
val hostsResults = hosts.resolve(host, isIpv6)
val hostsResults = hosts.resolve(host)
if (hostsResults.isNotEmpty()) {
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 useLocal = when (acl.shouldBypass(host)) {
Expand Down

0 comments on commit ef1bd7d

Please sign in to comment.