Compare commits

..
8 Commits
Author SHA1 Message Date
Max Lv bae0b9e746 fix a bug 2014-12-08 14:53:30 +08:00
Max Lv 15262343f4 restore DNS nicely 2014-12-08 10:35:59 +08:00
Max Lv be31a0ce82 bump version 2014-12-06 19:16:08 +08:00
Max Lv 0b0b6137b8 disable NAT mode on lollipop by default 2014-12-06 19:15:41 +08:00
Max Lv 156b0c27f5 refine DNS settings 2014-12-06 11:54:42 +08:00
Max Lv ca99596270 Merge branch 'master' of github.com:shadowsocks/shadowsocks-android
Conflicts:
	src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
2014-12-06 11:30:07 +08:00
Max Lv e22ffa8601 improve DNS utils 2014-12-06 11:29:11 +08:00
Max Lv 24233f104a Fix #167 2014-12-04 19:21:22 +08:00
8 changed files with 85 additions and 25 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.shadowsocks"
android:versionCode="89"
android:versionName="2.5.1">
android:versionCode="90"
android:versionName="2.5.2">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+3
View File
@@ -69,6 +69,9 @@
<string name="flushing">刷新中...</string>
<string name="add_profile">添加配置文件</string>
<string name="enable_nat">启用 NAT 模式.</string>
<string name="disable_nat">禁用 NAT 模式.</string>
<string name="udp_dns">UDP 转发</string>
<string name="udp_dns_summary">由远程服务器转发 UDP 协议的数据包</string>
File diff suppressed because one or more lines are too long
+2
View File
@@ -59,6 +59,8 @@
<string name="stop">Stop the service</string>
<string name="stopping">Shutting down...</string>
<string name="vpn_error">Error: \"%s\".</string>
<string name="enable_nat">Turn on NAT mode.</string>
<string name="disable_nat">Turn off NAT mode.</string>
<!-- alert category -->
<string name="ok_iknow">OK</string>
@@ -51,6 +51,7 @@ import android.net.{Uri, VpnService}
import android.os._
import android.preference._
import android.util.{DisplayMetrics, Log}
import android.view.View.OnLongClickListener
import android.view._
import android.webkit.{WebView, WebViewClient}
import android.widget._
@@ -499,13 +500,30 @@ class Shadowsocks
getActionBar.setDisplayShowTitleEnabled(false)
getActionBar.setDisplayShowCustomEnabled(true)
getActionBar.setIcon(R.drawable.ic_stat_shadowsocks)
title.setOnLongClickListener(new OnLongClickListener {
override def onLongClick(v: View): Boolean = {
if (Utils.isLollipopOrAbove && bgService != null
&& (bgService.getState == State.INIT || bgService.getState == State.STOPPED)) {
val natEnabled = status.getBoolean(Key.isNAT, false)
status.edit().putBoolean(Key.isNAT, !natEnabled).commit()
if (!natEnabled) {
Toast.makeText(getBaseContext, R.string.enable_nat, Toast.LENGTH_LONG).show()
} else {
Toast.makeText(getBaseContext, R.string.disable_nat, Toast.LENGTH_LONG).show()
}
true
} else {
false
}
}
})
// Register broadcast receiver
registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS))
// Bind to the service
spawn {
val isRoot = Console.isRoot
val isRoot = (!Utils.isLollipopOrAbove || status.getBoolean(Key.isNAT, false)) && Console.isRoot
handler.post(new Runnable {
override def run() {
status.edit.putBoolean(Key.isRoot, isRoot).commit()
@@ -41,6 +41,8 @@ package com.github.shadowsocks
import java.io.File
import java.lang.reflect.{InvocationTargetException, Method}
import java.net.InetAddress
import java.util
import android.app.{Notification, NotificationManager, PendingIntent, Service}
import android.content._
@@ -48,7 +50,7 @@ import android.content.pm.{PackageInfo, PackageManager}
import android.net.{Network, ConnectivityManager}
import android.os._
import android.support.v4.app.NotificationCompat
import android.util.Log
import android.util.{SparseArray, Log}
import android.widget.Toast
import com.github.shadowsocks.aidl.Config
import com.github.shadowsocks.utils._
@@ -71,6 +73,9 @@ class ShadowsocksNatService extends Service with BaseService {
private val mStartForegroundSignature = Array[Class[_]](classOf[Int], classOf[Notification])
private val mStopForegroundSignature = Array[Class[_]](classOf[Boolean])
private val mSetForegroundSignature = Array[Class[_]](classOf[Boolean])
private val mSetForegroundArgs = new Array[AnyRef](1)
private val mStartForegroundArgs = new Array[AnyRef](2)
private val mStopForegroundArgs = new Array[AnyRef](1)
var closeReceiver: BroadcastReceiver = null
var connReceiver: BroadcastReceiver = null
@@ -82,32 +87,61 @@ class ShadowsocksNatService extends Service with BaseService {
private var mSetForeground: Method = null
private var mStartForeground: Method = null
private var mStopForeground: Method = null
private var mSetForegroundArgs = new Array[AnyRef](1)
private var mStartForegroundArgs = new Array[AnyRef](2)
private var mStopForegroundArgs = new Array[AnyRef](1)
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
def setDnsForAllNetwork(dns: String) {
private val dnsAddressCache = new SparseArray[String]
def getNetId(network: Network): Int = {
network.getClass.getDeclaredField("netId").get(network).asInstanceOf[Int]
}
def restoreDnsForAllNetwork() {
val manager = getSystemService(Context.CONNECTIVITY_SERVICE).asInstanceOf[ConnectivityManager]
val networks = manager.getAllNetworks
val cmdBuf = new ArrayBuffer[String]()
networks.foreach(network => {
val networkInfo = manager.getNetworkInfo(network)
if (networkInfo.isAvailable) {
val netId = network.getClass.getDeclaredField("netId").get(network).asInstanceOf[Int]
cmdBuf.append("ndc resolver setnetdns %d \"\" %s".format(netId, dns))
val netId = getNetId(network)
val oldDns = dnsAddressCache.get(netId)
if (oldDns != null) {
cmdBuf.append("ndc resolver setnetdns %d \"\" %s".format(netId, oldDns))
dnsAddressCache.remove(netId)
}
})
Console.runRootCommand(cmdBuf.toArray)
if (cmdBuf.nonEmpty) Console.runRootCommand(cmdBuf.toArray)
}
def setupDns() = {
def setDnsForAllNetwork(dns: String) {
val manager = getSystemService(Context.CONNECTIVITY_SERVICE).asInstanceOf[ConnectivityManager]
val networks = manager.getAllNetworks
if (networks == null) return
val cmdBuf = new ArrayBuffer[String]()
networks.foreach(network => {
val networkInfo = manager.getNetworkInfo(network)
if (networkInfo == null) return
if (networkInfo.isConnected) {
val netId = getNetId(network)
val curDnsList = manager.getLinkProperties(network).getDnsServers
if (curDnsList != null) {
import scala.collection.JavaConverters._
val curDns = curDnsList.asScala.map(ip => ip.getHostAddress).mkString(" ")
if (curDns != dns) {
dnsAddressCache.put(netId, curDns)
cmdBuf.append("ndc resolver setnetdns %d \"\" %s".format(netId, dns))
}
}
}
})
if (cmdBuf.nonEmpty) Console.runRootCommand(cmdBuf.toArray)
}
def setupDns() {
setDnsForAllNetwork("127.0.0.1")
}
def resetDns() = {
setDnsForAllNetwork("114.114.114.114 8.8.8.8 208.67.222.222")
restoreDnsForAllNetwork()
}
def flushDns() {
@@ -476,7 +510,7 @@ class ShadowsocksNatService extends Service with BaseService {
filter.addAction(Action.CLOSE)
closeReceiver = new BroadcastReceiver() {
def onReceive(p1: Context, p2: Intent) {
Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT)
Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT).show()
stopRunner()
}
}
@@ -510,10 +544,6 @@ class ShadowsocksNatService extends Service with BaseService {
// Clean up
killProcesses()
// Set DNS
if (Utils.isLollipopOrAbove) setupDns()
flushDns()
var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
!InetAddressUtils.isIPv6Address(config.proxy)) {
@@ -528,6 +558,11 @@ class ShadowsocksNatService extends Service with BaseService {
}
if (resolved && handleConnection) {
// Set DNS
if (Utils.isLollipopOrAbove) setupDns()
flushDns()
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).format(config.profileName))
changeState(State.CONNECTED)
@@ -50,7 +50,8 @@ import com.github.shadowsocks.aidl.IShadowsocksService
class ShadowsocksRunnerActivity extends Activity {
lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
private lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
private lazy val status = getSharedPreferences(Key.status, Context.MODE_PRIVATE)
val handler = new Handler()
val connection = new ServiceConnection {
@@ -72,10 +73,10 @@ class ShadowsocksRunnerActivity extends Activity {
def isVpnEnabled: Boolean = {
if (vpnEnabled < 0) {
vpnEnabled = if (!Console.isRoot) {
1
} else {
vpnEnabled = if ((!Utils.isLollipopOrAbove || status.getBoolean(Key.isNAT, false)) && Console.isRoot) {
0
} else {
1
}
}
if (vpnEnabled == 1) true else false
@@ -65,6 +65,7 @@ object Key {
val proxied = "Proxyed"
val isNAT = "isNAT"
val isRoot = "isRoot"
val status = "status"
val proxyedApps = "proxyedApps"