Compare commits

..

109 Commits

Author SHA1 Message Date
世界
ccceb8b30a
documentation: Bump version 2025-06-17 14:27:11 +08:00
世界
778f9ef81f
Add API to dump AdGuard rules 2025-06-17 14:26:50 +08:00
Sukka
0c5947e1e3
Improve AdGuard rule-set parser 2025-06-17 14:26:50 +08:00
Restia-Ashbell
e268f53c87
Add ECH support for uTLS 2025-06-17 14:26:50 +08:00
世界
8505fc8352
Improve TLS fragments 2025-06-17 14:26:50 +08:00
世界
8c4298fd90
Add cache support for ssm-api 2025-06-17 14:26:50 +08:00
世界
e3f6d827bd
Fix service will not be closed 2025-06-17 14:26:50 +08:00
世界
3f78bf5b93
Add loopback address support for tun 2025-06-17 14:26:49 +08:00
世界
91f4ab15e9
documentation: Bump version 2025-06-17 14:26:49 +08:00
世界
663da9d605
release: Update Go to 1.24.4 2025-06-17 14:26:49 +08:00
世界
0c53d6fe4c
Fix tproxy listener 2025-06-17 14:26:49 +08:00
世界
63760e7f53
Fix systemd package 2025-06-17 14:26:49 +08:00
世界
d7936ad3a0
Fix missing home for derp service 2025-06-17 14:26:49 +08:00
Zero Clover
e2e36e0d9e
documentation: Fix services 2025-06-17 14:26:49 +08:00
世界
47b77b2cc0
Fix dns.client_subnet ignored 2025-06-17 14:26:49 +08:00
世界
8982765024
documentation: Minor fixes 2025-06-17 14:26:49 +08:00
世界
93dbcbdb47
Fix tailscale forward 2025-06-17 14:26:48 +08:00
世界
46a45af787
Minor fixes 2025-06-17 14:26:48 +08:00
世界
d3f7f2aaef
Add SSM API service 2025-06-17 14:26:48 +08:00
世界
e617f7ac2d
Add resolved service and DNS server 2025-06-17 14:26:47 +08:00
世界
213ad2f3c1
Add DERP service 2025-06-17 14:26:47 +08:00
世界
83ca997dd3
Add service component type 2025-06-17 14:26:47 +08:00
世界
bf2963da47
Fix tproxy tcp control 2025-06-17 14:26:47 +08:00
愚者
d0108ef0d7
release: Fix build tags for android
Signed-off-by: 愚者 <11926619+FansChou@users.noreply.github.com>
2025-06-17 14:26:47 +08:00
世界
6c559b5df1
prevent creation of bind and mark controls on unsupported platforms 2025-06-17 14:26:46 +08:00
PuerNya
4c2eaf624c
documentation: Fix description of reject DNS action behavior 2025-06-17 14:26:46 +08:00
Restia-Ashbell
819c2b46c4
Fix TLS record fragment 2025-06-17 14:26:46 +08:00
世界
5b34431612
Add missing accept_routes option for Tailscale 2025-06-17 14:26:45 +08:00
世界
d0e5d145f2
Add TLS record fragment support 2025-06-17 14:26:45 +08:00
世界
7a219c4613
Fix set edns0 client subnet 2025-06-17 14:26:45 +08:00
世界
1a4827a292
Update minor dependencies 2025-06-17 14:26:45 +08:00
世界
4f665ca82e
Update certmagic and providers 2025-06-17 14:26:45 +08:00
世界
37297190da
Update protobuf and grpc 2025-06-17 14:26:45 +08:00
世界
105101fa0b
Add control options for listeners 2025-06-17 14:26:45 +08:00
世界
58c2f6f2cb
Update quic-go to v0.52.0 2025-06-17 14:26:44 +08:00
世界
5cf1b601b4
Update utls to v1.7.2 2025-06-17 14:26:44 +08:00
世界
cd46c5323a
Handle EDNS version downgrade 2025-06-17 14:26:35 +08:00
世界
6c128dc213
documentation: Fix anytls padding scheme description 2025-06-17 14:26:35 +08:00
安容
c0e374451d
Report invalid DNS address early 2025-06-17 14:26:35 +08:00
世界
2f1a618390
Fix wireguard listen_port 2025-06-17 14:26:35 +08:00
世界
b0206c1337
clash-api: Add more meta api 2025-06-17 14:26:34 +08:00
世界
07b955c305
Fix DNS lookup 2025-06-17 14:26:34 +08:00
世界
442f96e509
Fix fetch ECH configs 2025-06-17 14:26:34 +08:00
reletor
2ae7c0964c
documentation: Minor fixes 2025-06-17 14:26:34 +08:00
caelansar
2afe76b3fd
Fix callback deletion in UDP transport 2025-06-17 14:26:34 +08:00
世界
6017820c82
documentation: Try to make the play review happy 2025-06-17 14:26:34 +08:00
世界
d2b136ed98
Fix missing handling of legacy domain_strategy options 2025-06-17 14:26:34 +08:00
世界
11c23a30a4
Improve local DNS server 2025-06-17 14:26:33 +08:00
anytls
d1a405cea0
Update anytls
Co-authored-by: anytls <anytls>
2025-06-17 14:25:23 +08:00
世界
194c890f7a
Fix DNS dialer 2025-06-17 14:25:23 +08:00
世界
c2518597d5
release: Skip override version for iOS 2025-06-17 14:25:23 +08:00
iikira
41e2cb5be4
Fix UDP DNS server crash
Signed-off-by: iikira <i2@mail.iikira.com>
2025-06-17 14:25:22 +08:00
ReleTor
41699a35f1
Fix fetch ECH configs 2025-06-17 14:25:22 +08:00
世界
9802c6a930
Allow direct outbounds without domain_resolver 2025-06-17 14:25:22 +08:00
世界
2450dec60e
Fix Tailscale dialer 2025-06-17 14:25:22 +08:00
dyhkwong
5d7c093158
Fix DNS over QUIC stream close 2025-06-17 14:25:21 +08:00
anytls
6de9da225a
Update anytls
Co-authored-by: anytls <anytls>
2025-06-17 14:25:21 +08:00
Rambling2076
4f9b09e82a
Fix missing with_tailscale in Dockerfile
Signed-off-by: Rambling2076 <Rambling2076@proton.me>
2025-06-17 14:25:21 +08:00
世界
bf556b1209
Fail when default DNS server not found 2025-06-17 14:25:20 +08:00
世界
34cd7f9634
Update gVisor to 20250319.0 2025-06-17 14:25:20 +08:00
世界
a6686075b1
Explicitly reject detour to empty direct outbounds 2025-06-17 14:25:20 +08:00
世界
0d6ae99f33
Add netns support 2025-06-17 14:25:19 +08:00
世界
dac7028377
Add wildcard name support for predefined records 2025-06-17 14:25:19 +08:00
世界
09e8f7a4ef
Remove map usage in options 2025-06-17 14:25:19 +08:00
世界
4ee3b46e52
Fix unhandled DNS loop 2025-06-17 14:25:19 +08:00
世界
69f86934fc
Add wildcard-sni support for shadow-tls inbound 2025-06-17 14:25:19 +08:00
k9982874
c64fb04fc9
Add ntp protocol sniffing 2025-06-17 14:25:09 +08:00
世界
689f3b6b10
option: Fix marshal legacy DNS options 2025-06-17 14:25:09 +08:00
世界
83aecd3605
Make domain_resolver optional when only one DNS server is configured 2025-06-17 14:25:09 +08:00
世界
6d2d9a58c6
Fix DNS lookup context pollution 2025-06-17 14:25:08 +08:00
世界
78488015c2
Fix http3 DNS server connecting to wrong address 2025-06-17 14:25:08 +08:00
Restia-Ashbell
ea3e5bf5e2
documentation: Fix typo 2025-06-17 14:25:08 +08:00
anytls
16da80db87
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-06-17 14:25:07 +08:00
k9982874
76e16f8a05
Fix hosts DNS server 2025-06-17 14:25:07 +08:00
世界
da25171807
Fix UDP DNS server crash 2025-06-17 14:25:06 +08:00
世界
afe870e530
documentation: Fix missing ip_accept_any DNS rule option 2025-06-17 14:25:06 +08:00
世界
434b81ecf0
Fix anytls dialer usage 2025-06-17 14:25:06 +08:00
世界
f204231a76
Move predefined DNS server to rule action 2025-06-17 14:25:05 +08:00
世界
b032700526
Fix domain resolver on direct outbound 2025-06-17 14:25:05 +08:00
Zephyruso
9514219058
Fix missing AnyTLS display name 2025-06-17 14:25:05 +08:00
anytls
2610949d7d
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-06-17 14:25:04 +08:00
Estel
241f5ec390
documentation: Fix typo
Signed-off-by: Estel <callmebedrockdigger@gmail.com>
2025-06-17 14:25:04 +08:00
TargetLocked
a277fa1020
Fix parsing legacy DNS options 2025-06-17 14:25:04 +08:00
世界
67ab67975f
Fix DNS fallback 2025-06-17 14:25:04 +08:00
世界
3665723c66
documentation: Fix missing hosts DNS server 2025-06-17 14:25:03 +08:00
anytls
5253490bde
Add MinIdleSession option to AnyTLS outbound
Co-authored-by: anytls <anytls>
2025-06-17 14:25:03 +08:00
ReleTor
46d40e6370
documentation: Minor fixes 2025-06-17 14:25:03 +08:00
libtry486
1b544afc62
documentation: Fix typo
fix typo

Signed-off-by: libtry486 <89328481+libtry486@users.noreply.github.com>
2025-06-17 14:25:03 +08:00
Alireza Ahmadi
9d5bc110ac
Fix Outbound deadlock 2025-06-17 14:25:02 +08:00
世界
71927fc02b
documentation: Fix AnyTLS doc 2025-06-17 14:25:02 +08:00
anytls
02885d2c0a
Add AnyTLS protocol 2025-06-17 14:25:01 +08:00
世界
3fb5d84542
Migrate to stdlib ECH support 2025-06-17 14:25:01 +08:00
世界
bf36e62560
Add fallback local DNS server for iOS 2025-06-17 14:25:01 +08:00
世界
ffd8ce99f0
Get darwin local DNS server from libresolv 2025-06-17 14:25:01 +08:00
世界
2a5bba8695
Improve resolve action 2025-06-17 14:25:00 +08:00
世界
e76d0d5a9b
Add back port hopping to hysteria 1 2025-06-17 14:25:00 +08:00
xchacha20-poly1305
0d287ae15e
Remove single quotes of raw Moziila certs 2025-06-17 14:24:59 +08:00
世界
a5332b48c3
Add Tailscale endpoint 2025-06-17 14:24:59 +08:00
世界
43ca1756dc
Build legacy binaries with latest Go 2025-06-17 14:24:59 +08:00
世界
8a0e272e7f
documentation: Remove outdated icons 2025-06-17 14:24:58 +08:00
世界
61ec6bb81c
documentation: Certificate store 2025-06-17 14:24:58 +08:00
世界
93a3f1e12f
documentation: TLS fragment 2025-06-17 14:24:58 +08:00
世界
125cad85c8
documentation: Outbound domain resolver 2025-06-17 14:24:57 +08:00
世界
26af3ecfa1
documentation: Refactor DNS 2025-06-17 14:24:57 +08:00
世界
4682149516
Add certificate store 2025-06-17 14:24:57 +08:00
世界
b465281ed9
Add TLS fragment support 2025-06-17 14:24:56 +08:00
世界
6094118a7a
refactor: Outbound domain resolver 2025-06-17 14:24:56 +08:00
世界
692d863422
refactor: DNS 2025-06-17 14:24:56 +08:00
世界
2d1b824b62
Fix gLazyConn race 2025-06-17 14:24:11 +08:00
8 changed files with 164 additions and 45 deletions

View File

@ -54,7 +54,7 @@ func convertRuleSet(sourcePath string) error {
var rules []option.HeadlessRule
switch flagRuleSetConvertType {
case "adguard":
rules, err = adguard.Convert(reader, log.StdLogger())
rules, err = adguard.ToOptions(reader, log.StdLogger())
case "":
return E.New("source type is required")
default:

View File

@ -6,7 +6,10 @@ import (
"strings"
"github.com/sagernet/sing-box/common/srs"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json"
"github.com/spf13/cobra"
@ -50,6 +53,11 @@ func decompileRuleSet(sourcePath string) error {
if err != nil {
return err
}
if hasRule(ruleSet.Options.Rules, func(rule option.DefaultHeadlessRule) bool {
return len(rule.AdGuardDomain) > 0
}) {
return E.New("unable to decompile binary AdGuard rules to rule-set.")
}
var outputPath string
if flagRuleSetDecompileOutput == flagRuleSetDecompileDefaultOutput {
if strings.HasSuffix(sourcePath, ".srs") {
@ -75,3 +83,19 @@ func decompileRuleSet(sourcePath string) error {
outputFile.Close()
return nil
}
func hasRule(rules []option.HeadlessRule, cond func(rule option.DefaultHeadlessRule) bool) bool {
for _, rule := range rules {
switch rule.Type {
case C.RuleTypeDefault:
if cond(rule.DefaultOptions) {
return true
}
case C.RuleTypeLogical:
if hasRule(rule.LogicalOptions.Rules, cond) {
return true
}
}
}
return false
}

View File

@ -2,6 +2,7 @@ package adguard
import (
"bufio"
"bytes"
"io"
"net/netip"
"os"
@ -27,7 +28,7 @@ type agdguardRuleLine struct {
isImportant bool
}
func Convert(reader io.Reader, logger logger.Logger) ([]option.HeadlessRule, error) {
func ToOptions(reader io.Reader, logger logger.Logger) ([]option.HeadlessRule, error) {
scanner := bufio.NewScanner(reader)
var (
ruleLines []agdguardRuleLine
@ -36,45 +37,17 @@ func Convert(reader io.Reader, logger logger.Logger) ([]option.HeadlessRule, err
parseLine:
for scanner.Scan() {
ruleLine := scanner.Text()
// Empty line
if ruleLine == "" {
continue
}
// Comment (both line comment and in-line comment)
if strings.Contains(ruleLine, "!") {
continue
}
// Either comment or cosmetic filter
if strings.Contains(ruleLine, "#") {
ignoredLines++
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
continue
}
// We don't support URL query anyway
if strings.Contains(ruleLine, "?") || strings.Contains(ruleLine, "&") {
ignoredLines++
logger.Debug("ignored unsupported rule with query: ", ruleLine)
continue
}
// Commonly seen in CSS selectors of cosmetic filters
if strings.Contains(ruleLine, "[") || strings.Contains(ruleLine, "]") {
ignoredLines++
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
continue
}
if strings.Contains(ruleLine, "(") || strings.Contains(ruleLine, ")") {
ignoredLines++
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
continue
}
// We don't support $domain modifier
if strings.Contains(ruleLine, "~") {
ignoredLines++
logger.Debug("ignored unsupported rule modifier: ", ruleLine)
continue
}
originRuleLine := ruleLine
if M.IsDomainName(ruleLine) {
ruleLines = append(ruleLines, agdguardRuleLine{
@ -169,6 +142,26 @@ parseLine:
logger.Debug("ignored unsupported rule with path: ", ruleLine)
continue
}
if strings.Contains(ruleLine, "?") || strings.Contains(ruleLine, "&") {
ignoredLines++
logger.Debug("ignored unsupported rule with query: ", ruleLine)
continue
}
if strings.Contains(ruleLine, "[") || strings.Contains(ruleLine, "]") {
ignoredLines++
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
continue
}
if strings.Contains(ruleLine, "(") || strings.Contains(ruleLine, ")") {
ignoredLines++
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
continue
}
if strings.Contains(ruleLine, "~") {
ignoredLines++
logger.Debug("ignored unsupported rule modifier: ", ruleLine)
continue
}
var domainCheck string
if strings.HasPrefix(ruleLine, ".") || strings.HasPrefix(ruleLine, "-") {
domainCheck = "r" + ruleLine
@ -313,6 +306,106 @@ parseLine:
return []option.HeadlessRule{currentRule}, nil
}
var ErrInvalid = E.New("invalid binary AdGuard rule-set")
func FromOptions(rules []option.HeadlessRule) ([]byte, error) {
if len(rules) != 1 {
return nil, ErrInvalid
}
rule := rules[0]
var (
importantDomain []string
importantDomainRegex []string
importantExcludeDomain []string
importantExcludeDomainRegex []string
domain []string
domainRegex []string
excludeDomain []string
excludeDomainRegex []string
)
parse:
for {
switch rule.Type {
case C.RuleTypeLogical:
if !(len(rule.LogicalOptions.Rules) == 2 && rule.LogicalOptions.Rules[0].Type == C.RuleTypeDefault) {
return nil, ErrInvalid
}
if rule.LogicalOptions.Mode == C.LogicalTypeAnd && rule.LogicalOptions.Rules[0].DefaultOptions.Invert {
if len(importantExcludeDomain) == 0 && len(importantExcludeDomainRegex) == 0 {
importantExcludeDomain = rule.LogicalOptions.Rules[0].DefaultOptions.AdGuardDomain
importantExcludeDomainRegex = rule.LogicalOptions.Rules[0].DefaultOptions.DomainRegex
if len(importantExcludeDomain)+len(importantExcludeDomainRegex) == 0 {
return nil, ErrInvalid
}
} else {
excludeDomain = rule.LogicalOptions.Rules[0].DefaultOptions.AdGuardDomain
excludeDomainRegex = rule.LogicalOptions.Rules[0].DefaultOptions.DomainRegex
if len(excludeDomain)+len(excludeDomainRegex) == 0 {
return nil, ErrInvalid
}
}
} else if rule.LogicalOptions.Mode == C.LogicalTypeOr && !rule.LogicalOptions.Rules[0].DefaultOptions.Invert {
importantDomain = rule.LogicalOptions.Rules[0].DefaultOptions.AdGuardDomain
importantDomainRegex = rule.LogicalOptions.Rules[0].DefaultOptions.DomainRegex
if len(importantDomain)+len(importantDomainRegex) == 0 {
return nil, ErrInvalid
}
} else {
return nil, ErrInvalid
}
rule = rule.LogicalOptions.Rules[1]
case C.RuleTypeDefault:
domain = rule.DefaultOptions.AdGuardDomain
domainRegex = rule.DefaultOptions.DomainRegex
if len(domain)+len(domainRegex) == 0 {
return nil, ErrInvalid
}
break parse
}
}
var output bytes.Buffer
for _, ruleLine := range importantDomain {
output.WriteString(ruleLine)
output.WriteString("$important\n")
}
for _, ruleLine := range importantDomainRegex {
output.WriteString("/")
output.WriteString(ruleLine)
output.WriteString("/$important\n")
}
for _, ruleLine := range importantExcludeDomain {
output.WriteString("@@")
output.WriteString(ruleLine)
output.WriteString("$important\n")
}
for _, ruleLine := range importantExcludeDomainRegex {
output.WriteString("@@/")
output.WriteString(ruleLine)
output.WriteString("/$important\n")
}
for _, ruleLine := range domain {
output.WriteString(ruleLine)
output.WriteString("\n")
}
for _, ruleLine := range domainRegex {
output.WriteString("/")
output.WriteString(ruleLine)
output.WriteString("/\n")
}
for _, ruleLine := range excludeDomain {
output.WriteString("@@")
output.WriteString(ruleLine)
output.WriteString("\n")
}
for _, ruleLine := range excludeDomainRegex {
output.WriteString("@@/")
output.WriteString(ruleLine)
output.WriteString("/\n")
}
return output.Bytes(), nil
}
func ignoreIPCIDRRegexp(ruleLine string) bool {
if strings.HasPrefix(ruleLine, "(http?:\\/\\/)") {
ruleLine = ruleLine[12:]

View File

@ -14,7 +14,8 @@ import (
func TestConverter(t *testing.T) {
t.Parallel()
rules, err := Convert(strings.NewReader(`
ruleString := `||sagernet.org^$important
@@|sing-box.sagernet.org^$important
||example.org^
|example.com^
example.net^
@ -22,10 +23,9 @@ example.net^
||example.edu.tw^
|example.gov
example.arpa
@@|sagernet.example.org|
||sagernet.org^$important
@@|sing-box.sagernet.org^$important
`), logger.NOP())
@@|sagernet.example.org^
`
rules, err := ToOptions(strings.NewReader(ruleString), logger.NOP())
require.NoError(t, err)
require.Len(t, rules, 1)
rule, err := rule.NewHeadlessRule(context.Background(), rules[0])
@ -76,11 +76,14 @@ example.arpa
Domain: domain,
}), domain)
}
ruleFromOptions, err := FromOptions(rules)
require.NoError(t, err)
require.Equal(t, ruleString, string(ruleFromOptions))
}
func TestHosts(t *testing.T) {
t.Parallel()
rules, err := Convert(strings.NewReader(`
rules, err := ToOptions(strings.NewReader(`
127.0.0.1 localhost
::1 localhost #[IPv6]
0.0.0.0 google.com
@ -111,7 +114,7 @@ func TestHosts(t *testing.T) {
func TestSimpleHosts(t *testing.T) {
t.Parallel()
rules, err := Convert(strings.NewReader(`
rules, err := ToOptions(strings.NewReader(`
example.com
www.example.org
`), logger.NOP())

View File

@ -215,16 +215,15 @@ func readDefaultRule(reader varbin.Reader, recover bool) (rule option.DefaultHea
case ruleItemWIFIBSSID:
rule.WIFIBSSID, err = readRuleItemString(reader)
case ruleItemAdGuardDomain:
if recover {
err = E.New("unable to decompile binary AdGuard rules to rule-set")
return
}
var matcher *domain.AdGuardMatcher
matcher, err = domain.ReadAdGuardMatcher(reader)
if err != nil {
return
}
rule.AdGuardDomainMatcher = matcher
if recover {
rule.AdGuardDomain = matcher.Dump()
}
case ruleItemNetworkType:
rule.NetworkType, err = readRuleItemUint8[option.InterfaceType](reader)
case ruleItemNetworkIsExpensive:

View File

@ -2,7 +2,7 @@
icon: material/alert-decagram
---
#### 1.12.0-beta.25
#### 1.12.0-beta.26
* Fixes and improvements

2
go.mod
View File

@ -34,7 +34,7 @@ require (
github.com/sagernet/sing-shadowsocks v0.2.8
github.com/sagernet/sing-shadowsocks2 v0.2.1
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11
github.com/sagernet/sing-tun v0.6.8-0.20250615093440-d1f6001b58c2
github.com/sagernet/sing-tun v0.6.9-0.20250617062442-df4458520f26
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88
github.com/sagernet/smux v1.5.34-mod.2
github.com/sagernet/tailscale v1.80.3-mod.5

4
go.sum
View File

@ -180,8 +180,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq
github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
github.com/sagernet/sing-tun v0.6.8-0.20250615093440-d1f6001b58c2 h1:leio5dGtYCKHQam+SyLszq4bbXGaxF4ElK5Aif/lUb8=
github.com/sagernet/sing-tun v0.6.8-0.20250615093440-d1f6001b58c2/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE=
github.com/sagernet/sing-tun v0.6.9-0.20250617062442-df4458520f26 h1:N9yAoqtQlawlJzLONjdQvIO3GJLEg9tZBfyKToSi0cM=
github.com/sagernet/sing-tun v0.6.9-0.20250617062442-df4458520f26/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE=
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88 h1:0pVm8sPOel+BoiCddW3pV3cKDKEaSioVTYDdTSKjyFI=
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88/go.mod h1:IL8Rr+EGwuqijszZkNrEFTQDKhilEpkqFqOlvdpS6/w=
github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4=