Improve tuic

This commit is contained in:
arm64v8a 2023-06-29 20:19:11 +09:00
parent e056056d2f
commit 71094bac5a
6 changed files with 63 additions and 13 deletions

View File

@ -33,6 +33,7 @@ import libcore.BoxPlatformInterface
import libcore.Libcore import libcore.Libcore
import libcore.NB4AInterface import libcore.NB4AInterface
import moe.matsuri.nb4a.utils.JavaUtil import moe.matsuri.nb4a.utils.JavaUtil
import moe.matsuri.nb4a.utils.LibcoreUtil
import moe.matsuri.nb4a.utils.cleanWebview import moe.matsuri.nb4a.utils.cleanWebview
import java.net.InetSocketAddress import java.net.InetSocketAddress
import androidx.work.Configuration as WorkConfiguration import androidx.work.Configuration as WorkConfiguration
@ -266,7 +267,7 @@ class SagerNet : Application(),
Logs.d("other selector: $selectorTag") Logs.d("other selector: $selectorTag")
return return
} }
Libcore.resetAllConnections(true) LibcoreUtil.resetAllConnections(true)
DataStore.baseService?.apply { DataStore.baseService?.apply {
runOnDefaultDispatcher { runOnDefaultDispatcher {
val id = data.proxy!!.config.profileTagMap val id = data.proxy!!.config.profileTagMap

View File

@ -23,6 +23,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import libcore.Libcore import libcore.Libcore
import moe.matsuri.nb4a.Protocols import moe.matsuri.nb4a.Protocols
import moe.matsuri.nb4a.utils.LibcoreUtil
import moe.matsuri.nb4a.utils.Util import moe.matsuri.nb4a.utils.Util
import java.net.UnknownHostException import java.net.UnknownHostException
@ -52,7 +53,7 @@ class BaseService {
Action.RELOAD -> service.reload() Action.RELOAD -> service.reload()
// Action.SWITCH_WAKE_LOCK -> runOnDefaultDispatcher { service.switchWakeLock() } // Action.SWITCH_WAKE_LOCK -> runOnDefaultDispatcher { service.switchWakeLock() }
Action.RESET_UPSTREAM_CONNECTIONS -> runOnDefaultDispatcher { Action.RESET_UPSTREAM_CONNECTIONS -> runOnDefaultDispatcher {
Libcore.resetAllConnections(true) LibcoreUtil.resetAllConnections(true)
runOnMainDispatcher { runOnMainDispatcher {
Util.collapseStatusBar(ctx) Util.collapseStatusBar(ctx)
Toast.makeText(ctx, "Reset upstream connections done", Toast.LENGTH_SHORT) Toast.makeText(ctx, "Reset upstream connections done", Toast.LENGTH_SHORT)
@ -266,7 +267,7 @@ class BaseService {
} }
if (oldName != null && upstreamInterfaceName != null && oldName != upstreamInterfaceName) { if (oldName != null && upstreamInterfaceName != null && oldName != upstreamInterfaceName) {
Logs.d("Network changed: $oldName -> $upstreamInterfaceName") Logs.d("Network changed: $oldName -> $upstreamInterfaceName")
Libcore.resetAllConnections(true) LibcoreUtil.resetAllConnections(true)
} }
} }
} }

View File

@ -443,6 +443,7 @@ fun buildConfig(
// External proxy need a dokodemo-door inbound to forward the traffic // External proxy need a dokodemo-door inbound to forward the traffic
// For external proxy software, their traffic must goes to v2ray-core to use protected fd. // For external proxy software, their traffic must goes to v2ray-core to use protected fd.
bean.finalAddress = bean.serverAddress
bean.finalPort = bean.serverPort bean.finalPort = bean.serverPort
if (bean.canMapping() && proxyEntity.needExternal()) { if (bean.canMapping() && proxyEntity.needExternal()) {
// With ss protect, don't use mapping // With ss protect, don't use mapping

View File

@ -30,15 +30,24 @@ fun TuicBean.buildTuicConfig(port: Int, cacheFile: (() -> File)?): String {
fun TuicBean.buildTuicConfigV5(port: Int, cacheFile: (() -> File)?): JSONObject { fun TuicBean.buildTuicConfigV5(port: Int, cacheFile: (() -> File)?): JSONObject {
return JSONObject().apply { return JSONObject().apply {
put("relay", JSONObject().apply { put("relay", JSONObject().apply {
if (sni.isNotBlank() && !disableSNI) { var disableSNI2 = disableSNI
if (sni.isNotBlank()) { // domain + SNI
put("server", "$sni:$finalPort") put("server", "$sni:$finalPort")
if (finalAddress.isIpAddress()) { if (finalAddress.isIpAddress()) {
put("ip", finalAddress) put("ip", finalAddress)
} else { } else {
throw Exception("TUIC must use IP address when you need spoof SNI.") throw Exception("TUIC must use IP address when you need spoof SNI.")
} }
} else { } else if (!serverAddress.isIpAddress()) { // domain
put("server", serverAddress.wrapIPV6Host() + ":" + finalPort) put("server", "$serverAddress:$finalPort")
if (finalAddress.isIpAddress()) {
put("ip", finalAddress)
}
} else { // prue IP server
put("server", "example.com:$finalPort")
put("ip", finalAddress)
disableSNI2 = true
} }
put("uuid", uuid) put("uuid", uuid)
@ -55,7 +64,7 @@ fun TuicBean.buildTuicConfigV5(port: Int, cacheFile: (() -> File)?): JSONObject
put("alpn", JSONArray(alpn.split("\n"))) put("alpn", JSONArray(alpn.split("\n")))
} }
put("congestion_control", congestionController) put("congestion_control", congestionController)
put("disable_sni", disableSNI) put("disable_sni", disableSNI2)
put("zero_rtt_handshake", reduceRTT) put("zero_rtt_handshake", reduceRTT)
if (allowInsecure) put("allow_insecure", true) if (allowInsecure) put("allow_insecure", true)
}) })
@ -69,16 +78,26 @@ fun TuicBean.buildTuicConfigV5(port: Int, cacheFile: (() -> File)?): JSONObject
fun TuicBean.buildTuicConfigV4(port: Int, cacheFile: (() -> File)?): JSONObject { fun TuicBean.buildTuicConfigV4(port: Int, cacheFile: (() -> File)?): JSONObject {
return JSONObject().apply { return JSONObject().apply {
put("relay", JSONObject().apply { put("relay", JSONObject().apply {
if (sni.isNotBlank() && !disableSNI) { var disableSNI2 = disableSNI
put("server", sni)
if (sni.isNotBlank()) { // domain + SNI
put("server", "$sni:$finalPort")
if (finalAddress.isIpAddress()) { if (finalAddress.isIpAddress()) {
put("ip", finalAddress) put("ip", finalAddress)
} else { } else {
throw Exception("TUIC must use IP address when you need spoof SNI.") throw Exception("TUIC must use IP address when you need spoof SNI.")
} }
} else { } else if (!serverAddress.isIpAddress()) { // domain
put("server", finalAddress) put("server", "$serverAddress:$finalPort")
if (finalAddress.isIpAddress()) {
put("ip", finalAddress)
} }
} else { // prue IP server
put("server", "example.com:$finalPort")
put("ip", finalAddress)
disableSNI2 = true
}
put("port", finalPort) put("port", finalPort)
put("token", token) put("token", token)
@ -93,7 +112,7 @@ fun TuicBean.buildTuicConfigV4(port: Int, cacheFile: (() -> File)?): JSONObject
put("alpn", JSONArray(alpn.split("\n"))) put("alpn", JSONArray(alpn.split("\n")))
} }
put("congestion_controller", congestionController) put("congestion_controller", congestionController)
put("disable_sni", disableSNI) put("disable_sni", disableSNI2)
put("reduce_rtt", reduceRTT) put("reduce_rtt", reduceRTT)
put("max_udp_relay_packet_size", mtu) put("max_udp_relay_packet_size", mtu)
if (fastConnect) put("fast_connect", true) if (fastConnect) put("fast_connect", true)

View File

@ -502,10 +502,12 @@ object RawUpdater : GroupUpdater() {
"tuic" -> { "tuic" -> {
val bean = TuicBean() val bean = TuicBean()
var ip = ""
for (opt in proxy) { for (opt in proxy) {
when (opt.key.replace("_", "-")) { when (opt.key.replace("_", "-")) {
"name" -> bean.name = opt.value?.toString() "name" -> bean.name = opt.value?.toString()
"server" -> bean.serverAddress = opt.value as String "server" -> bean.serverAddress = opt.value.toString()
"ip" -> ip = opt.value.toString()
"port" -> bean.serverPort = opt.value.toString().toInt() "port" -> bean.serverPort = opt.value.toString().toInt()
"token" -> { "token" -> {
@ -536,6 +538,14 @@ object RawUpdater : GroupUpdater() {
"congestion-controller" -> bean.congestionController = "congestion-controller" -> bean.congestionController =
opt.value.toString() opt.value.toString()
"udp-relay-mode" -> bean.udpRelayMode = opt.value.toString()
}
}
if (ip.isNotBlank()) {
bean.serverAddress = ip
if (bean.sni.isNullOrBlank() && !bean.serverAddress.isNullOrBlank() && !bean.serverAddress.isIpAddress()) {
bean.sni = bean.serverAddress
} }
} }
proxies.add(bean) proxies.add(bean)

View File

@ -0,0 +1,18 @@
package moe.matsuri.nb4a.utils
import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.database.ProxyEntity
import io.nekohasekai.sagernet.database.SagerDatabase
import libcore.Libcore
object LibcoreUtil {
fun resetAllConnections(system: Boolean) {
if (DataStore.serviceState.started) {
val proxy = SagerDatabase.proxyDao.getById(DataStore.currentProfile)
if (proxy?.type == ProxyEntity.TYPE_TUIC) {
return
}
}
Libcore.resetAllConnections(system)
}
}