diff --git a/core/schemas/com.github.shadowsocks.database.PrivateDatabase/29.json b/core/schemas/com.github.shadowsocks.database.PrivateDatabase/29.json index 5a695600e7..8251c64540 100644 --- a/core/schemas/com.github.shadowsocks.database.PrivateDatabase/29.json +++ b/core/schemas/com.github.shadowsocks.database.PrivateDatabase/29.json @@ -2,11 +2,11 @@ "formatVersion": 1, "database": { "version": 29, - "identityHash": "5b5c55a1277c63e14416316f9198ed43", + "identityHash": "edf35c5851b4cb55bb5dbbf278199450", "entities": [ { "tableName": "Profile", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `host` TEXT NOT NULL, `remotePort` INTEGER NOT NULL, `password` TEXT NOT NULL, `method` TEXT NOT NULL, `route` TEXT NOT NULL, `remoteDns` TEXT NOT NULL, `proxyApps` INTEGER NOT NULL, `bypass` INTEGER NOT NULL, `udpdns` INTEGER NOT NULL, `ipv6` INTEGER NOT NULL, `metered` INTEGER NOT NULL, `individual` TEXT NOT NULL, `plugin` TEXT, `udpFallback` INTEGER, `subscription` INTEGER NOT NULL, `tx` INTEGER NOT NULL, `rx` INTEGER NOT NULL, `userOrder` INTEGER NOT NULL)", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `host` TEXT NOT NULL, `remotePort` INTEGER NOT NULL, `password` TEXT NOT NULL, `method` TEXT NOT NULL, `route` TEXT NOT NULL, `remoteDns` TEXT NOT NULL, `proxyApps` INTEGER NOT NULL, `bypass` INTEGER NOT NULL, `udpdns` INTEGER NOT NULL, `ipv6` INTEGER NOT NULL, `metered` INTEGER NOT NULL, `individual` TEXT NOT NULL, `plugin` TEXT, `udpFallback` INTEGER, `optimizeBuffers` INTEGER NOT NULL, `subscription` INTEGER NOT NULL, `tx` INTEGER NOT NULL, `rx` INTEGER NOT NULL, `userOrder` INTEGER NOT NULL)", "fields": [ { "fieldPath": "id", @@ -104,6 +104,12 @@ "affinity": "INTEGER", "notNull": false }, + { + "fieldPath": "optimizeBuffers", + "columnName": "optimizeBuffers", + "affinity": "INTEGER", + "notNull": true + }, { "fieldPath": "subscription", "columnName": "subscription", @@ -130,10 +136,10 @@ } ], "primaryKey": { + "autoGenerate": true, "columnNames": [ "id" - ], - "autoGenerate": true + ] }, "indices": [], "foreignKeys": [] @@ -162,10 +168,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "key" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -174,7 +180,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5b5c55a1277c63e14416316f9198ed43')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'edf35c5851b4cb55bb5dbbf278199450')" ] } } \ No newline at end of file diff --git a/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt b/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt index 05f834707b..41dcdaaea3 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt @@ -117,10 +117,22 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro val cmd = arrayListOf( File((service as Context).applicationInfo.nativeLibraryDir, Executable.SS_LOCAL).absolutePath, "--stat-path", stat.absolutePath, - "-c", configFile.absolutePath, + "-c", configFile.absolutePath ) - if (service.isVpnService) cmd += "--vpn" + if (profile.optimizeBuffers) { + cmd += "--inbound-send-buffer-size=16384" + cmd += "--inbound-recv-buffer-size=16384" + + if (profile.plugin?.isNotBlank() == true) { + cmd += "--outbound-send-buffer-size=16384" + cmd += "--outbound-recv-buffer-size=16384" + } + } + + if (service.isVpnService) { + cmd += "--vpn" + } if (route != Acl.ALL) { cmd += "--acl" diff --git a/core/src/main/java/com/github/shadowsocks/database/Profile.kt b/core/src/main/java/com/github/shadowsocks/database/Profile.kt index bae60e1066..d1f95a1836 100644 --- a/core/src/main/java/com/github/shadowsocks/database/Profile.kt +++ b/core/src/main/java/com/github/shadowsocks/database/Profile.kt @@ -70,6 +70,7 @@ data class Profile( var individual: String = "", var plugin: String? = null, var udpFallback: Long? = null, + var optimizeBuffers: Boolean = true, // managed fields var subscription: SubscriptionStatus = SubscriptionStatus.UserConfigured, @@ -355,6 +356,7 @@ data class Profile( DataStore.individual = individual DataStore.plugin = plugin ?: "" DataStore.udpFallback = udpFallback + DataStore.optimizeBuffers = optimizeBuffers DataStore.privateStore.remove(Key.dirty) } @@ -378,5 +380,6 @@ data class Profile( individual = DataStore.individual plugin = DataStore.plugin udpFallback = DataStore.udpFallback + optimizeBuffers = DataStore.optimizeBuffers } } diff --git a/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt b/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt index a523681f74..c6fd940c5c 100644 --- a/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt +++ b/core/src/main/java/com/github/shadowsocks/preference/DataStore.kt @@ -104,6 +104,9 @@ object DataStore : OnPreferenceDataStoreChangeListener { var udpFallback: Long? get() = privateStore.getLong(Key.udpFallback) set(value) = privateStore.putLong(Key.udpFallback, value) + var optimizeBuffers: Boolean + get() = privateStore.getBoolean(Key.optimizeBuffers) ?: true + set(value) = privateStore.putBoolean(Key.optimizeBuffers, value) var dirty: Boolean get() = privateStore.getBoolean(Key.dirty) ?: false set(value) = privateStore.putBoolean(Key.dirty, value) diff --git a/core/src/main/java/com/github/shadowsocks/utils/Constants.kt b/core/src/main/java/com/github/shadowsocks/utils/Constants.kt index 52b6de20ec..b48f54bbd8 100644 --- a/core/src/main/java/com/github/shadowsocks/utils/Constants.kt +++ b/core/src/main/java/com/github/shadowsocks/utils/Constants.kt @@ -61,6 +61,7 @@ object Key { const val plugin = "plugin" const val pluginConfigure = "plugin.configure" const val udpFallback = "udpFallback" + const val optimizeBuffers = "optimizeBuffers"; const val dirty = "profileDirty" diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 04ed7d9d67..8fb5180a50 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -32,6 +32,8 @@ Remote Port Password Encrypt Method + Optimize TCP Buffers + Fix upload timeout (bufferbloat) IPv6 Route diff --git a/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt b/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt index 8ca2d21c4d..f238097ec1 100644 --- a/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt +++ b/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt @@ -79,6 +79,7 @@ class ProfileConfigFragment : PreferenceFragmentCompat(), private lateinit var pluginConfiguration: PluginConfiguration private lateinit var receiver: BroadcastReceiver private lateinit var udpFallback: Preference + private lateinit var optimizeBuffers: SwitchPreference private fun makeDirt() { DataStore.dirty = true @@ -115,6 +116,8 @@ class ProfileConfigFragment : PreferenceFragmentCompat(), pluginConfiguration = PluginConfiguration(DataStore.plugin) initPlugins() udpFallback = findPreference(Key.udpFallback)!! + optimizeBuffers = findPreference(Key.optimizeBuffers)!! + optimizeBuffers.isChecked = DataStore.optimizeBuffers DataStore.privateStore.registerChangeListener(this) val profile = ProfileManager.getProfile(profileId) ?: Profile() diff --git a/mobile/src/main/res/xml/pref_profile.xml b/mobile/src/main/res/xml/pref_profile.xml index 5db0dd19a3..64f2891d83 100644 --- a/mobile/src/main/res/xml/pref_profile.xml +++ b/mobile/src/main/res/xml/pref_profile.xml @@ -65,8 +65,11 @@ app:key="remoteDns" app:icon="@drawable/ic_action_dns" app:title="@string/remote_dns" - app:useSimpleSummaryProvider="true"/> - + app:useSimpleSummaryProvider="true" /> +