No need to disconnect VPN when running URLTest

This commit is contained in:
armv9 2025-02-26 14:14:24 +09:00
parent 573ad36fea
commit 4752f8e39d
7 changed files with 50 additions and 18 deletions

View File

@ -12,7 +12,7 @@ import kotlinx.coroutines.delay
import libcore.Libcore
import kotlin.coroutines.suspendCoroutine
class TestInstance(profile: ProxyEntity, val link: String, val timeout: Int) :
class TestInstance(profile: ProxyEntity, val link: String, private val timeout: Int) :
BoxInstance(profile) {
suspend fun doTest(): Int {

View File

@ -6,7 +6,7 @@ import io.nekohasekai.sagernet.database.ProxyEntity
class UrlTest {
val link = DataStore.connectionTestURL
val timeout = 3000
private val timeout = 5000
suspend fun doTest(profile: ProxyEntity): Int {
return TestInstance(profile, link, timeout).doTest()

View File

@ -182,12 +182,6 @@ fun buildConfig(
}
dns = DNSOptions().apply {
// TODO nb4a hosts?
// hosts = DataStore.hosts.split("\n")
// .filter { it.isNotBlank() }
// .associate { it.substringBefore(" ") to it.substringAfter(" ") }
// .toMutableMap()
servers = mutableListOf()
rules = mutableListOf()
independent_cache = true
@ -665,7 +659,8 @@ fun buildConfig(
// remote dns obj
remoteDns.firstOrNull().let {
dns.servers.add(DNSServerOptions().apply {
// Always use direct DNS for urlTest
if (!forTest) dns.servers.add(DNSServerOptions().apply {
address = it ?: throw Exception("No remote DNS, check your settings!")
tag = "dns-remote"
address_resolver = "dns-direct"
@ -701,8 +696,6 @@ fun buildConfig(
}
if (forTest) {
// Always use direct DNS for urlTest
dns.servers.removeAt(0)
dns.rules = listOf()
} else {
// built-in DNS rules

View File

@ -821,10 +821,6 @@ class ConfigurationFragment @JvmOverloads constructor(
val testJobs = mutableListOf<Job>()
val mainJob = runOnDefaultDispatcher {
if (DataStore.serviceState.started) {
stopService()
delay(500) // wait for service stop
}
val group = DataStore.currentGroup()
val profilesUnfiltered = SagerDatabase.proxyDao.getByGroup(group.id)
test.proxyN = profilesUnfiltered.size

View File

@ -14,6 +14,7 @@ require (
github.com/sagernet/sing-tun v0.6.1
github.com/ulikunitz/xz v0.5.11
golang.org/x/mobile v0.0.0-20231108233038-35478a0c49da
golang.org/x/sys v0.30.0
)
require (
@ -78,7 +79,6 @@ require (
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.24.0 // indirect

View File

@ -1,6 +1,7 @@
package libcore
import (
"fmt"
"libcore/device"
"os"
"path/filepath"
@ -13,11 +14,14 @@ import (
"github.com/matsuridayo/libneko/neko_common"
"github.com/matsuridayo/libneko/neko_log"
"github.com/sagernet/sing-box/nekoutils"
"golang.org/x/sys/unix"
)
//go:linkname resourcePaths github.com/sagernet/sing-box/constant.resourcePaths
var resourcePaths []string
var isBgProcess bool
func NekoLogPrintln(s string) {
log.Println(s)
}
@ -35,7 +39,7 @@ func InitCore(process, cachePath, internalAssets, externalAssets string,
if1 NB4AInterface, if2 BoxPlatformInterface,
) {
defer device.DeferPanicToError("InitCore", func(err error) { log.Println(err) })
isBgProcess := strings.HasSuffix(process, ":bg")
isBgProcess = strings.HasSuffix(process, ":bg")
neko_common.RunMode = neko_common.RunMode_NekoBoxForAndroid
intfNB4A = if1
@ -81,3 +85,37 @@ func InitCore(process, cachePath, internalAssets, externalAssets string,
}
}()
}
func sendFdToProtect(fd int, path string) error {
socketFd, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0)
if err != nil {
return fmt.Errorf("failed to create unix socket: %w", err)
}
defer unix.Close(socketFd)
var timeout unix.Timeval
timeout.Usec = 100 * 1000
_ = unix.SetsockoptTimeval(socketFd, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &timeout)
_ = unix.SetsockoptTimeval(socketFd, unix.SOL_SOCKET, unix.SO_SNDTIMEO, &timeout)
err = unix.Connect(socketFd, &unix.SockaddrUnix{Name: path})
if err != nil {
return fmt.Errorf("failed to connect: %w", err)
}
err = unix.Sendmsg(socketFd, nil, unix.UnixRights(fd), nil, 0)
if err != nil {
return fmt.Errorf("failed to send: %w", err)
}
dummy := []byte{1}
n, err := unix.Read(socketFd, dummy)
if err != nil {
return fmt.Errorf("failed to receive: %w", err)
}
if n != 1 {
return fmt.Errorf("socket closed unexpectedly")
}
return nil
}

View File

@ -44,7 +44,12 @@ func (w *boxPlatformInterfaceWrapper) UsePlatformAutoDetectInterfaceControl() bo
}
func (w *boxPlatformInterfaceWrapper) AutoDetectInterfaceControl(fd int) error {
// "protect"
// call protect_path
if !isBgProcess {
_ = sendFdToProtect(fd, "protect_path")
return nil
}
// bg process call VPNService
return intfBox.AutoDetectInterfaceControl(int32(fd))
}