From 00e9a6d12d5aa7a52886c2959f884998b77a24a2 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 11 May 2013 10:47:07 +0800 Subject: [PATCH] fix issue #11 --- project/Build.scala | 4 +- .../github/shadowsocks/ShadowVpnService.scala | 74 ++++++------------- .../com/github/shadowsocks/Shadowsocks.scala | 7 +- .../shadowsocks/ShadowsocksService.scala | 40 ++-------- .../scala/com/github/shadowsocks/Utils.scala | 56 +++++++++++++- 5 files changed, 90 insertions(+), 91 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index edb957ce..1115f532 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -5,8 +5,8 @@ import org.scalasbt.androidplugin._ import org.scalasbt.androidplugin.AndroidKeys._ object App { - val version = "1.4.2" - val versionCode = 24 + val version = "1.4.3" + val versionCode = 25 } object General { diff --git a/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala index 01095025..2dc8214f 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala @@ -53,6 +53,7 @@ import org.apache.http.conn.util.InetAddressUtils import org.xbill.DNS._ import android.os.Message import scala.Some +import java.net.{UnknownHostException, InetAddress} object ShadowVpnService { def isServiceStarted: Boolean = { @@ -116,24 +117,6 @@ class ShadowVpnService extends VpnService { }.start() } - def resolve(host: String, addrType: Int): Option[String] = { - val lookup = new Lookup(host, addrType) - val resolver = new SimpleResolver("8.8.8.8") - resolver.setTimeout(5) - lookup.setResolver(resolver) - val records = lookup.run() - if (records == null) return None - for (r <- records) { - addrType match { - case Type.A => - return Some(r.asInstanceOf[ARecord].getAddress.getHostAddress) - case Type.AAAA => - return Some(r.asInstanceOf[AAAARecord].getAddress.getHostAddress) - } - } - None - } - def getVersionName: String = { var version: String = null try { @@ -187,23 +170,11 @@ class ShadowVpnService extends VpnService { // Resolve server address var resolved: Boolean = false if (!InetAddressUtils.isIPv4Address(appHost) && !InetAddressUtils.isIPv6Address(appHost)) { - if (Utils.isIPv6Support) { - resolve(appHost, Type.AAAA) match { - case Some(host) => { - appHost = host - resolved = true - } - case None => - } - } - if (!resolved) { - resolve(appHost, Type.A) match { - case Some(host) => { - appHost = host - resolved = true - } - case None => - } + Utils.resolve(appHost, enableIPv6 = true) match { + case Some(addr) => + appHost = addr + resolved = true + case None => resolved = false } } else { resolved = true @@ -211,20 +182,20 @@ class ShadowVpnService extends VpnService { // Resolve UDP gateway if (resolved) { - resolve("u.maxcdn.info", Type.A) match { + Utils.resolve("u.maxcdn.info", enableIPv6 = false) match { case Some(host) => udpgw = host case None => resolved = false } } if (resolved && handleConnection) { - handler.sendEmptyMessageDelayed(MSG_CONNECT_SUCCESS, 500) + handler.sendEmptyMessageDelayed(MSG_CONNECT_SUCCESS, 300) } else { notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) - stopSelf() - handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 500) + handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 300) + handler.sendEmptyMessageDelayed(MSG_STOP_SELF, 500) } - handler.sendEmptyMessageDelayed(MSG_CONNECT_FINISH, 500) + handler.sendEmptyMessageDelayed(MSG_CONNECT_FINISH, 300) } }).start() markServiceStarted() @@ -363,13 +334,20 @@ class ShadowVpnService extends VpnService { val filter = new IntentFilter() filter.addAction(Intent.ACTION_SHUTDOWN) filter.addAction(Utils.CLOSE_ACTION) - receiver = new CloseReceiver + receiver = new BroadcastReceiver { + def onReceive(p1: Context, p2: Intent) { + destroy() + stopSelf()} + } registerReceiver(receiver, filter) } def destroy() { EasyTracker.getTracker.sendEvent("service", "stop", getVersionName, 0L) - if (receiver != null) unregisterReceiver(receiver) + if (receiver != null) { + unregisterReceiver(receiver) + receiver = null + } new Thread { override def run() { onDisconnect() @@ -383,6 +361,7 @@ class ShadowVpnService extends VpnService { conn.close() conn = null } + notificationManager.cancel(1) markServiceStopped() } @@ -419,20 +398,12 @@ class ShadowVpnService extends VpnService { stopSelf() } - class CloseReceiver extends BroadcastReceiver { - def onReceive(p1: Context, p2: Intent) { - destroy() - stopSelf() - } - } - val handler: Handler = new Handler { override def handleMessage(msg: Message) { val ed: SharedPreferences.Editor = settings.edit msg.what match { case MSG_CONNECT_START => ed.putBoolean("isConnecting", true) - val pm: PowerManager = getSystemService(Context.POWER_SERVICE).asInstanceOf[PowerManager] case MSG_CONNECT_FINISH => ed.putBoolean("isConnecting", false) case MSG_CONNECT_SUCCESS => @@ -442,6 +413,7 @@ class ShadowVpnService extends VpnService { case MSG_HOST_CHANGE => ed.putString("appHost", appHost) case MSG_STOP_SELF => + destroy() stopSelf() } ed.commit @@ -450,7 +422,7 @@ class ShadowVpnService extends VpnService { } var notificationManager: NotificationManager = null - var receiver: CloseReceiver = null + var receiver: BroadcastReceiver = null var appHost: String = null var remotePort: Int = 0 var localPort: Int = 0 diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 2da1f7e0..68935d97 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -421,14 +421,15 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton. def onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) - if (key == "isRunning") { + if ((key == "isConnecting" || key == "isRunning") + && !settings.getBoolean("isConnecting", false)) { if (settings.getBoolean("isRunning", false)) { if (!switchButton.isChecked) switchButton.setChecked(true) - } - else { + } else { if (switchButton.isChecked) { switchButton.setEnabled(true) switchButton.setChecked(false) + Crouton.cancelAllCroutons() } } } diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala index c27a3e76..51154c53 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala @@ -64,6 +64,7 @@ import scala.collection._ import org.xbill.DNS._ import scala.Some import scala.Some +import java.net.{UnknownHostException, InetAddress} object ShadowsocksService { def isServiceStarted: Boolean = { @@ -141,23 +142,6 @@ class ShadowsocksService extends Service { version } - def resolve(host: String, addrType: Int): Option[String] = { - val lookup = new Lookup(host, addrType) - val resolver = new SimpleResolver("8.8.8.8") - resolver.setTimeout(5) - lookup.setResolver(resolver) - val records = lookup.run() - for (r <- records) { - addrType match { - case Type.A => - return Some(r.asInstanceOf[ARecord].getAddress.getHostAddress) - case Type.AAAA => - return Some(r.asInstanceOf[AAAARecord].getAddress.getHostAddress) - } - } - None - } - def handleCommand(intent: Intent) { if (intent == null) { stopSelf() @@ -195,23 +179,11 @@ class ShadowsocksService extends Service { handler.sendEmptyMessage(MSG_CONNECT_START) var resolved: Boolean = false if (!InetAddressUtils.isIPv4Address(appHost) && !InetAddressUtils.isIPv6Address(appHost)) { - if (Utils.isIPv6Support) { - resolve(appHost, Type.AAAA) match { - case Some(host) => { - appHost = host - resolved = true - } - case None => - } - } - if (!resolved) { - resolve(appHost, Type.A) match { - case Some(host) => { - appHost = host - resolved = true - } - case None => - } + Utils.resolve(appHost, enableIPv6 = true) match { + case Some(addr) => + appHost = addr + resolved = true + case None => resolved = false } } else { resolved = true diff --git a/src/main/scala/com/github/shadowsocks/Utils.scala b/src/main/scala/com/github/shadowsocks/Utils.scala index 458c5ff4..890dc3f3 100644 --- a/src/main/scala/com/github/shadowsocks/Utils.scala +++ b/src/main/scala/com/github/shadowsocks/Utils.scala @@ -44,12 +44,66 @@ import android.graphics.drawable.Drawable import android.os.Environment import android.util.Log import java.io._ -import java.net.NetworkInterface +import java.net.{UnknownHostException, InetAddress, NetworkInterface} import org.apache.http.conn.util.InetAddressUtils import scala.collection.mutable.ArrayBuffer +import org.xbill.DNS._ +import scala.Some object Utils { + + def resolve(host: String, addrType: Int): Option[String] = { + val lookup = new Lookup(host, addrType) + val resolver = new SimpleResolver("8.8.8.8") + resolver.setTimeout(5) + lookup.setResolver(resolver) + val records = lookup.run() + if (records == null) return None + for (r <- records) { + addrType match { + case Type.A => + return Some(r.asInstanceOf[ARecord].getAddress.getHostAddress) + case Type.AAAA => + return Some(r.asInstanceOf[AAAARecord].getAddress.getHostAddress) + } + } + None + } + + def resolve(host: String): Option[String] = { + try { + val addr = InetAddress.getByName(host) + Some(addr.getHostAddress) + } catch { + case e: UnknownHostException => None + } + } + + def resolve(host: String, enableIPv6: Boolean): Option[String] = { + if (enableIPv6 && Utils.isIPv6Support) { + resolve(host, Type.AAAA) match { + case Some(addr) => { + return Some(addr) + } + case None => + } + } + resolve(host, Type.A) match { + case Some(addr) => { + return Some(addr) + } + case None => + } + resolve(host) match { + case Some(addr) => { + return Some(addr) + } + case None => + } + None + } + /** * Get local IPv4 address */