diff --git a/app/src/main/java/io/nekohasekai/sagernet/Constants.kt b/app/src/main/java/io/nekohasekai/sagernet/Constants.kt
index 4290737d..b4becb35 100644
--- a/app/src/main/java/io/nekohasekai/sagernet/Constants.kt
+++ b/app/src/main/java/io/nekohasekai/sagernet/Constants.kt
@@ -49,6 +49,7 @@ object Key {
const val MIXED_PORT = "mixedPort"
const val ALLOW_ACCESS = "allowAccess"
+ const val DISCOVERY_IN_LAN = "discoveryInLan"
const val SPEED_INTERVAL = "speedInterval"
const val SHOW_DIRECT_SPEED = "showDirectSpeed"
const val LOCAL_DNS_PORT = "portLocalDns"
diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/NativeInterface.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/NativeInterface.kt
index bb30849e..49281cdb 100644
--- a/app/src/main/java/io/nekohasekai/sagernet/bg/NativeInterface.kt
+++ b/app/src/main/java/io/nekohasekai/sagernet/bg/NativeInterface.kt
@@ -164,4 +164,8 @@ class NativeInterface : PlatformInterface {
return SDK_INT >= Build.VERSION_CODES.R // SDK 30 (Android 11)
}
+ override fun allowDiscoveryByLan(): Boolean {
+ return DataStore.discoveryInLan
+ }
+
}
diff --git a/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt b/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt
index 72858134..999f7b70 100644
--- a/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt
+++ b/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt
@@ -112,6 +112,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
var inboundPassword by configurationStore.string(Key.INBOUND_PASSWORD) { "" }
var allowAccess by configurationStore.boolean(Key.ALLOW_ACCESS)
+ var discoveryInLan by configurationStore.boolean(Key.DISCOVERY_IN_LAN)
var speedInterval by configurationStore.stringToInt(Key.SPEED_INTERVAL)
var showGroupInNotification by configurationStore.boolean("showGroupInNotification")
diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt
index e649d75e..b4fc2880 100644
--- a/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt
+++ b/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt
@@ -64,6 +64,9 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
lateinit var bypassLan: SwitchPreference
lateinit var bypassLanInCore: SwitchPreference
+ lateinit var allowAccess: SwitchPreference
+ lateinit var discoveryInLan: SwitchPreference
+
lateinit var logLevel: LongClickListPreference
lateinit var alwaysShowAddress: SwitchPreference
lateinit var blurredAddress: SwitchPreference
@@ -177,6 +180,8 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
Key.INBOUND_SETTINGS -> preferenceCategory.forEach { preference ->
when (preference.key) {
Key.MIXED_PORT, Key.LOCAL_DNS_PORT -> (preference as EditTextPreference).setPortEdit()
+ Key.ALLOW_ACCESS -> allowAccess = preference as SwitchPreference
+ Key.DISCOVERY_IN_LAN -> discoveryInLan = preference as SwitchPreference
else -> preference.onPreferenceChangeListener = reloadListener
}
}
@@ -275,6 +280,14 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
true
}
+ discoveryInLan.isEnabled = bypassLan.isChecked
+ discoveryInLan.onPreferenceChangeListener = reloadListener
+ allowAccess.setOnPreferenceChangeListener { _, newValue ->
+ discoveryInLan.isEnabled = newValue as Boolean
+ needReload()
+ true
+ }
+
blurredAddress.isEnabled = alwaysShowAddress.isChecked
alwaysShowAddress.setOnPreferenceChangeListener { _, newValue ->
blurredAddress.isEnabled = newValue as Boolean
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 8deba375..d1a92f65 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -588,4 +588,5 @@
覆写端口
允许应用绕过 VPN
Clash 模式
+ 允许局域网发现
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 006aad86..690a7159 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -655,4 +655,5 @@
Override Port
Allow Apps to bypass VPN
Clash Mode
+ Enable Local Network Discovery
\ No newline at end of file
diff --git a/app/src/main/res/xml/global_preferences.xml b/app/src/main/res/xml/global_preferences.xml
index 17193179..0ee3b2ab 100644
--- a/app/src/main/res/xml/global_preferences.xml
+++ b/app/src/main/res/xml/global_preferences.xml
@@ -267,6 +267,10 @@
app:key="allowAccess"
app:summary="@string/allow_access_sum"
app:title="@string/allow_access" />
+
0 {
+ anchorOptions.User = inbound.MixedOptions.Users[0]
+ }
+ case C.TypeDirect:
+ if inbound.Tag != "dns-in" {
+ continue
+ }
+ anchorOptions.DnsPort = inbound.DirectOptions.OverridePort
+ }
+ }
+ anchorServer, err := anchor.New(ctx, log.StdLogger(), anchorOptions)
+ if err != nil {
+ log.WarnContext(ctx, "create anchor service: ", err)
+ } else {
+ b.services = append(b.services, anchorServer)
+ }
+ }
+
// Protect
protectServer, err := protect.New(ctx, log.StdLogger(), ProtectPath, func(fd int) error {
return platformInterface.AutoDetectInterfaceControl(int32(fd))
diff --git a/libcore/go.mod b/libcore/go.mod
index 361e8811..44373f5f 100644
--- a/libcore/go.mod
+++ b/libcore/go.mod
@@ -12,6 +12,7 @@ require (
github.com/sagernet/sing-dns v0.3.0-beta.14
github.com/sagernet/sing-tun v0.4.0-beta.16
github.com/xchacha20-poly1305/TLS-scribe v0.6.1
+ github.com/xchacha20-poly1305/anchor v0.2.0-beta.0
github.com/xchacha20-poly1305/cazilla v0.3.3
github.com/xchacha20-poly1305/libping v0.7.1
golang.org/x/crypto v0.27.0
diff --git a/libcore/go.sum b/libcore/go.sum
index 797d6c50..85767a1f 100644
--- a/libcore/go.sum
+++ b/libcore/go.sum
@@ -154,6 +154,8 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/xchacha20-poly1305/TLS-scribe v0.6.1 h1:eMe562VUOSjoumbom/XS1O5mw0A3/QOKPyLgwAjVDgo=
github.com/xchacha20-poly1305/TLS-scribe v0.6.1/go.mod h1:2suBWLi3ESUbkp97tMz1okYK6Dh9XpjRzyO7eMA5s6Q=
+github.com/xchacha20-poly1305/anchor v0.2.0-beta.0 h1:qic4oHg2TNeOaRSyDIPkeEDqAXzgITjiR01FIFhqm18=
+github.com/xchacha20-poly1305/anchor v0.2.0-beta.0/go.mod h1:/QUPDmgmJ0q7m5vuPte9Bve9vXLS/SNophSntKuCrX4=
github.com/xchacha20-poly1305/cazilla v0.3.3 h1:9qKZHKexlzGHmXeAHVOwj0dnc9/WEftGSwwWC3703wM=
github.com/xchacha20-poly1305/cazilla v0.3.3/go.mod h1:CRNqqSLuWw8gStu7qDwjPYmsLE91OCVWazN9AH4LyWc=
github.com/xchacha20-poly1305/libping v0.7.1 h1:MQkq6gxn67SZlBgG2Wp7ek0QYQsxKnKSbg0h235S6+o=
diff --git a/libcore/platform_java.go b/libcore/platform_java.go
index 3e2820d1..3a3aed91 100644
--- a/libcore/platform_java.go
+++ b/libcore/platform_java.go
@@ -14,6 +14,7 @@ type PlatformInterface interface {
GetInterfaces() (NetworkInterfaceIterator, error)
UsePlatformInterfaceGetter() bool
+ AllowDiscoveryByLan() bool
SelectorCallback(tag string)
ClashModeCallback(mode string)
}