Commit 80d93a84 authored by Mygod's avatar Mygod Committed by Max Lv

Add support for TCP Fast Open (#809)

* Add support for TCP Fast Open

* Remove useless echo done line

* Check return values before proceeding in TcpFastOpen.enabled
parent 9b07239c
......@@ -53,6 +53,8 @@
<string name="bypass_apps_summary">Включите эту опцию для работы выбранных приложений в обход прокси</string>
<string name="auto_connect">Авто Подключение</string>
<string name="auto_connect_summary">Запускать Shadowsocks при включении</string>
<string name="tcp_fastopen_summary">Переключение требует наличия ROOT прав</string>
<string name="tcp_fastopen_summary_unsupported">Неподдерживаемая версия ядра: %s &lt; 3.7.1</string>
<string name="udp_dns">Проброс UDP</string>
<string name="udp_dns_summary">Пробрасывать UDP пакеты на удалённый сервер</string>
......
......@@ -32,6 +32,8 @@
<string name="bypass_apps_summary">启用该选项,以使所选应用程序的流量不经过代理</string>
<string name="auto_connect">自动连接</string>
<string name="auto_connect_summary">随系统启动后台服务</string>
<string name="tcp_fastopen_summary">切换需要 ROOT 权限</string>
<string name="tcp_fastopen_summary_unsupported">不支持的内核版本:%s &lt; 3.7.1</string>
<string name="forward_success">后台服务已开始运行。</string>
<string name="service_failed">无法连接远程服务器</string>
<string name="invalid_server">服务器名无效</string>
......
......@@ -33,6 +33,8 @@
<string name="bypass_apps_summary">啟用此選項,會略過已選擇的應用程式</string>
<string name="auto_connect">自動連線</string>
<string name="auto_connect_summary">在裝置啟動時啟用 Shadowsocks</string>
<string name="tcp_fastopen_summary">切換需要 ROOT 權限</string>
<string name="tcp_fastopen_summary_unsupported">不支持的內核版本:%s &lt; 3.7.1</string>
<string name="forward_success">Shadowsocks 已啟動。</string>
<string name="service_failed">連線至遠端伺服器失敗</string>
<string name="invalid_server">伺服器名稱無效</string>
......
......@@ -59,6 +59,8 @@
<string name="bypass_apps_summary">Enable this option to bypass selected apps</string>
<string name="auto_connect">Auto Connect</string>
<string name="auto_connect_summary">Enable Shadowsocks on startup</string>
<string name="tcp_fastopen_summary">Toggling requires ROOT permission</string>
<string name="tcp_fastopen_summary_unsupported">Unsupported kernel version: %s &lt; 3.7.1</string>
<string name="udp_dns">UDP Forwarding</string>
<string name="udp_dns_summary">Forward UDP packets to remote</string>
......
......@@ -110,6 +110,12 @@
android:summary="@string/auto_connect_summary"
android:title="@string/auto_connect"/>
<SwitchPreference
android:key="tcp_fastopen"
android:persistent="false"
android:summary="@string/tcp_fastopen_summary"
android:title="TCP Fast Open"/>
<SwitchPreference android:key="isNAT"
android:title="@string/nat"
android:summary="@string/nat_summary"/>
......
......@@ -106,6 +106,8 @@ class ShadowsocksNatService extends BaseService {
if (profile.auth) cmd += "-A"
if (TcpFastOpen.sendEnabled) cmd += "--fast-open"
if (profile.route != Route.ALL) {
cmd += "--acl"
cmd += (getApplicationInfo.dataDir + "/acl.list")
......@@ -149,6 +151,8 @@ class ShadowsocksNatService extends BaseService {
if (profile.auth) cmd += "-A"
if (TcpFastOpen.sendEnabled) cmd += "--fast-open"
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
sstunnelProcess = new GuardedProcess(cmd).start()
......
......@@ -12,7 +12,7 @@ import android.webkit.{WebView, WebViewClient}
import com.github.shadowsocks.ShadowsocksApplication.app
import com.github.shadowsocks.database.Profile
import com.github.shadowsocks.preferences._
import com.github.shadowsocks.utils.{Key, Utils}
import com.github.shadowsocks.utils.{Key, TcpFastOpen, Utils}
object ShadowsocksSettings {
// Constants
......@@ -154,6 +154,18 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
}
switch.setChecked(BootReceiver.getEnabled(activity))
val tfo = findPreference("tcp_fastopen").asInstanceOf[SwitchPreference]
tfo.setChecked(TcpFastOpen.sendEnabled)
tfo.setOnPreferenceChangeListener((_, v) => {
val value = v.asInstanceOf[Boolean]
TcpFastOpen.enabled(value)
value == TcpFastOpen.sendEnabled
})
if (!TcpFastOpen.supported) {
tfo.setEnabled(false)
tfo.setSummary(getString(R.string.tcp_fastopen_summary_unsupported, java.lang.System.getProperty("os.version")))
}
findPreference("recovery").setOnPreferenceClickListener((preference: Preference) => {
app.track(TAG, "reset")
activity.recovery()
......
......@@ -236,6 +236,8 @@ class ShadowsocksVpnService extends VpnService with BaseService {
if (profile.auth) cmd += "-A"
if (TcpFastOpen.sendEnabled) cmd += "--fast-open"
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
sstunnelProcess = new GuardedProcess(cmd).start()
......@@ -312,6 +314,8 @@ class ShadowsocksVpnService extends VpnService with BaseService {
if (profile.auth) cmd += "-A"
if (TcpFastOpen.sendEnabled) cmd += "--fast-open"
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
sstunnelProcess = new GuardedProcess(cmd).start()
......
package com.github.shadowsocks.utils
import java.io.File
import eu.chainfire.libsuperuser.Shell
/**
* @author Mygod
*/
object TcpFastOpen {
/**
* Is kernel version >= 3.7.1.
*/
lazy val supported = "^(\\d+)\\.(\\d+)\\.(\\d+)".r.findFirstMatchIn(System.getProperty("os.version")) match {
case Some(m) =>
val kernel = m.group(1).toInt
if (kernel < 3) false else if (kernel > 3) true else {
val major = m.group(2).toInt
if (major < 7) false else if (major > 7) true else m.group(3).toInt >= 1
}
case _ => false
}
def sendEnabled = {
val file = new File("/proc/sys/net/ipv4/tcp_fastopen")
file.canRead && (Utils.readAllLines(file).toInt & 1) > 0
}
def enabled(value: Boolean) = if (supported) {
val fastopen = "sysctl -w net.ipv4.tcp_fastopen=" + (if (value) 3 else 0)
Shell.SU.run(Array(
"mount -o remount,rw /system && " + fastopen + " && echo '#!/system/bin/sh\n" + fastopen +
"' > /etc/init.d/tcp_fastopen && chmod 755 /etc/init.d/tcp_fastopen",
"mount -o remount,ro /system"))
}
}
......@@ -38,8 +38,10 @@
*/
package com.github.shadowsocks.utils
import java.io.File
import java.net._
import java.security.MessageDigest
import java.util.Scanner
import android.animation.{Animator, AnimatorListenerAdapter}
import android.content.pm.PackageManager
......@@ -108,6 +110,13 @@ object Utils {
})
}
def readAllLines(f: File) = {
val scanner = new Scanner(f)
try {
scanner.useDelimiter("\\Z")
scanner.next()
} finally scanner.close()
}
def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) {
val p = new java.io.PrintWriter(f)
try {
......
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