From 1f59432337f9e2b76217a6b707a0828794807159 Mon Sep 17 00:00:00 2001 From: arm64v8a <48624112+arm64v8a@users.noreply.github.com> Date: Fri, 26 May 2023 15:59:06 +0900 Subject: [PATCH] UOT option for naive & socks --- .../io/nekohasekai/sagernet/bg/Executable.kt | 4 ++-- .../nekohasekai/sagernet/fmt/ConfigBuilder.kt | 19 ++++++++++++++----- .../sagernet/fmt/naive/NaiveBean.java | 10 +++++++++- .../fmt/shadowsocks/ShadowsocksBean.java | 7 +++++++ .../fmt/shadowsocks/ShadowsocksFmt.kt | 5 ----- .../sagernet/fmt/socks/SOCKSBean.java | 9 ++++++++- .../ui/profile/NaiveSettingsActivity.kt | 2 ++ .../ui/profile/SocksSettingsActivity.kt | 4 ++++ app/src/main/res/xml/naive_preferences.xml | 6 +++++- app/src/main/res/xml/socks_preferences.xml | 5 +++++ 10 files changed, 56 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt index 8e69f0b..f944058 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/Executable.kt @@ -13,8 +13,8 @@ object Executable { "libtrojan.so", "libtrojan-go.so", "libnaive.so", - "libhysteria.so", - "libwg.so" + "libtuic.so", + "libhysteria.so" ) fun killAll(alsoKillBg: Boolean = false) { diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt index e3af583..d977f16 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt @@ -372,8 +372,7 @@ fun buildConfig( globalOutbounds[proxyEntity.id] = tagOut } - // Chain outbound - if (proxyEntity.needExternal()) { + if (proxyEntity.needExternal()) { // externel outbound val localPort = mkPort() externalChainMap[localPort] = proxyEntity currentOutbound = Outbound_SocksOptions().apply { @@ -381,9 +380,7 @@ fun buildConfig( server = LOCALHOST server_port = localPort }.asMap() - } else { - // internal outbound - + } else { // internal outbound currentOutbound = when (bean) { is ConfigBean -> gson.fromJson(bean.config, currentOutbound.javaClass) @@ -430,6 +427,18 @@ fun buildConfig( } } } + } + + // internal & external + currentOutbound.apply { + // udp over tcp + try { + val sUoT = bean.javaClass.getField("sUoT").get(bean) + if (sUoT is Boolean && sUoT == true) { + currentOutbound["udp_over_tcp"] = true + } + } catch (_: Exception) { + } // custom JSON merge if (bean.customOutboundJson.isNotBlank()) { diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/naive/NaiveBean.java b/app/src/main/java/io/nekohasekai/sagernet/fmt/naive/NaiveBean.java index 841ae59..6e504d4 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/naive/NaiveBean.java +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/naive/NaiveBean.java @@ -23,6 +23,9 @@ public class NaiveBean extends AbstractBean { public String certificates; public Integer insecureConcurrency; + // sing-box socks + public Boolean sUoT; + @Override public void initializeDefaultValues() { if (serverPort == null) serverPort = 443; @@ -34,11 +37,12 @@ public class NaiveBean extends AbstractBean { if (certificates == null) certificates = ""; if (sni == null) sni = ""; if (insecureConcurrency == null) insecureConcurrency = 0; + if (sUoT == null) sUoT = false; } @Override public void serialize(ByteBufferOutput output) { - output.writeInt(2); + output.writeInt(3); super.serialize(output); output.writeString(proto); output.writeString(username); @@ -48,6 +52,7 @@ public class NaiveBean extends AbstractBean { output.writeString(certificates); output.writeString(sni); output.writeInt(insecureConcurrency); + output.writeBoolean(sUoT); } @Override @@ -65,6 +70,9 @@ public class NaiveBean extends AbstractBean { if (version >= 1) { insecureConcurrency = input.readInt(); } + if (version >= 3) { + sUoT = input.readBoolean(); + } } @NotNull diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksBean.java b/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksBean.java index 10c394f..326662f 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksBean.java +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksBean.java @@ -50,6 +50,13 @@ public class ShadowsocksBean extends AbstractBean { sUoT = input.readBoolean(); } + @Override + public void applyFeatureSettings(AbstractBean other) { + if (!(other instanceof ShadowsocksBean)) return; + ShadowsocksBean bean = ((ShadowsocksBean) other); + bean.sUoT = sUoT; + } + @NotNull @Override public ShadowsocksBean clone() { diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksFmt.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksFmt.kt index 9b0c616..04506ab 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksFmt.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksFmt.kt @@ -114,11 +114,6 @@ fun buildSingBoxOutboundShadowsocksBean(bean: ShadowsocksBean): SingBoxOptions.O server_port = bean.serverPort password = bean.password method = bean.method - if (bean.sUoT) { - udp_over_tcp = SingBoxOptions.UDPOverTCPOptions().apply { - enabled = true - } - } if (bean.plugin.isNotBlank()) { plugin = bean.plugin.substringBefore(";") plugin_opts = bean.plugin.substringAfter(";") diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/socks/SOCKSBean.java b/app/src/main/java/io/nekohasekai/sagernet/fmt/socks/SOCKSBean.java index fb07ac1..5780480 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/socks/SOCKSBean.java +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/socks/SOCKSBean.java @@ -14,6 +14,8 @@ public class SOCKSBean extends AbstractBean { public Integer protocol; + public Boolean sUoT; + public int protocolVersion() { switch (protocol) { case 0: @@ -66,15 +68,17 @@ public class SOCKSBean extends AbstractBean { if (protocol == null) protocol = PROTOCOL_SOCKS5; if (username == null) username = ""; if (password == null) password = ""; + if (sUoT == null) sUoT = false; } @Override public void serialize(ByteBufferOutput output) { - output.writeInt(1); + output.writeInt(2); super.serialize(output); output.writeInt(protocol); output.writeString(username); output.writeString(password); + output.writeBoolean(sUoT); } @Override @@ -86,6 +90,9 @@ public class SOCKSBean extends AbstractBean { } username = input.readString(); password = input.readString(); + if (version >= 2) { + sUoT = input.readBoolean(); + } } @NotNull diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/NaiveSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/NaiveSettingsActivity.kt index 0c0068f..88dcaaf 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/NaiveSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/NaiveSettingsActivity.kt @@ -24,6 +24,7 @@ class NaiveSettingsActivity : ProfileSettingsActivity() { DataStore.serverCertificates = certificates DataStore.serverHeaders = extraHeaders DataStore.serverInsecureConcurrency = insecureConcurrency + DataStore.profileCacheStore.putBoolean("sUoT", sUoT) } override fun NaiveBean.serialize() { @@ -37,6 +38,7 @@ class NaiveSettingsActivity : ProfileSettingsActivity() { certificates = DataStore.serverCertificates extraHeaders = DataStore.serverHeaders.replace("\r\n", "\n") insecureConcurrency = DataStore.serverInsecureConcurrency + sUoT = DataStore.profileCacheStore.getBoolean("sUoT") } override fun PreferenceFragmentCompat.createPreferences( diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SocksSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SocksSettingsActivity.kt index 3d5d8e3..14eb355 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SocksSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SocksSettingsActivity.kt @@ -21,6 +21,8 @@ class SocksSettingsActivity : ProfileSettingsActivity() { DataStore.serverProtocolVersion = protocol DataStore.serverUsername = username DataStore.serverPassword = password + + DataStore.profileCacheStore.putBoolean("sUoT", sUoT) } override fun SOCKSBean.serialize() { @@ -31,6 +33,8 @@ class SocksSettingsActivity : ProfileSettingsActivity() { protocol = DataStore.serverProtocolVersion username = DataStore.serverUsername password = DataStore.serverPassword + + sUoT = DataStore.profileCacheStore.getBoolean("sUoT") } override fun PreferenceFragmentCompat.createPreferences( diff --git a/app/src/main/res/xml/naive_preferences.xml b/app/src/main/res/xml/naive_preferences.xml index 0a7f802..2b91a48 100644 --- a/app/src/main/res/xml/naive_preferences.xml +++ b/app/src/main/res/xml/naive_preferences.xml @@ -61,5 +61,9 @@ app:useSimpleSummaryProvider="true" /> - + + + \ No newline at end of file diff --git a/app/src/main/res/xml/socks_preferences.xml b/app/src/main/res/xml/socks_preferences.xml index 516cbc0..83c6a7e 100644 --- a/app/src/main/res/xml/socks_preferences.xml +++ b/app/src/main/res/xml/socks_preferences.xml @@ -38,4 +38,9 @@ app:title="@string/password_opt" /> + + + \ No newline at end of file