mirror of
https://github.com/MatsuriDayo/NekoBoxForAndroid.git
synced 2025-12-19 14:40:06 +08:00
optimize code
This commit is contained in:
parent
d0c68e38ef
commit
ad0dd1d63f
@ -6,8 +6,6 @@ import android.content.ClipData
|
|||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageInfo
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.Network
|
import android.net.Network
|
||||||
@ -20,27 +18,21 @@ import androidx.core.content.ContextCompat
|
|||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import go.Seq
|
import go.Seq
|
||||||
import io.nekohasekai.sagernet.bg.SagerConnection
|
import io.nekohasekai.sagernet.bg.SagerConnection
|
||||||
import io.nekohasekai.sagernet.bg.ServiceNotification
|
|
||||||
import io.nekohasekai.sagernet.database.DataStore
|
import io.nekohasekai.sagernet.database.DataStore
|
||||||
import io.nekohasekai.sagernet.database.SagerDatabase
|
|
||||||
import io.nekohasekai.sagernet.ktx.Logs
|
import io.nekohasekai.sagernet.ktx.Logs
|
||||||
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
|
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
|
||||||
import io.nekohasekai.sagernet.ui.MainActivity
|
import io.nekohasekai.sagernet.ui.MainActivity
|
||||||
import io.nekohasekai.sagernet.utils.*
|
import io.nekohasekai.sagernet.utils.*
|
||||||
import kotlinx.coroutines.DEBUG_PROPERTY_NAME
|
import kotlinx.coroutines.DEBUG_PROPERTY_NAME
|
||||||
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON
|
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON
|
||||||
import libcore.BoxPlatformInterface
|
|
||||||
import libcore.Libcore
|
import libcore.Libcore
|
||||||
import libcore.NB4AInterface
|
import moe.matsuri.nb4a.NativeInterface
|
||||||
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 androidx.work.Configuration as WorkConfiguration
|
import androidx.work.Configuration as WorkConfiguration
|
||||||
|
|
||||||
class SagerNet : Application(),
|
class SagerNet : Application(),
|
||||||
BoxPlatformInterface,
|
WorkConfiguration.Provider {
|
||||||
WorkConfiguration.Provider, NB4AInterface {
|
|
||||||
|
|
||||||
override fun attachBaseContext(base: Context) {
|
override fun attachBaseContext(base: Context) {
|
||||||
super.attachBaseContext(base)
|
super.attachBaseContext(base)
|
||||||
@ -48,6 +40,8 @@ class SagerNet : Application(),
|
|||||||
application = this
|
application = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val nativeInterface = NativeInterface()
|
||||||
|
|
||||||
val externalAssets by lazy { getExternalFilesDir(null) ?: filesDir }
|
val externalAssets by lazy { getExternalFilesDir(null) ?: filesDir }
|
||||||
val process = JavaUtil.getProcessName()
|
val process = JavaUtil.getProcessName()
|
||||||
val isMainProcess = process == BuildConfig.APPLICATION_ID
|
val isMainProcess = process == BuildConfig.APPLICATION_ID
|
||||||
@ -81,12 +75,9 @@ class SagerNet : Application(),
|
|||||||
externalAssets.absolutePath + "/",
|
externalAssets.absolutePath + "/",
|
||||||
DataStore.logBufSize,
|
DataStore.logBufSize,
|
||||||
DataStore.logLevel > 0,
|
DataStore.logLevel > 0,
|
||||||
this
|
nativeInterface, nativeInterface
|
||||||
)
|
)
|
||||||
|
|
||||||
// libbox: platform interface
|
|
||||||
Libcore.setBoxPlatformInterface(this)
|
|
||||||
|
|
||||||
if (isMainProcess) {
|
if (isMainProcess) {
|
||||||
Theme.apply(this)
|
Theme.apply(this)
|
||||||
Theme.applyNightTheme()
|
Theme.applyNightTheme()
|
||||||
@ -133,11 +124,6 @@ class SagerNet : Application(),
|
|||||||
uiMode.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION
|
uiMode.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION
|
||||||
}
|
}
|
||||||
|
|
||||||
// /data/user_de available when not unlocked
|
|
||||||
val deviceStorage by lazy {
|
|
||||||
if (Build.VERSION.SDK_INT < 24) application else DeviceStorageApp(application)
|
|
||||||
}
|
|
||||||
|
|
||||||
val configureIntent: (Context) -> PendingIntent by lazy {
|
val configureIntent: (Context) -> PendingIntent by lazy {
|
||||||
{
|
{
|
||||||
PendingIntent.getActivity(
|
PendingIntent.getActivity(
|
||||||
@ -209,82 +195,4 @@ class SagerNet : Application(),
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// libbox interface
|
|
||||||
|
|
||||||
override fun autoDetectInterfaceControl(fd: Int) {
|
|
||||||
DataStore.vpnService?.protect(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun openTun(singTunOptionsJson: String, tunPlatformOptionsJson: String): Long {
|
|
||||||
if (DataStore.vpnService == null) {
|
|
||||||
throw Exception("no VpnService")
|
|
||||||
}
|
|
||||||
return DataStore.vpnService!!.startVpn(singTunOptionsJson, tunPlatformOptionsJson).toLong()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun useProcFS(): Boolean {
|
|
||||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.Q)
|
|
||||||
override fun findConnectionOwner(
|
|
||||||
ipProto: Int, srcIp: String, srcPort: Int, destIp: String, destPort: Int
|
|
||||||
): Int {
|
|
||||||
return connectivity.getConnectionOwnerUid(
|
|
||||||
ipProto, InetSocketAddress(srcIp, srcPort), InetSocketAddress(destIp, destPort)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun packageNameByUid(uid: Int): String {
|
|
||||||
PackageCache.awaitLoadSync()
|
|
||||||
|
|
||||||
if (uid <= 1000L) {
|
|
||||||
return "android"
|
|
||||||
}
|
|
||||||
|
|
||||||
val packageNames = PackageCache.uidMap[uid]
|
|
||||||
if (!packageNames.isNullOrEmpty()) for (packageName in packageNames) {
|
|
||||||
return packageName
|
|
||||||
}
|
|
||||||
|
|
||||||
error("unknown uid $uid")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun uidByPackageName(packageName: String): Int {
|
|
||||||
PackageCache.awaitLoadSync()
|
|
||||||
return PackageCache[packageName] ?: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// nb4a interface
|
|
||||||
|
|
||||||
override fun useOfficialAssets(): Boolean {
|
|
||||||
return DataStore.rulesProvider == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun selector_OnProxySelected(selectorTag: String, tag: String) {
|
|
||||||
if (selectorTag != "proxy") {
|
|
||||||
Logs.d("other selector: $selectorTag")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
LibcoreUtil.resetAllConnections(true)
|
|
||||||
DataStore.baseService?.apply {
|
|
||||||
runOnDefaultDispatcher {
|
|
||||||
val id = data.proxy!!.config.profileTagMap
|
|
||||||
.filterValues { it == tag }.keys.firstOrNull() ?: -1
|
|
||||||
val ent = SagerDatabase.proxyDao.getById(id) ?: return@runOnDefaultDispatcher
|
|
||||||
// traffic & title
|
|
||||||
data.proxy?.apply {
|
|
||||||
looper?.selectMain(id)
|
|
||||||
displayProfileName = ServiceNotification.genTitle(ent)
|
|
||||||
data.notification?.postNotificationTitle(displayProfileName)
|
|
||||||
}
|
|
||||||
// post binder
|
|
||||||
data.binder.broadcast { b ->
|
|
||||||
b.cbSelectorUpdate(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package io.nekohasekai.sagernet.bg.proto
|
package io.nekohasekai.sagernet.bg.proto
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import io.nekohasekai.sagernet.SagerNet
|
import io.nekohasekai.sagernet.SagerNet
|
||||||
import io.nekohasekai.sagernet.bg.AbstractInstance
|
import io.nekohasekai.sagernet.bg.AbstractInstance
|
||||||
@ -117,10 +116,8 @@ abstract class BoxInstance(
|
|||||||
|
|
||||||
override fun launch() {
|
override fun launch() {
|
||||||
// TODO move, this is not box
|
// TODO move, this is not box
|
||||||
val context =
|
val cacheDir = File(SagerNet.application.cacheDir, "tmpcfg")
|
||||||
if (Build.VERSION.SDK_INT < 24 || SagerNet.user.isUserUnlocked) SagerNet.application else SagerNet.deviceStorage
|
cacheDir.mkdirs()
|
||||||
val cache = File(context.cacheDir, "tmpcfg")
|
|
||||||
cache.mkdirs()
|
|
||||||
|
|
||||||
for ((chain) in config.externalIndex) {
|
for ((chain) in config.externalIndex) {
|
||||||
chain.entries.forEachIndexed { index, (port, profile) ->
|
chain.entries.forEachIndexed { index, (port, profile) ->
|
||||||
@ -135,7 +132,7 @@ abstract class BoxInstance(
|
|||||||
|
|
||||||
bean is TrojanGoBean -> {
|
bean is TrojanGoBean -> {
|
||||||
val configFile = File(
|
val configFile = File(
|
||||||
cache, "trojan_go_" + SystemClock.elapsedRealtime() + ".json"
|
cacheDir, "trojan_go_" + SystemClock.elapsedRealtime() + ".json"
|
||||||
)
|
)
|
||||||
configFile.parentFile?.mkdirs()
|
configFile.parentFile?.mkdirs()
|
||||||
configFile.writeText(config)
|
configFile.writeText(config)
|
||||||
@ -150,7 +147,7 @@ abstract class BoxInstance(
|
|||||||
|
|
||||||
bean is NaiveBean -> {
|
bean is NaiveBean -> {
|
||||||
val configFile = File(
|
val configFile = File(
|
||||||
cache, "naive_" + SystemClock.elapsedRealtime() + ".json"
|
cacheDir, "naive_" + SystemClock.elapsedRealtime() + ".json"
|
||||||
)
|
)
|
||||||
|
|
||||||
configFile.parentFile?.mkdirs()
|
configFile.parentFile?.mkdirs()
|
||||||
@ -161,7 +158,7 @@ abstract class BoxInstance(
|
|||||||
|
|
||||||
if (bean.certificates.isNotBlank()) {
|
if (bean.certificates.isNotBlank()) {
|
||||||
val certFile = File(
|
val certFile = File(
|
||||||
cache, "naive_" + SystemClock.elapsedRealtime() + ".crt"
|
cacheDir, "naive_" + SystemClock.elapsedRealtime() + ".crt"
|
||||||
)
|
)
|
||||||
|
|
||||||
certFile.parentFile?.mkdirs()
|
certFile.parentFile?.mkdirs()
|
||||||
@ -180,7 +177,7 @@ abstract class BoxInstance(
|
|||||||
|
|
||||||
bean is HysteriaBean -> {
|
bean is HysteriaBean -> {
|
||||||
val configFile = File(
|
val configFile = File(
|
||||||
cache, "hysteria_" + SystemClock.elapsedRealtime() + ".json"
|
cacheDir, "hysteria_" + SystemClock.elapsedRealtime() + ".json"
|
||||||
)
|
)
|
||||||
|
|
||||||
configFile.parentFile?.mkdirs()
|
configFile.parentFile?.mkdirs()
|
||||||
@ -213,7 +210,7 @@ abstract class BoxInstance(
|
|||||||
any as JSONObject
|
any as JSONObject
|
||||||
|
|
||||||
val name = any.getString("name")
|
val name = any.getString("name")
|
||||||
val configFile = File(cache, name)
|
val configFile = File(cacheDir, name)
|
||||||
configFile.parentFile?.mkdirs()
|
configFile.parentFile?.mkdirs()
|
||||||
val content = any.getString("content")
|
val content = any.getString("content")
|
||||||
configFile.writeText(content)
|
configFile.writeText(content)
|
||||||
@ -243,10 +240,8 @@ abstract class BoxInstance(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bean is TuicBean -> {
|
bean is TuicBean -> {
|
||||||
val configFile = File(
|
val configFile =
|
||||||
context.noBackupFilesDir,
|
File(cacheDir, "tuic_" + SystemClock.elapsedRealtime() + ".json")
|
||||||
"tuic_" + SystemClock.elapsedRealtime() + ".json"
|
|
||||||
)
|
|
||||||
|
|
||||||
configFile.parentFile?.mkdirs()
|
configFile.parentFile?.mkdirs()
|
||||||
configFile.writeText(config)
|
configFile.writeText(config)
|
||||||
|
|||||||
@ -422,24 +422,22 @@ fun buildConfig(
|
|||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// domain_strategy
|
||||||
|
pastEntity?.requireBean()?.apply {
|
||||||
|
// don't loopback
|
||||||
|
if (currentDomainStrategy != "" && !serverAddress.isIpAddress()) {
|
||||||
|
domainListDNSDirectForce.add("full:$serverAddress")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentOutbound["domain_strategy"] = if (forTest) "" else currentDomainStrategy
|
||||||
|
|
||||||
// custom JSON merge
|
// custom JSON merge
|
||||||
if (bean.customOutboundJson.isNotBlank()) {
|
if (bean.customOutboundJson.isNotBlank()) {
|
||||||
Util.mergeJSON(bean.customOutboundJson, currentOutbound)
|
Util.mergeJSON(bean.customOutboundJson, currentOutbound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pastEntity?.requireBean()?.apply {
|
|
||||||
// don't loopback
|
|
||||||
if (currentDomainStrategy != "" && !serverAddress.isIpAddress()) {
|
|
||||||
domainListDNSDirectForce.add("full:$serverAddress")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (forTest) {
|
|
||||||
currentDomainStrategy = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
currentOutbound["tag"] = tagOut
|
currentOutbound["tag"] = tagOut
|
||||||
currentOutbound["domain_strategy"] = currentDomainStrategy
|
|
||||||
|
|
||||||
// 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.
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
package io.nekohasekai.sagernet.utils
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.app.Application
|
|
||||||
import android.content.Context
|
|
||||||
|
|
||||||
@SuppressLint("Registered")
|
|
||||||
@TargetApi(24)
|
|
||||||
class DeviceStorageApp(context: Context) : Application() {
|
|
||||||
init {
|
|
||||||
attachBaseContext(context.createDeviceProtectedStorageContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thou shalt not get the REAL underlying application context which would no longer be operating under device
|
|
||||||
* protected storage.
|
|
||||||
*/
|
|
||||||
override fun getApplicationContext() = this
|
|
||||||
}
|
|
||||||
96
app/src/main/java/moe/matsuri/nb4a/NativeInterface.kt
Normal file
96
app/src/main/java/moe/matsuri/nb4a/NativeInterface.kt
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package moe.matsuri.nb4a
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import io.nekohasekai.sagernet.SagerNet
|
||||||
|
import io.nekohasekai.sagernet.bg.ServiceNotification
|
||||||
|
import io.nekohasekai.sagernet.database.DataStore
|
||||||
|
import io.nekohasekai.sagernet.database.SagerDatabase
|
||||||
|
import io.nekohasekai.sagernet.ktx.Logs
|
||||||
|
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
|
||||||
|
import io.nekohasekai.sagernet.utils.PackageCache
|
||||||
|
import libcore.BoxPlatformInterface
|
||||||
|
import libcore.NB4AInterface
|
||||||
|
import moe.matsuri.nb4a.utils.LibcoreUtil
|
||||||
|
import java.net.InetSocketAddress
|
||||||
|
|
||||||
|
class NativeInterface : BoxPlatformInterface, NB4AInterface {
|
||||||
|
|
||||||
|
// libbox interface
|
||||||
|
|
||||||
|
override fun autoDetectInterfaceControl(fd: Int) {
|
||||||
|
DataStore.vpnService?.protect(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openTun(singTunOptionsJson: String, tunPlatformOptionsJson: String): Long {
|
||||||
|
if (DataStore.vpnService == null) {
|
||||||
|
throw Exception("no VpnService")
|
||||||
|
}
|
||||||
|
return DataStore.vpnService!!.startVpn(singTunOptionsJson, tunPlatformOptionsJson).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun useProcFS(): Boolean {
|
||||||
|
return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
override fun findConnectionOwner(
|
||||||
|
ipProto: Int, srcIp: String, srcPort: Int, destIp: String, destPort: Int
|
||||||
|
): Int {
|
||||||
|
return SagerNet.connectivity.getConnectionOwnerUid(
|
||||||
|
ipProto, InetSocketAddress(srcIp, srcPort), InetSocketAddress(destIp, destPort)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun packageNameByUid(uid: Int): String {
|
||||||
|
PackageCache.awaitLoadSync()
|
||||||
|
|
||||||
|
if (uid <= 1000L) {
|
||||||
|
return "android"
|
||||||
|
}
|
||||||
|
|
||||||
|
val packageNames = PackageCache.uidMap[uid]
|
||||||
|
if (!packageNames.isNullOrEmpty()) for (packageName in packageNames) {
|
||||||
|
return packageName
|
||||||
|
}
|
||||||
|
|
||||||
|
error("unknown uid $uid")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun uidByPackageName(packageName: String): Int {
|
||||||
|
PackageCache.awaitLoadSync()
|
||||||
|
return PackageCache[packageName] ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// nb4a interface
|
||||||
|
|
||||||
|
override fun useOfficialAssets(): Boolean {
|
||||||
|
return DataStore.rulesProvider == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun selector_OnProxySelected(selectorTag: String, tag: String) {
|
||||||
|
if (selectorTag != "proxy") {
|
||||||
|
Logs.d("other selector: $selectorTag")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
LibcoreUtil.resetAllConnections(true)
|
||||||
|
DataStore.baseService?.apply {
|
||||||
|
runOnDefaultDispatcher {
|
||||||
|
val id = data.proxy!!.config.profileTagMap
|
||||||
|
.filterValues { it == tag }.keys.firstOrNull() ?: -1
|
||||||
|
val ent = SagerDatabase.proxyDao.getById(id) ?: return@runOnDefaultDispatcher
|
||||||
|
// traffic & title
|
||||||
|
data.proxy?.apply {
|
||||||
|
looper?.selectMain(id)
|
||||||
|
displayProfileName = ServiceNotification.genTitle(ent)
|
||||||
|
data.notification?.postNotificationTitle(displayProfileName)
|
||||||
|
}
|
||||||
|
// post binder
|
||||||
|
data.binder.broadcast { b ->
|
||||||
|
b.cbSelectorUpdate(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
if [ ! -z $ENV_NB4A ]; then
|
if [ ! -z $ENV_NB4A ]; then
|
||||||
export COMMIT_SING_BOX_EXTRA="9400fd007ad5a19b5892a7c42aae0951e1163747"
|
export COMMIT_SING_BOX_EXTRA="3805838008319a97e4495f43e10a1d4c9c1e512a"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -z $ENV_SING_BOX_EXTRA ]; then
|
if [ ! -z $ENV_SING_BOX_EXTRA ]; then
|
||||||
|
|||||||
@ -21,13 +21,10 @@ func init() {
|
|||||||
D.RegisterTransport([]string{"underlying"}, createUnderlyingTransport)
|
D.RegisterTransport([]string{"underlying"}, createUnderlyingTransport)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateUnderlyingTransport for Android
|
|
||||||
func createUnderlyingTransport(name string, ctx context.Context, logger logger.ContextLogger, dialer N.Dialer, link string) (D.Transport, error) {
|
func createUnderlyingTransport(name string, ctx context.Context, logger logger.ContextLogger, dialer N.Dialer, link string) (D.Transport, error) {
|
||||||
return &androidUnderlyingTransportSing{name, underlyingResolver}, nil
|
return &androidUnderlyingTransportSing{name, underlyingResolver}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
type androidUnderlyingTransportSing struct {
|
type androidUnderlyingTransportSing struct {
|
||||||
name string
|
name string
|
||||||
*androidUnderlyingTransport
|
*androidUnderlyingTransport
|
||||||
@ -37,12 +34,10 @@ func (t *androidUnderlyingTransportSing) Name() string { return t.name }
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
var systemResolver = &net.Resolver{PreferGo: false} // Using System API, lookup from current network.
|
var systemResolver = &net.Resolver{PreferGo: false} // Using System API, lookup from current network.
|
||||||
var underlyingResolver = &androidUnderlyingTransport{systemResolver: systemResolver} // Using System API, lookup from non-VPN network.
|
var underlyingResolver = &androidUnderlyingTransport{} // Using System API, lookup from non-VPN network.
|
||||||
|
|
||||||
type androidUnderlyingTransport struct {
|
type androidUnderlyingTransport struct{}
|
||||||
systemResolver *net.Resolver
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *androidUnderlyingTransport) Start() error { return nil }
|
func (t *androidUnderlyingTransport) Start() error { return nil }
|
||||||
func (t *androidUnderlyingTransport) Close() error { return nil }
|
func (t *androidUnderlyingTransport) Close() error { return nil }
|
||||||
@ -96,7 +91,7 @@ func (t *androidUnderlyingTransport) Lookup(ctx context.Context, domain string,
|
|||||||
ips = append(ips, netip.MustParseAddr(ip))
|
ips = append(ips, netip.MustParseAddr(ip))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ips2, err2 := t.systemResolver.LookupIP(context.Background(), network, domain)
|
ips2, err2 := systemResolver.LookupIP(context.Background(), network, domain)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
err = err2
|
err = err2
|
||||||
return
|
return
|
||||||
|
|||||||
@ -32,19 +32,17 @@ func ForceGc() {
|
|||||||
go runtime.GC()
|
go runtime.GC()
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetLocalResolver(lr LocalResolver) {
|
|
||||||
localResolver = lr
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitCore(process, cachePath, internalAssets, externalAssets string,
|
func InitCore(process, cachePath, internalAssets, externalAssets string,
|
||||||
maxLogSizeKb int32, logEnable bool,
|
maxLogSizeKb int32, logEnable bool,
|
||||||
iif NB4AInterface,
|
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 = iif
|
intfNB4A = if1
|
||||||
|
intfBox = if2
|
||||||
|
useProcfs = intfBox.UseProcFS()
|
||||||
|
|
||||||
// Working dir
|
// Working dir
|
||||||
tmp := filepath.Join(cachePath, "../no_backup")
|
tmp := filepath.Join(cachePath, "../no_backup")
|
||||||
@ -64,7 +62,7 @@ func InitCore(process, cachePath, internalAssets, externalAssets string,
|
|||||||
boxmain.DisableColor()
|
boxmain.DisableColor()
|
||||||
|
|
||||||
// nekoutils
|
// nekoutils
|
||||||
nekoutils.Selector_OnProxySelected = iif.Selector_OnProxySelected
|
nekoutils.Selector_OnProxySelected = intfNB4A.Selector_OnProxySelected
|
||||||
|
|
||||||
// Set up some component
|
// Set up some component
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
@ -16,6 +16,10 @@ type LocalResolver interface {
|
|||||||
|
|
||||||
var localResolver LocalResolver // Android: passed from java (only when VPNService)
|
var localResolver LocalResolver // Android: passed from java (only when VPNService)
|
||||||
|
|
||||||
|
func SetLocalResolver(lr LocalResolver) {
|
||||||
|
localResolver = lr
|
||||||
|
}
|
||||||
|
|
||||||
type BoxPlatformInterface interface {
|
type BoxPlatformInterface interface {
|
||||||
AutoDetectInterfaceControl(fd int32) error
|
AutoDetectInterfaceControl(fd int32) error
|
||||||
OpenTun(singTunOptionsJson, tunPlatformOptionsJson string) (int, error)
|
OpenTun(singTunOptionsJson, tunPlatformOptionsJson string) (int, error)
|
||||||
@ -24,8 +28,3 @@ type BoxPlatformInterface interface {
|
|||||||
PackageNameByUid(uid int32) (string, error)
|
PackageNameByUid(uid int32) (string, error)
|
||||||
UIDByPackageName(packageName string) (int32, error)
|
UIDByPackageName(packageName string) (int32, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetBoxPlatformInterface(iif BoxPlatformInterface) {
|
|
||||||
intfBox = iif
|
|
||||||
useProcfs = intfBox.UseProcFS()
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user