mirror of
https://github.com/MatsuriDayo/NekoBoxForAndroid.git
synced 2025-12-19 06:30:05 +08:00
No need to disconnect VPN when running URLTest
This commit is contained in:
parent
573ad36fea
commit
4752f8e39d
@ -12,7 +12,7 @@ import kotlinx.coroutines.delay
|
|||||||
import libcore.Libcore
|
import libcore.Libcore
|
||||||
import kotlin.coroutines.suspendCoroutine
|
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) {
|
BoxInstance(profile) {
|
||||||
|
|
||||||
suspend fun doTest(): Int {
|
suspend fun doTest(): Int {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import io.nekohasekai.sagernet.database.ProxyEntity
|
|||||||
class UrlTest {
|
class UrlTest {
|
||||||
|
|
||||||
val link = DataStore.connectionTestURL
|
val link = DataStore.connectionTestURL
|
||||||
val timeout = 3000
|
private val timeout = 5000
|
||||||
|
|
||||||
suspend fun doTest(profile: ProxyEntity): Int {
|
suspend fun doTest(profile: ProxyEntity): Int {
|
||||||
return TestInstance(profile, link, timeout).doTest()
|
return TestInstance(profile, link, timeout).doTest()
|
||||||
|
|||||||
@ -182,12 +182,6 @@ fun buildConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
dns = DNSOptions().apply {
|
dns = DNSOptions().apply {
|
||||||
// TODO nb4a hosts?
|
|
||||||
// hosts = DataStore.hosts.split("\n")
|
|
||||||
// .filter { it.isNotBlank() }
|
|
||||||
// .associate { it.substringBefore(" ") to it.substringAfter(" ") }
|
|
||||||
// .toMutableMap()
|
|
||||||
|
|
||||||
servers = mutableListOf()
|
servers = mutableListOf()
|
||||||
rules = mutableListOf()
|
rules = mutableListOf()
|
||||||
independent_cache = true
|
independent_cache = true
|
||||||
@ -665,7 +659,8 @@ fun buildConfig(
|
|||||||
|
|
||||||
// remote dns obj
|
// remote dns obj
|
||||||
remoteDns.firstOrNull().let {
|
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!")
|
address = it ?: throw Exception("No remote DNS, check your settings!")
|
||||||
tag = "dns-remote"
|
tag = "dns-remote"
|
||||||
address_resolver = "dns-direct"
|
address_resolver = "dns-direct"
|
||||||
@ -701,8 +696,6 @@ fun buildConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (forTest) {
|
if (forTest) {
|
||||||
// Always use direct DNS for urlTest
|
|
||||||
dns.servers.removeAt(0)
|
|
||||||
dns.rules = listOf()
|
dns.rules = listOf()
|
||||||
} else {
|
} else {
|
||||||
// built-in DNS rules
|
// built-in DNS rules
|
||||||
|
|||||||
@ -821,10 +821,6 @@ class ConfigurationFragment @JvmOverloads constructor(
|
|||||||
val testJobs = mutableListOf<Job>()
|
val testJobs = mutableListOf<Job>()
|
||||||
|
|
||||||
val mainJob = runOnDefaultDispatcher {
|
val mainJob = runOnDefaultDispatcher {
|
||||||
if (DataStore.serviceState.started) {
|
|
||||||
stopService()
|
|
||||||
delay(500) // wait for service stop
|
|
||||||
}
|
|
||||||
val group = DataStore.currentGroup()
|
val group = DataStore.currentGroup()
|
||||||
val profilesUnfiltered = SagerDatabase.proxyDao.getByGroup(group.id)
|
val profilesUnfiltered = SagerDatabase.proxyDao.getByGroup(group.id)
|
||||||
test.proxyN = profilesUnfiltered.size
|
test.proxyN = profilesUnfiltered.size
|
||||||
|
|||||||
@ -14,6 +14,7 @@ require (
|
|||||||
github.com/sagernet/sing-tun v0.6.1
|
github.com/sagernet/sing-tun v0.6.1
|
||||||
github.com/ulikunitz/xz v0.5.11
|
github.com/ulikunitz/xz v0.5.11
|
||||||
golang.org/x/mobile v0.0.0-20231108233038-35478a0c49da
|
golang.org/x/mobile v0.0.0-20231108233038-35478a0c49da
|
||||||
|
golang.org/x/sys v0.30.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@ -78,7 +79,6 @@ require (
|
|||||||
golang.org/x/mod v0.20.0 // indirect
|
golang.org/x/mod v0.20.0 // indirect
|
||||||
golang.org/x/net v0.34.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
golang.org/x/sync v0.10.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/text v0.21.0 // indirect
|
||||||
golang.org/x/time v0.7.0 // indirect
|
golang.org/x/time v0.7.0 // indirect
|
||||||
golang.org/x/tools v0.24.0 // indirect
|
golang.org/x/tools v0.24.0 // indirect
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package libcore
|
package libcore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"libcore/device"
|
"libcore/device"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -13,11 +14,14 @@ import (
|
|||||||
"github.com/matsuridayo/libneko/neko_common"
|
"github.com/matsuridayo/libneko/neko_common"
|
||||||
"github.com/matsuridayo/libneko/neko_log"
|
"github.com/matsuridayo/libneko/neko_log"
|
||||||
"github.com/sagernet/sing-box/nekoutils"
|
"github.com/sagernet/sing-box/nekoutils"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname resourcePaths github.com/sagernet/sing-box/constant.resourcePaths
|
//go:linkname resourcePaths github.com/sagernet/sing-box/constant.resourcePaths
|
||||||
var resourcePaths []string
|
var resourcePaths []string
|
||||||
|
|
||||||
|
var isBgProcess bool
|
||||||
|
|
||||||
func NekoLogPrintln(s string) {
|
func NekoLogPrintln(s string) {
|
||||||
log.Println(s)
|
log.Println(s)
|
||||||
}
|
}
|
||||||
@ -35,7 +39,7 @@ func InitCore(process, cachePath, internalAssets, externalAssets string,
|
|||||||
if1 NB4AInterface, if2 BoxPlatformInterface,
|
if1 NB4AInterface, if2 BoxPlatformInterface,
|
||||||
) {
|
) {
|
||||||
defer device.DeferPanicToError("InitCore", func(err error) { log.Println(err) })
|
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
|
neko_common.RunMode = neko_common.RunMode_NekoBoxForAndroid
|
||||||
intfNB4A = if1
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -44,7 +44,12 @@ func (w *boxPlatformInterfaceWrapper) UsePlatformAutoDetectInterfaceControl() bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *boxPlatformInterfaceWrapper) AutoDetectInterfaceControl(fd int) error {
|
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))
|
return intfBox.AutoDetectInterfaceControl(int32(fd))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user