Commit 35125420 authored by Max Lv's avatar Max Lv

fix #366

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