fix #366
This commit is contained in:
@@ -11,6 +11,7 @@ public class Config implements Parcelable {
|
||||
public boolean isTrafficStat = false;
|
||||
public boolean isUdpDns = false;
|
||||
public boolean isAuth = false;
|
||||
public boolean isIpv6 = false;
|
||||
|
||||
public String profileName = "Untitled";
|
||||
public String proxy = "127.0.0.1";
|
||||
@@ -34,7 +35,7 @@ public class Config implements Parcelable {
|
||||
};
|
||||
|
||||
public Config(boolean isGlobalProxy, boolean isGFWList, boolean isBypassApps,
|
||||
boolean isTrafficStat, boolean isUdpDns, boolean isAuth, String profileName, String proxy, String sitekey,
|
||||
boolean isTrafficStat, boolean isUdpDns, boolean isAuth, boolean isIpv6, String profileName, String proxy, String sitekey,
|
||||
String encMethod, String proxiedAppString, String route, int remotePort, int localPort) {
|
||||
this.isGlobalProxy = isGlobalProxy;
|
||||
this.isGFWList = isGFWList;
|
||||
@@ -42,6 +43,7 @@ public class Config implements Parcelable {
|
||||
this.isTrafficStat = isTrafficStat;
|
||||
this.isUdpDns = isUdpDns;
|
||||
this.isAuth = isAuth;
|
||||
this.isIpv6 = isIpv6;
|
||||
this.profileName = profileName;
|
||||
this.proxy = proxy;
|
||||
this.sitekey = sitekey;
|
||||
@@ -63,6 +65,7 @@ public class Config implements Parcelable {
|
||||
isTrafficStat = in.readInt() == 1;
|
||||
isUdpDns = in.readInt() == 1;
|
||||
isAuth = in.readInt() == 1;
|
||||
isIpv6 = in.readInt() == 1;
|
||||
profileName = in.readString();
|
||||
proxy = in.readString();
|
||||
sitekey = in.readString();
|
||||
@@ -84,6 +87,7 @@ public class Config implements Parcelable {
|
||||
out.writeInt(isTrafficStat ? 1 : 0);
|
||||
out.writeInt(isUdpDns ? 1 : 0);
|
||||
out.writeInt(isAuth ? 1 : 0);
|
||||
out.writeInt(isIpv6 ? 1 : 0);
|
||||
out.writeString(profileName);
|
||||
out.writeString(proxy);
|
||||
out.writeString(sitekey);
|
||||
|
||||
@@ -80,6 +80,9 @@
|
||||
<string name="onetime_auth">一次性认证</string>
|
||||
<string name="onetime_auth_summary">启用一次性认证(实验性)</string>
|
||||
|
||||
<string name="ipv6">IPv6 路由</string>
|
||||
<string name="ipv6_summary">向远程服务器转发 IPv6 流量</string>
|
||||
|
||||
<!-- profile -->
|
||||
<string name="add_profile_dialog">为影梭添加此配置文件?</string>
|
||||
<string-array name="add_profile_methods">
|
||||
|
||||
@@ -25,12 +25,14 @@
|
||||
|
||||
<!-- feature category -->
|
||||
<string name="feature_cat">Feature Settings</string>
|
||||
<string name="ipv6">IPv6 Route</string>
|
||||
<string name="ipv6_summary">Redirect IPv6 traffic to remote</string>
|
||||
<string name="onetime_auth">One-time Authentication</string>
|
||||
<string name="onetime_auth_summary">Enable one-time authentication (Experimental)</string>
|
||||
<string name="http_proxy">HTTP Proxy</string>
|
||||
<string name="http_proxy_summary">Local HTTP Proxy</string>
|
||||
<string name="dns_proxy">DNS Proxy</string>
|
||||
<string name="dns_proxy_summary">Redirect DNS queries to remote server</string>
|
||||
<string name="dns_proxy_summary">Redirect DNS queries to remote</string>
|
||||
<string name="auto_set_gfwlist">CHN Route</string>
|
||||
<string name="auto_set_gfwlist_summary">Bypass all sites located in China
|
||||
</string>
|
||||
|
||||
@@ -58,6 +58,12 @@
|
||||
android:summary="@string/route_list_summary"
|
||||
android:title="@string/route_list">
|
||||
</com.github.shadowsocks.preferences.SummaryListPreference>
|
||||
<CheckBoxPreference
|
||||
android:key="isIpv6"
|
||||
android:defaultValue="false"
|
||||
android:summary="@string/ipv6_summary"
|
||||
android:title="@string/ipv6">
|
||||
</CheckBoxPreference>
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="isGlobalProxy"
|
||||
|
||||
@@ -127,7 +127,7 @@ object Shadowsocks {
|
||||
val PROXY_PREFS = Array(Key.profileName, Key.proxy, Key.remotePort, Key.localPort, Key.sitekey,
|
||||
Key.encMethod)
|
||||
val FEATRUE_PREFS = Array(Key.route, Key.isGlobalProxy, Key.proxyedApps,
|
||||
Key.isUdpDns, Key.isAuth, Key.isAutoConnect)
|
||||
Key.isUdpDns, Key.isAuth, Key.isIpv6, Key.isAutoConnect)
|
||||
|
||||
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL, Executable.TUN2SOCKS)
|
||||
|
||||
@@ -167,6 +167,7 @@ object Shadowsocks {
|
||||
case Key.isGlobalProxy => updateCheckBoxPreference(pref, profile.global)
|
||||
case Key.isUdpDns => updateCheckBoxPreference(pref, profile.udpdns)
|
||||
case Key.isAuth => updateCheckBoxPreference(pref, profile.auth)
|
||||
case Key.isIpv6 => updateCheckBoxPreference(pref, profile.ipv6)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,10 +271,10 @@ class ShadowsocksNatService extends Service with BaseService {
|
||||
val reject = ConfigUtils.getRejectList(getContext, application)
|
||||
val blackList = ConfigUtils.getBlackList(getContext, application)
|
||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
|
||||
Path.BASE + "pdnsd-nat.pid", reject, blackList, 8163)
|
||||
Path.BASE + "pdnsd-nat.pid", reject, blackList, 8163, "")
|
||||
} else {
|
||||
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
|
||||
Path.BASE + "pdnsd-nat.pid", 8163)
|
||||
Path.BASE + "pdnsd-nat.pid", 8163, "")
|
||||
}
|
||||
|
||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-nat.conf"))(p => {
|
||||
|
||||
@@ -65,6 +65,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
val TAG = "ShadowsocksVpnService"
|
||||
val VPN_MTU = 1500
|
||||
val PRIVATE_VLAN = "26.26.26.%s"
|
||||
val PRIVATE_VLAN6 = "fdfe:dcba:9876::%s"
|
||||
var conn: ParcelFileDescriptor = null
|
||||
var notificationManager: NotificationManager = null
|
||||
var receiver: BroadcastReceiver = null
|
||||
@@ -344,15 +345,16 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
}
|
||||
|
||||
def startDnsDaemon() {
|
||||
val ipv6 = if (config.isIpv6) "" else "reject = ::/0;"
|
||||
val conf = {
|
||||
if (config.route == Route.BYPASS_CHN) {
|
||||
val reject = ConfigUtils.getRejectList(getContext, application)
|
||||
val blackList = ConfigUtils.getBlackList(getContext, application)
|
||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153,
|
||||
Path.BASE + "pdnsd-vpn.pid", reject, blackList, 8163)
|
||||
Path.BASE + "pdnsd-vpn.pid", reject, blackList, 8163, ipv6)
|
||||
} else {
|
||||
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153,
|
||||
Path.BASE + "pdnsd-vpn.pid", 8163)
|
||||
Path.BASE + "pdnsd-vpn.pid", 8163, ipv6)
|
||||
}
|
||||
}
|
||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-vpn.conf"))(p => {
|
||||
@@ -375,9 +377,12 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
.addAddress(PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), 24)
|
||||
.addDnsServer("8.8.8.8")
|
||||
|
||||
if (Utils.isLollipopOrAbove) {
|
||||
if (config.isIpv6) {
|
||||
builder.addAddress(PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "1"), 126)
|
||||
builder.addRoute("::", 0)
|
||||
}
|
||||
|
||||
builder.allowFamily(android.system.OsConstants.AF_INET6)
|
||||
if (Utils.isLollipopOrAbove) {
|
||||
|
||||
if (!config.isGlobalProxy) {
|
||||
val apps = AppManager.getProxiedApps(this, config.proxiedAppString)
|
||||
@@ -433,7 +438,12 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
+ "--tunmtu %d "
|
||||
+ "--loglevel 3 "
|
||||
+ "--pid %stun2socks-vpn.pid")
|
||||
.formatLocal(Locale.ENGLISH, PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "2"), config.localPort, fd, VPN_MTU, Path.BASE)
|
||||
.formatLocal(Locale.ENGLISH,
|
||||
PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "2"),
|
||||
config.localPort, fd, VPN_MTU, Path.BASE)
|
||||
|
||||
if (config.isIpv6)
|
||||
cmd += " --netif-ip6addr " + PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "2")
|
||||
|
||||
if (config.isUdpDns)
|
||||
cmd += " --enable-udprelay"
|
||||
|
||||
@@ -51,7 +51,7 @@ object DBHelper {
|
||||
}
|
||||
|
||||
class DBHelper(val context: Context)
|
||||
extends OrmLiteSqliteOpenHelper(context, DBHelper.PROFILE, null, 10) {
|
||||
extends OrmLiteSqliteOpenHelper(context, DBHelper.PROFILE, null, 11) {
|
||||
|
||||
lazy val profileDao: Dao[Profile, Int] = getDao(classOf[Profile])
|
||||
|
||||
@@ -69,6 +69,8 @@ class DBHelper(val context: Context)
|
||||
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN route VARCHAR;")
|
||||
} else if (oldVersion < 10) {
|
||||
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN auth SMALLINT;")
|
||||
} else if (oldVersion < 11) {
|
||||
profileDao.executeRaw("ALTER TABLE `profile` ADD COLUMN ipv6 SMALLINT;")
|
||||
} else {
|
||||
profileDao.executeRaw("DROP TABLE IF EXISTS 'profile';")
|
||||
onCreate(database, connectionSource)
|
||||
|
||||
@@ -93,6 +93,9 @@ class Profile {
|
||||
@DatabaseField
|
||||
var auth: Boolean = false
|
||||
|
||||
@DatabaseField
|
||||
var ipv6: Boolean = false
|
||||
|
||||
@DatabaseField(dataType = DataType.LONG_STRING)
|
||||
var individual: String = ""
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
|
||||
edit.putBoolean(Key.isTrafficStat, profile.traffic)
|
||||
edit.putBoolean(Key.isUdpDns, profile.udpdns)
|
||||
edit.putBoolean(Key.isAuth, profile.auth)
|
||||
edit.putBoolean(Key.isIpv6, profile.ipv6)
|
||||
edit.putString(Key.profileName, profile.name)
|
||||
edit.putString(Key.proxy, profile.host)
|
||||
edit.putString(Key.sitekey, profile.password)
|
||||
@@ -148,6 +149,7 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
|
||||
profile.traffic = settings.getBoolean(Key.isTrafficStat, false)
|
||||
profile.udpdns = settings.getBoolean(Key.isUdpDns, false)
|
||||
profile.auth = settings.getBoolean(Key.isAuth, false)
|
||||
profile.ipv6 = settings.getBoolean(Key.isIpv6, false)
|
||||
profile.name = settings.getString(Key.profileName, "default")
|
||||
profile.host = settings.getString(Key.proxy, "127.0.0.1")
|
||||
profile.password = settings.getString(Key.sitekey, "default")
|
||||
|
||||
@@ -82,7 +82,7 @@ object ConfigUtils {
|
||||
| label = "local";
|
||||
| ip = 127.0.0.1;
|
||||
| port = %d;
|
||||
| reject = ::/0;
|
||||
| %s
|
||||
| reject_policy = negate;
|
||||
| reject_recursively = on;
|
||||
| timeout = 5;
|
||||
@@ -174,7 +174,7 @@ object ConfigUtils {
|
||||
| label = "local-server";
|
||||
| ip = 127.0.0.1;
|
||||
| port = %d;
|
||||
| reject = ::/0;
|
||||
| %s
|
||||
| reject_policy = negate;
|
||||
| reject_recursively = on;
|
||||
|}
|
||||
@@ -242,7 +242,7 @@ object ConfigUtils {
|
||||
val method = proxy(3).trim
|
||||
|
||||
new Config(config.isGlobalProxy, config.isGFWList, config.isBypassApps, config.isTrafficStat,
|
||||
config.isUdpDns, config.isAuth, config.profileName, host, password, method, config.proxiedAppString, config.route, port,
|
||||
config.isUdpDns, config.isAuth, config.isIpv6, config.profileName, host, password, method, config.proxiedAppString, config.route, port,
|
||||
config.localPort)
|
||||
}
|
||||
|
||||
@@ -253,6 +253,7 @@ object ConfigUtils {
|
||||
val isTrafficStat = settings.getBoolean(Key.isTrafficStat, false)
|
||||
val isUdpDns = settings.getBoolean(Key.isUdpDns, false)
|
||||
val isAuth = settings.getBoolean(Key.isAuth, false)
|
||||
val isIpv6 = settings.getBoolean(Key.isIpv6, false)
|
||||
|
||||
val profileName = settings.getString(Key.profileName, "default")
|
||||
val proxy = settings.getString(Key.proxy, "127.0.0.1")
|
||||
@@ -274,7 +275,7 @@ object ConfigUtils {
|
||||
}
|
||||
val proxiedAppString = settings.getString(Key.proxied, "")
|
||||
|
||||
new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, isUdpDns, isAuth, profileName, proxy,
|
||||
new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, isUdpDns, isAuth, isIpv6, profileName, proxy,
|
||||
sitekey, encMethod, proxiedAppString, route, remotePort, localPort)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ object Key {
|
||||
val isTrafficStat = "isTrafficStat"
|
||||
val isUdpDns = "isUdpDns"
|
||||
val isAuth= "isAuth"
|
||||
val isIpv6= "isIpv6"
|
||||
|
||||
val proxy = "proxy"
|
||||
val sitekey = "sitekey"
|
||||
|
||||
Reference in New Issue
Block a user