diff --git a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index 8b06aee4..48626a84 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -23,14 +23,13 @@ package com.github.shadowsocks import java.io.File import java.util.Locale -import android.annotation.SuppressLint import android.content._ import android.content.pm.PackageManager.NameNotFoundException import android.net.VpnService import android.os._ import android.util.Log import com.github.shadowsocks.ShadowsocksApplication.app -import com.github.shadowsocks.acl.{Acl, AclSyncJob} +import com.github.shadowsocks.acl.{Acl, AclSyncJob, Subnet} import com.github.shadowsocks.database.Profile import com.github.shadowsocks.utils._ @@ -212,7 +211,6 @@ class ShadowsocksVpnService extends VpnService with BaseService { pdnsdProcess = new GuardedProcess(cmd: _*).start() } - @SuppressLint(Array("NewApi")) def startVpn(): Int = { val builder = new Builder() @@ -249,15 +247,12 @@ class ShadowsocksVpnService extends VpnService with BaseService { if (profile.route == Acl.ALL || profile.route == Acl.BYPASS_CHN) { builder.addRoute("0.0.0.0", 0) } else { - val privateList = getResources.getStringArray(R.array.bypass_private_route) - privateList.foreach(cidr => { - val addr = cidr.split('/') - builder.addRoute(addr(0), addr(1).toInt) + getResources.getStringArray(R.array.bypass_private_route).foreach(cidr => { + val subnet = Subnet.fromString(cidr) + builder.addRoute(subnet.address.getHostAddress, subnet.prefixSize) }) } - builder.addRoute("8.8.0.0", 16) - conn = builder.establish() if (conn == null) throw new NullConnectionException diff --git a/mobile/src/main/scala/com/github/shadowsocks/acl/Subnet.scala b/mobile/src/main/scala/com/github/shadowsocks/acl/Subnet.scala index d7d4cc0b..8d7c140c 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/acl/Subnet.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/acl/Subnet.scala @@ -1,6 +1,6 @@ package com.github.shadowsocks.acl -import java.net.{Inet4Address, Inet6Address, InetAddress} +import java.net.InetAddress import com.github.shadowsocks.utils.Utils @@ -9,16 +9,11 @@ import com.github.shadowsocks.utils.Utils */ @throws[IllegalArgumentException] class Subnet(val address: InetAddress, val prefixSize: Int) extends Comparable[Subnet] { - if (prefixSize < 0) throw new IllegalArgumentException - address match { - case _: Inet4Address => if (prefixSize > 32) throw new IllegalArgumentException - case _: Inet6Address => if (prefixSize > 128) throw new IllegalArgumentException - } + private def addressLength = address.getAddress.length << 3 + if (prefixSize < 0 || prefixSize > addressLength) throw new IllegalArgumentException - override def toString: String = if (address match { - case _: Inet4Address => prefixSize == 32 - case _: Inet6Address => prefixSize == 128 - }) address.getHostAddress else address.getHostAddress + '/' + prefixSize + override def toString: String = + if (prefixSize == addressLength) address.getHostAddress else address.getHostAddress + '/' + prefixSize override def compareTo(that: Subnet): Int = { val addrThis = address.getAddress @@ -37,13 +32,9 @@ object Subnet { @throws[IllegalArgumentException] def fromString(value: String): Subnet = { val parts = value.split("/") - if (!Utils.isNumeric(parts(0))) throw new IllegalArgumentException() - val addr = InetAddress.getByName(parts(0)) + val addr = Utils.parseNumericAddress(parts(0)) parts.length match { - case 1 => new Subnet(addr, addr match { - case _: Inet4Address => 32 - case _: Inet6Address => 128 - }) + case 1 => new Subnet(addr, addr.getAddress.length << 3) case 2 => new Subnet(addr, parts(1).toInt) case _ => throw new IllegalArgumentException() } diff --git a/mobile/src/main/scala/com/github/shadowsocks/utils/Utils.scala b/mobile/src/main/scala/com/github/shadowsocks/utils/Utils.scala index 03e55b85..a97f6f25 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/utils/Utils.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/utils/Utils.scala @@ -20,6 +20,7 @@ package com.github.shadowsocks.utils +import java.lang.reflect.InvocationTargetException import java.net._ import java.security.MessageDigest @@ -108,7 +109,15 @@ object Utils { .orElse(resolve(host)) private lazy val isNumericMethod = classOf[InetAddress].getMethod("isNumeric", classOf[String]) + private lazy val parseNumericAddressMethod = classOf[InetAddress].getMethod("parseNumericAddress", classOf[String]) def isNumeric(address: String): Boolean = isNumericMethod.invoke(null, address).asInstanceOf[Boolean] + def parseNumericAddress(address: String): InetAddress = + try parseNumericAddressMethod.invoke(null, address).asInstanceOf[InetAddress] catch { + case exc: InvocationTargetException => throw exc.getCause match { + case null => exc + case cause => cause + } + } /** * If there exists a valid IPv6 interface