From 717872ef6d233637fce536b14359037e2911e1ef Mon Sep 17 00:00:00 2001 From: HystericalDragon Date: Tue, 1 Oct 2024 12:08:34 +0800 Subject: [PATCH 1/2] feat: add anchor, a protocol to share proxy in Lan Signed-off-by: HystericalDragon --- .../java/io/nekohasekai/sagernet/Constants.kt | 1 + .../sagernet/bg/NativeInterface.kt | 4 + .../sagernet/database/DataStore.kt | 1 + .../sagernet/ui/SettingsPreferenceFragment.kt | 13 ++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/global_preferences.xml | 4 + libcore/anchor/option.go | 12 ++ libcore/anchor/service.go | 120 ++++++++++++++++++ libcore/box.go | 30 +++++ libcore/go.mod | 1 + libcore/go.sum | 2 + libcore/platform_java.go | 1 + 13 files changed, 191 insertions(+) create mode 100644 libcore/anchor/option.go create mode 100644 libcore/anchor/service.go 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) } From f70887f0ac8026193a45b46e4ede59f132cdfbf3 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 16:43:52 +0800 Subject: [PATCH 2/2] Fix break loop --- libcore/box.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libcore/box.go b/libcore/box.go index 2cf7d5a9..bd96e1ef 100644 --- a/libcore/box.go +++ b/libcore/box.go @@ -114,12 +114,13 @@ func NewBoxInstance(config string, platformInterface PlatformInterface) (b *BoxI if platformInterface.AllowDiscoveryByLan() { var anchorOptions anchor.Options + Find: for _, inbound := range options.Inbounds { switch inbound.Type { case C.TypeMixed: listen := (*netip.Addr)(inbound.MixedOptions.Listen) if !listen.IsUnspecified() { - break + break Find } anchorOptions.SocksPort = inbound.MixedOptions.ListenPort if len(inbound.MixedOptions.Users) > 0 {