Commit 00e9a6d1 authored by Max Lv's avatar Max Lv

fix issue #11

parent d82dc551
...@@ -5,8 +5,8 @@ import org.scalasbt.androidplugin._ ...@@ -5,8 +5,8 @@ import org.scalasbt.androidplugin._
import org.scalasbt.androidplugin.AndroidKeys._ import org.scalasbt.androidplugin.AndroidKeys._
object App { object App {
val version = "1.4.2" val version = "1.4.3"
val versionCode = 24 val versionCode = 25
} }
object General { object General {
......
...@@ -53,6 +53,7 @@ import org.apache.http.conn.util.InetAddressUtils ...@@ -53,6 +53,7 @@ import org.apache.http.conn.util.InetAddressUtils
import org.xbill.DNS._ import org.xbill.DNS._
import android.os.Message import android.os.Message
import scala.Some import scala.Some
import java.net.{UnknownHostException, InetAddress}
object ShadowVpnService { object ShadowVpnService {
def isServiceStarted: Boolean = { def isServiceStarted: Boolean = {
...@@ -116,24 +117,6 @@ class ShadowVpnService extends VpnService { ...@@ -116,24 +117,6 @@ class ShadowVpnService extends VpnService {
}.start() }.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 = { def getVersionName: String = {
var version: String = null var version: String = null
try { try {
...@@ -187,23 +170,11 @@ class ShadowVpnService extends VpnService { ...@@ -187,23 +170,11 @@ class ShadowVpnService extends VpnService {
// Resolve server address // Resolve server address
var resolved: Boolean = false var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(appHost) && !InetAddressUtils.isIPv6Address(appHost)) { if (!InetAddressUtils.isIPv4Address(appHost) && !InetAddressUtils.isIPv6Address(appHost)) {
if (Utils.isIPv6Support) { Utils.resolve(appHost, enableIPv6 = true) match {
resolve(appHost, Type.AAAA) match { case Some(addr) =>
case Some(host) => { appHost = addr
appHost = host
resolved = true
}
case None =>
}
}
if (!resolved) {
resolve(appHost, Type.A) match {
case Some(host) => {
appHost = host
resolved = true resolved = true
} case None => resolved = false
case None =>
}
} }
} else { } else {
resolved = true resolved = true
...@@ -211,20 +182,20 @@ class ShadowVpnService extends VpnService { ...@@ -211,20 +182,20 @@ class ShadowVpnService extends VpnService {
// Resolve UDP gateway // Resolve UDP gateway
if (resolved) { if (resolved) {
resolve("u.maxcdn.info", Type.A) match { Utils.resolve("u.maxcdn.info", enableIPv6 = false) match {
case Some(host) => udpgw = host case Some(host) => udpgw = host
case None => resolved = false case None => resolved = false
} }
} }
if (resolved && handleConnection) { if (resolved && handleConnection) {
handler.sendEmptyMessageDelayed(MSG_CONNECT_SUCCESS, 500) handler.sendEmptyMessageDelayed(MSG_CONNECT_SUCCESS, 300)
} else { } else {
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
stopSelf() handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 300)
handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 500) handler.sendEmptyMessageDelayed(MSG_STOP_SELF, 500)
} }
handler.sendEmptyMessageDelayed(MSG_CONNECT_FINISH, 500) handler.sendEmptyMessageDelayed(MSG_CONNECT_FINISH, 300)
} }
}).start() }).start()
markServiceStarted() markServiceStarted()
...@@ -363,13 +334,20 @@ class ShadowVpnService extends VpnService { ...@@ -363,13 +334,20 @@ class ShadowVpnService extends VpnService {
val filter = new IntentFilter() val filter = new IntentFilter()
filter.addAction(Intent.ACTION_SHUTDOWN) filter.addAction(Intent.ACTION_SHUTDOWN)
filter.addAction(Utils.CLOSE_ACTION) filter.addAction(Utils.CLOSE_ACTION)
receiver = new CloseReceiver receiver = new BroadcastReceiver {
def onReceive(p1: Context, p2: Intent) {
destroy()
stopSelf()}
}
registerReceiver(receiver, filter) registerReceiver(receiver, filter)
} }
def destroy() { def destroy() {
EasyTracker.getTracker.sendEvent("service", "stop", getVersionName, 0L) EasyTracker.getTracker.sendEvent("service", "stop", getVersionName, 0L)
if (receiver != null) unregisterReceiver(receiver) if (receiver != null) {
unregisterReceiver(receiver)
receiver = null
}
new Thread { new Thread {
override def run() { override def run() {
onDisconnect() onDisconnect()
...@@ -383,6 +361,7 @@ class ShadowVpnService extends VpnService { ...@@ -383,6 +361,7 @@ class ShadowVpnService extends VpnService {
conn.close() conn.close()
conn = null conn = null
} }
notificationManager.cancel(1)
markServiceStopped() markServiceStopped()
} }
...@@ -419,20 +398,12 @@ class ShadowVpnService extends VpnService { ...@@ -419,20 +398,12 @@ class ShadowVpnService extends VpnService {
stopSelf() stopSelf()
} }
class CloseReceiver extends BroadcastReceiver {
def onReceive(p1: Context, p2: Intent) {
destroy()
stopSelf()
}
}
val handler: Handler = new Handler { val handler: Handler = new Handler {
override def handleMessage(msg: Message) { override def handleMessage(msg: Message) {
val ed: SharedPreferences.Editor = settings.edit val ed: SharedPreferences.Editor = settings.edit
msg.what match { msg.what match {
case MSG_CONNECT_START => case MSG_CONNECT_START =>
ed.putBoolean("isConnecting", true) ed.putBoolean("isConnecting", true)
val pm: PowerManager = getSystemService(Context.POWER_SERVICE).asInstanceOf[PowerManager]
case MSG_CONNECT_FINISH => case MSG_CONNECT_FINISH =>
ed.putBoolean("isConnecting", false) ed.putBoolean("isConnecting", false)
case MSG_CONNECT_SUCCESS => case MSG_CONNECT_SUCCESS =>
...@@ -442,6 +413,7 @@ class ShadowVpnService extends VpnService { ...@@ -442,6 +413,7 @@ class ShadowVpnService extends VpnService {
case MSG_HOST_CHANGE => case MSG_HOST_CHANGE =>
ed.putString("appHost", appHost) ed.putString("appHost", appHost)
case MSG_STOP_SELF => case MSG_STOP_SELF =>
destroy()
stopSelf() stopSelf()
} }
ed.commit ed.commit
...@@ -450,7 +422,7 @@ class ShadowVpnService extends VpnService { ...@@ -450,7 +422,7 @@ class ShadowVpnService extends VpnService {
} }
var notificationManager: NotificationManager = null var notificationManager: NotificationManager = null
var receiver: CloseReceiver = null var receiver: BroadcastReceiver = null
var appHost: String = null var appHost: String = null
var remotePort: Int = 0 var remotePort: Int = 0
var localPort: Int = 0 var localPort: Int = 0
......
...@@ -421,14 +421,15 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton. ...@@ -421,14 +421,15 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
def onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { def onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
if (key == "isRunning") { if ((key == "isConnecting" || key == "isRunning")
&& !settings.getBoolean("isConnecting", false)) {
if (settings.getBoolean("isRunning", false)) { if (settings.getBoolean("isRunning", false)) {
if (!switchButton.isChecked) switchButton.setChecked(true) if (!switchButton.isChecked) switchButton.setChecked(true)
} } else {
else {
if (switchButton.isChecked) { if (switchButton.isChecked) {
switchButton.setEnabled(true) switchButton.setEnabled(true)
switchButton.setChecked(false) switchButton.setChecked(false)
Crouton.cancelAllCroutons()
} }
} }
} }
......
...@@ -64,6 +64,7 @@ import scala.collection._ ...@@ -64,6 +64,7 @@ import scala.collection._
import org.xbill.DNS._ import org.xbill.DNS._
import scala.Some import scala.Some
import scala.Some import scala.Some
import java.net.{UnknownHostException, InetAddress}
object ShadowsocksService { object ShadowsocksService {
def isServiceStarted: Boolean = { def isServiceStarted: Boolean = {
...@@ -141,23 +142,6 @@ class ShadowsocksService extends Service { ...@@ -141,23 +142,6 @@ class ShadowsocksService extends Service {
version 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) { def handleCommand(intent: Intent) {
if (intent == null) { if (intent == null) {
stopSelf() stopSelf()
...@@ -195,23 +179,11 @@ class ShadowsocksService extends Service { ...@@ -195,23 +179,11 @@ class ShadowsocksService extends Service {
handler.sendEmptyMessage(MSG_CONNECT_START) handler.sendEmptyMessage(MSG_CONNECT_START)
var resolved: Boolean = false var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(appHost) && !InetAddressUtils.isIPv6Address(appHost)) { if (!InetAddressUtils.isIPv4Address(appHost) && !InetAddressUtils.isIPv6Address(appHost)) {
if (Utils.isIPv6Support) { Utils.resolve(appHost, enableIPv6 = true) match {
resolve(appHost, Type.AAAA) match { case Some(addr) =>
case Some(host) => { appHost = addr
appHost = host
resolved = true
}
case None =>
}
}
if (!resolved) {
resolve(appHost, Type.A) match {
case Some(host) => {
appHost = host
resolved = true resolved = true
} case None => resolved = false
case None =>
}
} }
} else { } else {
resolved = true resolved = true
......
...@@ -44,12 +44,66 @@ import android.graphics.drawable.Drawable ...@@ -44,12 +44,66 @@ import android.graphics.drawable.Drawable
import android.os.Environment import android.os.Environment
import android.util.Log import android.util.Log
import java.io._ import java.io._
import java.net.NetworkInterface import java.net.{UnknownHostException, InetAddress, NetworkInterface}
import org.apache.http.conn.util.InetAddressUtils import org.apache.http.conn.util.InetAddressUtils
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import org.xbill.DNS._
import scala.Some
object Utils { 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 * Get local IPv4 address
*/ */
......
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