Compare commits

..

107 Commits

Author SHA1 Message Date
世界
46bb372a37 documentation: Bump version 2025-06-20 14:10:49 +08:00
世界
9e3b34ea50 Add API to dump AdGuard rules 2025-06-20 13:21:22 +08:00
Sukka
983421c1cb Improve AdGuard rule-set parser 2025-06-20 13:21:05 +08:00
Restia-Ashbell
4861ceb6ee Add ECH support for uTLS 2025-06-20 13:21:04 +08:00
世界
4f4e3eb8c3 Improve TLS fragments 2025-06-20 13:21:04 +08:00
世界
7b7feb794e Add cache support for ssm-api 2025-06-20 13:21:04 +08:00
世界
b3b8d1fa29 Fix service will not be closed 2025-06-20 13:21:04 +08:00
世界
da924b51c8 Add loopback address support for tun 2025-06-20 13:21:04 +08:00
世界
fb3983ff6d Fix tproxy listener 2025-06-20 13:21:04 +08:00
世界
07ec062876 Fix systemd package 2025-06-20 13:21:04 +08:00
世界
80f43fa51b Fix missing home for derp service 2025-06-20 13:21:03 +08:00
Zero Clover
e0e9160290 documentation: Fix services 2025-06-20 13:21:03 +08:00
世界
5d1f13385b Fix dns.client_subnet ignored 2025-06-20 13:21:03 +08:00
世界
9ef08196a4 documentation: Minor fixes 2025-06-20 13:21:03 +08:00
世界
cf26a7b6f6 Fix tailscale forward 2025-06-20 13:21:03 +08:00
世界
49efb2b8de Minor fixes 2025-06-20 13:21:03 +08:00
世界
965bec8967 Add SSM API service 2025-06-20 13:21:03 +08:00
世界
cc34e8391d Add resolved service and DNS server 2025-06-20 13:21:02 +08:00
世界
b89158efb9 Add DERP service 2025-06-20 13:20:54 +08:00
世界
a226bdca28 Add service component type 2025-06-20 13:20:53 +08:00
世界
360130af7b Fix tproxy tcp control 2025-06-20 13:20:53 +08:00
愚者
f327ea7737 release: Fix build tags for android
Signed-off-by: 愚者 <11926619+FansChou@users.noreply.github.com>
2025-06-20 13:20:53 +08:00
世界
90d6de9220 prevent creation of bind and mark controls on unsupported platforms 2025-06-20 13:20:53 +08:00
PuerNya
6d71e440e0 documentation: Fix description of reject DNS action behavior 2025-06-20 13:20:52 +08:00
Restia-Ashbell
d249150a63 Fix TLS record fragment 2025-06-20 13:20:52 +08:00
世界
b3921910e4 Add missing accept_routes option for Tailscale 2025-06-20 13:20:52 +08:00
世界
b9163feb77 Add TLS record fragment support 2025-06-20 13:20:52 +08:00
世界
40d7e13103 Fix set edns0 client subnet 2025-06-20 13:20:52 +08:00
世界
7b56fb370f Update minor dependencies 2025-06-20 13:20:52 +08:00
世界
6036174a37 Update certmagic and providers 2025-06-20 13:20:52 +08:00
世界
6ed4a3e25e Update protobuf and grpc 2025-06-20 13:20:52 +08:00
世界
168809cfe2 Add control options for listeners 2025-06-20 13:20:51 +08:00
世界
b6ca331c7d Update quic-go to v0.52.0 2025-06-20 13:20:51 +08:00
世界
d2a04c4e41 Update utls to v1.7.2 2025-06-20 13:20:51 +08:00
世界
027ff49390 Handle EDNS version downgrade 2025-06-20 13:20:43 +08:00
世界
8936f41e54 documentation: Fix anytls padding scheme description 2025-06-20 13:20:42 +08:00
安容
e8a6ae0ac7 Report invalid DNS address early 2025-06-20 13:20:42 +08:00
世界
df36013d7d Fix wireguard listen_port 2025-06-20 13:20:42 +08:00
世界
a9cd830a9a clash-api: Add more meta api 2025-06-20 13:20:42 +08:00
世界
306abab55d Fix DNS lookup 2025-06-20 13:20:41 +08:00
世界
f7a92111c5 Fix fetch ECH configs 2025-06-20 13:20:41 +08:00
reletor
dfe82895ab documentation: Minor fixes 2025-06-20 13:20:41 +08:00
caelansar
973ab97813 Fix callback deletion in UDP transport 2025-06-20 13:20:41 +08:00
世界
a78f3cb116 documentation: Try to make the play review happy 2025-06-20 13:20:41 +08:00
世界
13037a56d8 Fix missing handling of legacy domain_strategy options 2025-06-20 13:20:41 +08:00
世界
3dc3a0b6e3 Improve local DNS server 2025-06-20 13:20:40 +08:00
anytls
577c51a1f1 Update anytls
Co-authored-by: anytls <anytls>
2025-06-20 13:20:25 +08:00
世界
64db52f638 Fix DNS dialer 2025-06-20 13:20:25 +08:00
世界
1b6521f5f8 release: Skip override version for iOS 2025-06-20 13:20:25 +08:00
iikira
ec8821fc94 Fix UDP DNS server crash
Signed-off-by: iikira <i2@mail.iikira.com>
2025-06-20 13:20:25 +08:00
ReleTor
c90e0ad48d Fix fetch ECH configs 2025-06-20 13:20:24 +08:00
世界
38676a2f06 Allow direct outbounds without domain_resolver 2025-06-20 13:20:24 +08:00
世界
8d2b641f92 Fix Tailscale dialer 2025-06-20 13:20:24 +08:00
dyhkwong
f0bf1f0ae8 Fix DNS over QUIC stream close 2025-06-20 13:20:24 +08:00
anytls
084071e882 Update anytls
Co-authored-by: anytls <anytls>
2025-06-20 13:20:24 +08:00
Rambling2076
90499e90de Fix missing with_tailscale in Dockerfile
Signed-off-by: Rambling2076 <Rambling2076@proton.me>
2025-06-20 13:20:23 +08:00
世界
20055a362c Fail when default DNS server not found 2025-06-20 13:20:23 +08:00
世界
376dd20254 Update gVisor to 20250319.0 2025-06-20 13:20:22 +08:00
世界
9a83c088b1 Explicitly reject detour to empty direct outbounds 2025-06-20 13:20:22 +08:00
世界
2b4c6f4ebb Add netns support 2025-06-20 13:20:22 +08:00
世界
3ca6fee62f Add wildcard name support for predefined records 2025-06-20 13:20:22 +08:00
世界
372ac544c8 Remove map usage in options 2025-06-20 13:20:22 +08:00
世界
138c1e4969 Fix unhandled DNS loop 2025-06-20 13:20:22 +08:00
世界
8a586db5f1 Add wildcard-sni support for shadow-tls inbound 2025-06-20 13:20:21 +08:00
k9982874
9959239b1a Add ntp protocol sniffing 2025-06-20 13:20:13 +08:00
世界
4d96d78cd8 option: Fix marshal legacy DNS options 2025-06-20 13:20:13 +08:00
世界
d3d58b37e8 Make domain_resolver optional when only one DNS server is configured 2025-06-20 13:20:12 +08:00
世界
21e7bbdffc Fix DNS lookup context pollution 2025-06-20 13:20:12 +08:00
世界
c0b6a876ff Fix http3 DNS server connecting to wrong address 2025-06-20 13:20:12 +08:00
Restia-Ashbell
9b42c2efac documentation: Fix typo 2025-06-20 13:20:12 +08:00
anytls
dc433869cd Update sing-anytls
Co-authored-by: anytls <anytls>
2025-06-20 13:20:11 +08:00
k9982874
98db9aa3ec Fix hosts DNS server 2025-06-20 13:20:11 +08:00
世界
46a7a2b457 Fix UDP DNS server crash 2025-06-20 13:20:11 +08:00
世界
279fa7379c documentation: Fix missing ip_accept_any DNS rule option 2025-06-20 13:20:10 +08:00
世界
d896cbe623 Fix anytls dialer usage 2025-06-20 13:20:10 +08:00
世界
2b1d40c9b7 Move predefined DNS server to rule action 2025-06-20 13:20:10 +08:00
世界
ca304a9d6f Fix domain resolver on direct outbound 2025-06-20 13:20:09 +08:00
Zephyruso
7bc733b5b1 Fix missing AnyTLS display name 2025-06-20 13:20:09 +08:00
anytls
a6a934a91b Update sing-anytls
Co-authored-by: anytls <anytls>
2025-06-20 13:20:09 +08:00
Estel
cf5a34a318 documentation: Fix typo
Signed-off-by: Estel <callmebedrockdigger@gmail.com>
2025-06-20 13:20:08 +08:00
TargetLocked
9570568caa Fix parsing legacy DNS options 2025-06-20 13:20:08 +08:00
世界
bf1962cfe4 Fix DNS fallback 2025-06-20 13:20:08 +08:00
世界
e6a07492d0 documentation: Fix missing hosts DNS server 2025-06-20 13:20:07 +08:00
anytls
36b12f4ab5 Add MinIdleSession option to AnyTLS outbound
Co-authored-by: anytls <anytls>
2025-06-20 13:20:07 +08:00
ReleTor
bc0cbef785 documentation: Minor fixes 2025-06-20 13:20:07 +08:00
libtry486
8dc7698c5f documentation: Fix typo
fix typo

Signed-off-by: libtry486 <89328481+libtry486@users.noreply.github.com>
2025-06-20 13:20:06 +08:00
Alireza Ahmadi
cc59cb27e9 Fix Outbound deadlock 2025-06-20 13:20:06 +08:00
世界
0e1c8a1134 documentation: Fix AnyTLS doc 2025-06-20 13:20:06 +08:00
anytls
418f6fff49 Add AnyTLS protocol 2025-06-20 13:20:06 +08:00
世界
e5f87fab4b Migrate to stdlib ECH support 2025-06-20 13:20:05 +08:00
世界
61e9a9f674 Add fallback local DNS server for iOS 2025-06-20 13:20:05 +08:00
世界
19fd3e836e Get darwin local DNS server from libresolv 2025-06-20 13:20:05 +08:00
世界
78515fd9c7 Improve resolve action 2025-06-20 13:20:04 +08:00
世界
7506b2711c Add back port hopping to hysteria 1 2025-06-20 13:20:04 +08:00
xchacha20-poly1305
07817df680 Remove single quotes of raw Moziila certs 2025-06-20 13:20:03 +08:00
世界
dc9b7c880d Add Tailscale endpoint 2025-06-20 13:20:03 +08:00
世界
b79f1b2540 Build legacy binaries with latest Go 2025-06-20 13:20:03 +08:00
世界
7487fa28be documentation: Remove outdated icons 2025-06-20 13:20:03 +08:00
世界
10c7c67e3c documentation: Certificate store 2025-06-20 13:20:02 +08:00
世界
ca2a10f9f6 documentation: TLS fragment 2025-06-20 13:20:02 +08:00
世界
ddc6cdc3fb documentation: Outbound domain resolver 2025-06-20 13:20:01 +08:00
世界
2e96569fef documentation: Refactor DNS 2025-06-20 13:20:01 +08:00
世界
fe5ee7d31d Add certificate store 2025-06-20 13:20:01 +08:00
世界
06c2824df9 Add TLS fragment support 2025-06-20 13:20:01 +08:00
世界
b28d19cfa7 refactor: Outbound domain resolver 2025-06-20 13:20:01 +08:00
世界
1709ad7f7f refactor: DNS 2025-06-20 13:19:42 +08:00
世界
842f209da0 Fix log for rejected connections 2025-06-20 13:12:49 +08:00
33 changed files with 236 additions and 288 deletions

View File

@@ -476,11 +476,11 @@ jobs:
- name: Setup Xcode stable
if: matrix.if && github.ref == 'refs/heads/main-next'
run: |-
sudo xcode-select -s /Applications/Xcode_16.4.app
sudo xcode-select -s /Applications/Xcode_16.2.app
- name: Setup Xcode beta
if: matrix.if && github.ref == 'refs/heads/dev-next'
run: |-
sudo xcode-select -s /Applications/Xcode_16.4.app
sudo xcode-select -s /Applications/Xcode_16.2.app
- name: Set tag
if: matrix.if
run: |-
@@ -615,7 +615,7 @@ jobs:
path: 'dist'
upload:
name: Upload builds
if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')"
if: always() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')
runs-on: ubuntu-latest
needs:
- calculate_version

View File

@@ -108,16 +108,6 @@ upload_ios_app_store:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
export_ios_ipa:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFI && \
cp build/SFI/sing-box.ipa dist/SFI.ipa
upload_ios_ipa:
cd dist && \
cp SFI.ipa "SFI-${VERSION}.ipa" && \
ghr --replace --draft --prerelease "v${VERSION}" "SFI-${VERSION}.ipa"
release_ios: build_ios upload_ios_app_store
build_macos:
@@ -185,16 +175,6 @@ upload_tvos_app_store:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
export_tvos_ipa:
cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFT && \
cp build/SFT/sing-box.ipa dist/SFT.ipa
upload_tvos_ipa:
cd dist && \
cp SFT.ipa "SFT-${VERSION}.ipa" && \
ghr --replace --draft --prerelease "v${VERSION}" "SFT-${VERSION}.ipa"
release_tvos: build_tvos upload_tvos_app_store
update_apple_version:

View File

@@ -3,7 +3,6 @@ package adapter
import (
"context"
"net/netip"
"time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
@@ -37,7 +36,6 @@ type DNSQueryOptions struct {
Transport DNSTransport
Strategy C.DomainStrategy
LookupStrategy C.DomainStrategy
Timeout time.Duration
DisableCache bool
RewriteTTL *uint32
ClientSubnet netip.Prefix
@@ -55,7 +53,6 @@ func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptio
return &DNSQueryOptions{
Transport: transport,
Strategy: C.DomainStrategy(options.Strategy),
Timeout: time.Duration(options.Timeout),
DisableCache: options.DisableCache,
RewriteTTL: options.RewriteTTL,
ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
@@ -73,7 +70,6 @@ type DNSTransport interface {
Type() string
Tag() string
Dependencies() []string
HasDetour() bool
Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
}

View File

@@ -53,11 +53,11 @@ type InboundContext struct {
// sniffer
Protocol string
Domain string
Client string
SniffContext any
SniffError error
Protocol string
Domain string
Client string
SniffContext any
PacketSniffError error
// cache

View File

@@ -16,17 +16,15 @@ import (
)
var (
debugEnabled bool
target string
platform string
withTailscale bool
debugEnabled bool
target string
platform string
)
func init() {
flag.BoolVar(&debugEnabled, "debug", false, "enable debug")
flag.StringVar(&target, "target", "android", "target platform")
flag.StringVar(&platform, "platform", "", "specify platform")
flag.BoolVar(&withTailscale, "with-tailscale", false, "build tailscale for iOS and tvOS")
}
func main() {
@@ -153,9 +151,7 @@ func buildApple() {
"-v",
"-target", bindTarget,
"-libname=box",
}
if !withTailscale {
args = append(args, "-tags-macos="+strings.Join(memcTags, ","))
"-tags-macos=" + strings.Join(memcTags, ","),
}
if !debugEnabled {
@@ -165,9 +161,6 @@ func buildApple() {
}
tags := append(sharedTags, iosTags...)
if withTailscale {
tags = append(tags, memcTags...)
}
if debugEnabled {
tags = append(tags, debugTags...)
}

View File

@@ -96,7 +96,7 @@ parseLine:
}
if !ignored {
ignoredLines++
logger.Debug("ignored unsupported rule with modifier: ", paramParts[0], ": ", originRuleLine)
logger.Debug("ignored unsupported rule with modifier: ", paramParts[0], ": ", ruleLine)
continue parseLine
}
}
@@ -124,35 +124,34 @@ parseLine:
ruleLine = ruleLine[1 : len(ruleLine)-1]
if ignoreIPCIDRRegexp(ruleLine) {
ignoredLines++
logger.Debug("ignored unsupported rule with IPCIDR regexp: ", originRuleLine)
logger.Debug("ignored unsupported rule with IPCIDR regexp: ", ruleLine)
continue
}
isRegexp = true
} else {
if strings.Contains(ruleLine, "://") {
ruleLine = common.SubstringAfter(ruleLine, "://")
isSuffix = true
}
if strings.Contains(ruleLine, "/") {
ignoredLines++
logger.Debug("ignored unsupported rule with path: ", originRuleLine)
logger.Debug("ignored unsupported rule with path: ", ruleLine)
continue
}
if strings.Contains(ruleLine, "?") || strings.Contains(ruleLine, "&") {
ignoredLines++
logger.Debug("ignored unsupported rule with query: ", originRuleLine)
logger.Debug("ignored unsupported rule with query: ", ruleLine)
continue
}
if strings.Contains(ruleLine, "[") || strings.Contains(ruleLine, "]") ||
strings.Contains(ruleLine, "(") || strings.Contains(ruleLine, ")") ||
strings.Contains(ruleLine, "!") || strings.Contains(ruleLine, "#") {
ignoredLines++
logger.Debug("ignored unsupported cosmetic filter: ", originRuleLine)
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
continue
}
if strings.Contains(ruleLine, "~") {
ignoredLines++
logger.Debug("ignored unsupported rule modifier: ", originRuleLine)
logger.Debug("ignored unsupported rule modifier: ", ruleLine)
continue
}
var domainCheck string
@@ -171,13 +170,13 @@ parseLine:
_, ipErr := parseADGuardIPCIDRLine(ruleLine)
if ipErr == nil {
ignoredLines++
logger.Debug("ignored unsupported rule with IPCIDR: ", originRuleLine)
logger.Debug("ignored unsupported rule with IPCIDR: ", ruleLine)
continue
}
if M.ParseSocksaddr(domainCheck).Port != 0 {
logger.Debug("ignored unsupported rule with port: ", originRuleLine)
logger.Debug("ignored unsupported rule with port: ", ruleLine)
} else {
logger.Debug("ignored unsupported rule with invalid domain: ", originRuleLine)
logger.Debug("ignored unsupported rule with invalid domain: ", ruleLine)
}
ignoredLines++
continue
@@ -408,9 +407,11 @@ func ignoreIPCIDRRegexp(ruleLine string) bool {
ruleLine = ruleLine[13:]
} else if strings.HasPrefix(ruleLine, "^") {
ruleLine = ruleLine[1:]
} else {
return false
}
return common.Error(strconv.ParseUint(common.SubstringBefore(ruleLine, "\\."), 10, 8)) == nil ||
common.Error(strconv.ParseUint(common.SubstringBefore(ruleLine, "."), 10, 8)) == nil
_, parseErr := strconv.ParseUint(common.SubstringBefore(ruleLine, "\\."), 10, 8)
return parseErr == nil
}
func parseAdGuardHostLine(ruleLine string) (string, error) {

View File

@@ -89,7 +89,6 @@ func NewWithOptions(options Options) (N.Dialer, error) {
dnsQueryOptions = adapter.DNSQueryOptions{
Transport: transport,
Strategy: strategy,
Timeout: time.Duration(dialOptions.DomainResolver.Timeout),
DisableCache: dialOptions.DomainResolver.DisableCache,
RewriteTTL: dialOptions.DomainResolver.RewriteTTL,
ClientSubnet: dialOptions.DomainResolver.ClientSubnet.Build(netip.Prefix{}),

View File

@@ -5,13 +5,13 @@ package tls
import (
"context"
"crypto/tls"
"os"
"strings"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
"github.com/caddyserver/certmagic"
"github.com/libdns/alidns"
@@ -37,38 +37,7 @@ func (w *acmeWrapper) Close() error {
return nil
}
type acmeLogWriter struct {
logger logger.Logger
}
func (w *acmeLogWriter) Write(p []byte) (n int, err error) {
logLine := strings.ReplaceAll(string(p), " ", ": ")
switch {
case strings.HasPrefix(logLine, "error: "):
w.logger.Error(logLine[7:])
case strings.HasPrefix(logLine, "warn: "):
w.logger.Warn(logLine[6:])
case strings.HasPrefix(logLine, "info: "):
w.logger.Info(logLine[6:])
case strings.HasPrefix(logLine, "debug: "):
w.logger.Debug(logLine[7:])
default:
w.logger.Debug(logLine)
}
return len(p), nil
}
func (w *acmeLogWriter) Sync() error {
return nil
}
func encoderConfig() zapcore.EncoderConfig {
config := zap.NewProductionEncoderConfig()
config.TimeKey = zapcore.OmitKey
return config
}
func startACME(ctx context.Context, logger logger.Logger, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
func startACME(ctx context.Context, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
var acmeServer string
switch options.Provider {
case "", "letsencrypt":
@@ -89,15 +58,14 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
} else {
storage = certmagic.Default.Storage
}
zapLogger := zap.New(zapcore.NewCore(
zapcore.NewConsoleEncoder(encoderConfig()),
&acmeLogWriter{logger: logger},
zap.DebugLevel,
))
config := &certmagic.Config{
DefaultServerName: options.DefaultServerName,
Storage: storage,
Logger: zapLogger,
Logger: zap.New(zapcore.NewCore(
zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig()),
os.Stderr,
zap.InfoLevel,
)),
}
acmeConfig := certmagic.ACMEIssuer{
CA: acmeServer,
@@ -107,7 +75,7 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
DisableTLSALPNChallenge: options.DisableTLSALPNChallenge,
AltHTTPPort: int(options.AlternativeHTTPPort),
AltTLSALPNPort: int(options.AlternativeTLSPort),
Logger: zapLogger,
Logger: config.Logger,
}
if dnsOptions := options.DNS01Challenge; dnsOptions != nil && dnsOptions.Provider != "" {
var solver certmagic.DNS01Solver
@@ -135,7 +103,6 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) {
return config, nil
},
Logger: zapLogger,
})
config = certmagic.New(cache, *config)
var tlsConfig *tls.Config

View File

@@ -9,9 +9,8 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
)
func startACME(ctx context.Context, logger logger.Logger, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
func startACME(ctx context.Context, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
return nil, nil, E.New(`ACME is not included in this build, rebuild with -tags with_acme`)
}

View File

@@ -169,7 +169,7 @@ func NewSTDServer(ctx context.Context, logger log.Logger, options option.Inbound
var err error
if options.ACME != nil && len(options.ACME.Domain) > 0 {
//nolint:staticcheck
tlsConfig, acmeService, err = startACME(ctx, logger, common.PtrValueOrDefault(options.ACME))
tlsConfig, acmeService, err = startACME(ctx, common.PtrValueOrDefault(options.ACME))
if err != nil {
return nil, err
}

View File

@@ -9,7 +9,6 @@ const (
TCPTimeout = 15 * time.Second
ReadPayloadTimeout = 300 * time.Millisecond
DNSTimeout = 10 * time.Second
DirectDNSTimeout = 5 * time.Second
UDPTimeout = 5 * time.Minute
DefaultURLTestInterval = 3 * time.Minute
DefaultURLTestIdleTimeout = 30 * time.Minute

View File

@@ -30,6 +30,7 @@ var (
var _ adapter.DNSClient = (*Client)(nil)
type Client struct {
timeout time.Duration
disableCache bool
disableExpire bool
independentCache bool
@@ -42,6 +43,7 @@ type Client struct {
}
type ClientOptions struct {
Timeout time.Duration
DisableCache bool
DisableExpire bool
IndependentCache bool
@@ -53,6 +55,7 @@ type ClientOptions struct {
func NewClient(options ClientOptions) *Client {
client := &Client{
timeout: options.Timeout,
disableCache: options.DisableCache,
disableExpire: options.DisableExpire,
independentCache: options.IndependentCache,
@@ -60,6 +63,9 @@ func NewClient(options ClientOptions) *Client {
initRDRCFunc: options.RDRC,
logger: options.Logger,
}
if client.timeout == 0 {
client.timeout = C.DNSTimeout
}
cacheCapacity := options.CacheCapacity
if cacheCapacity < 1024 {
cacheCapacity = 1024
@@ -147,15 +153,7 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
return nil, ErrResponseRejectedCached
}
}
timeout := options.Timeout
if timeout == 0 {
if transport.HasDetour() {
timeout = C.DNSTimeout
} else {
timeout = C.DirectDNSTimeout
}
}
ctx, cancel := context.WithTimeout(ctx, timeout)
ctx, cancel := context.WithTimeout(ctx, c.timeout)
response, err := transport.Exchange(ctx, message)
cancel()
if err != nil {

View File

@@ -158,9 +158,6 @@ func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleIndex int,
if action.Strategy != C.DomainStrategyAsIS {
options.Strategy = action.Strategy
}
if action.Timeout > 0 {
options.Timeout = action.Timeout
}
if isFakeIP || action.DisableCache {
options.DisableCache = true
}
@@ -183,9 +180,6 @@ func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleIndex int,
if action.Strategy != C.DomainStrategyAsIS {
options.Strategy = action.Strategy
}
if action.Timeout > 0 {
options.Timeout = action.Timeout
}
if action.DisableCache {
options.DisableCache = true
}

View File

@@ -41,7 +41,6 @@ type Transport struct {
dns.TransportAdapter
ctx context.Context
dialer N.Dialer
hasDetour bool
logger logger.ContextLogger
networkManager adapter.NetworkManager
interfaceName string
@@ -60,7 +59,6 @@ func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, opt
TransportAdapter: dns.NewTransportAdapterWithLocalOptions(C.DNSTypeDHCP, tag, options.LocalDNSServerOptions),
ctx: ctx,
dialer: transportDialer,
hasDetour: options.Detour != "",
logger: logger,
networkManager: service.FromContext[adapter.NetworkManager](ctx),
interfaceName: options.Interface,
@@ -91,10 +89,6 @@ func (t *Transport) Close() error {
return nil
}
func (t *Transport) HasDetour() bool {
return t.hasDetour
}
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
err := t.fetchServers()
if err != nil {

View File

@@ -3,15 +3,11 @@ package transport
import (
"bytes"
"context"
"errors"
"io"
"net"
"net/http"
"net/url"
"os"
"strconv"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
@@ -43,13 +39,11 @@ func RegisterHTTPS(registry *dns.TransportRegistry) {
type HTTPSTransport struct {
dns.TransportAdapter
logger logger.ContextLogger
dialer N.Dialer
destination *url.URL
headers http.Header
transportAccess sync.Mutex
transport *http.Transport
transportResetAt time.Time
logger logger.ContextLogger
dialer N.Dialer
destination *url.URL
headers http.Header
transport *http.Transport
}
func NewHTTPS(ctx context.Context, logger log.ContextLogger, tag string, options option.RemoteHTTPSDNSServerOptions) (adapter.DNSTransport, error) {
@@ -167,33 +161,12 @@ func (t *HTTPSTransport) Start(stage adapter.StartStage) error {
}
func (t *HTTPSTransport) Close() error {
t.transportAccess.Lock()
defer t.transportAccess.Unlock()
t.transport.CloseIdleConnections()
t.transport = t.transport.Clone()
return nil
}
func (t *HTTPSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
startAt := time.Now()
response, err := t.exchange(ctx, message)
if err != nil {
if errors.Is(err, os.ErrDeadlineExceeded) {
t.transportAccess.Lock()
defer t.transportAccess.Unlock()
if t.transportResetAt.After(startAt) {
return nil, err
}
t.transport.CloseIdleConnections()
t.transport = t.transport.Clone()
t.transportResetAt = time.Now()
}
return nil, err
}
return response, nil
}
func (t *HTTPSTransport) exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
exMessage := *message
exMessage.Id = 0
exMessage.Compress = true

View File

@@ -20,8 +20,7 @@ import (
)
func dnsReadConfig(_ context.Context, _ string) *dnsConfig {
var state C.res_state
if C.res_ninit(state) != 0 {
if C.res_init() != 0 {
return &dnsConfig{
servers: defaultNS,
search: dnsDefaultSearch(),
@@ -34,10 +33,10 @@ func dnsReadConfig(_ context.Context, _ string) *dnsConfig {
conf := &dnsConfig{
ndots: 1,
timeout: 5 * time.Second,
attempts: int(state.retry),
attempts: int(C._res.retry),
}
for i := 0; i < int(state.nscount); i++ {
ns := state.nsaddr_list[i]
for i := 0; i < int(C._res.nscount); i++ {
ns := C._res.nsaddr_list[i]
addr := C.inet_ntoa(ns.sin_addr)
if addr == nil {
continue
@@ -45,7 +44,7 @@ func dnsReadConfig(_ context.Context, _ string) *dnsConfig {
conf.servers = append(conf.servers, C.GoString(addr))
}
for i := 0; ; i++ {
search := state.dnsrch[i]
search := C._res.dnsrch[i]
if search == nil {
break
}

View File

@@ -14,7 +14,6 @@ type TransportAdapter struct {
transportType string
transportTag string
dependencies []string
hasDetour bool
strategy C.DomainStrategy
clientSubnet netip.Prefix
}
@@ -36,7 +35,6 @@ func NewTransportAdapterWithLocalOptions(transportType string, transportTag stri
transportType: transportType,
transportTag: transportTag,
dependencies: dependencies,
hasDetour: localOptions.Detour != "",
strategy: C.DomainStrategy(localOptions.LegacyStrategy),
clientSubnet: localOptions.LegacyClientSubnet,
}
@@ -71,10 +69,6 @@ func (a *TransportAdapter) Dependencies() []string {
return a.dependencies
}
func (a *TransportAdapter) HasDetour() bool {
return a.hasDetour
}
func (a *TransportAdapter) LegacyStrategy() C.DomainStrategy {
return a.strategy
}

View File

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

View File

@@ -25,7 +25,7 @@ icon: material/new-box
| 类型 | 格式 |
|-------------|---------------------------|
| `wireguard` | [WireGuard](./wireguard/) |
| `wireguard` | [WireGuard](./wiregaurd/) |
| `tailscale` | [Tailscale](./tailscale/) |
#### tag

View File

@@ -59,7 +59,7 @@
{
"external_controller": "0.0.0.0:9090",
"external_ui": "dashboard"
// "external_ui_download_detour": "direct"
// external_ui_download_detour: "direct"
}
```

View File

@@ -59,7 +59,7 @@
{
"external_controller": "0.0.0.0:9090",
"external_ui": "dashboard"
// "external_ui_download_detour": "direct"
// external_ui_download_detour: "direct"
}
```

View File

@@ -64,7 +64,7 @@ icon: material/new-box
"auto_redirect_input_mark": "0x2023",
"auto_redirect_output_mark": "0x2024",
"loopback_address": [
"10.7.0.1"
"10.0.7.1"
],
"strict_route": true,
"route_address": [
@@ -284,7 +284,7 @@ Connection output mark used by `auto_redirect`.
Loopback addresses make TCP connections to the specified address connect to the source address.
Setting option value to `10.7.0.1` achieves the same behavior as SideStore/StosVPN.
Setting option value to `10.0.7.1` achieves the same behavior as SideStore/StosVPN.
When `auto_redirect` is enabled, the same behavior can be achieved for LAN devices (not just local) as a gateway.

View File

@@ -64,7 +64,7 @@ icon: material/new-box
"auto_redirect_input_mark": "0x2023",
"auto_redirect_output_mark": "0x2024",
"loopback_address": [
"10.7.0.1"
"10.0.7.1"
],
"strict_route": true,
"route_address": [
@@ -283,7 +283,7 @@ tun 接口的 IPv6 前缀。
环回地址是用于使指向指定地址的 TCP 连接连接到来源地址的。
将选项值设置为 `10.7.0.1` 可实现与 SideStore/StosVPN 相同的行为。
将选项值设置为 `10.0.7.1` 可实现与 SideStore/StosVPN 相同的行为。
当启用 `auto_redirect` 时,可以作为网关为局域网设备(而不仅仅是本地)实现相同的行为。

View File

@@ -94,13 +94,18 @@ flowchart TB
"servers": [
{
"tag": "google",
"type": "tls",
"server": "8.8.8.8"
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"type": "udp",
"server": "223.5.5.5"
"address": "223.5.5.5",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
}
],
"strategy": "ipv4_only"
@@ -110,8 +115,7 @@ flowchart TB
"type": "tun",
"inet4_address": "172.19.0.1/30",
"auto_route": true,
// "auto_redirect": true, // On linux
"strict_route": true
"strict_route": false
}
],
"outbounds": [
@@ -119,23 +123,25 @@ flowchart TB
{
"type": "direct",
"tag": "direct"
},
{
"type": "dns",
"tag": "dns-out"
}
],
"route": {
"rules": [
{
"action": "sniff"
},
{
"protocol": "dns",
"action": "hijack-dns"
"outbound": "dns-out"
},
{
"ip_is_private": true,
"geoip": [
"private"
],
"outbound": "direct"
}
],
"default_domain_resolver": "local",
"auto_detect_interface": true
}
}
@@ -149,13 +155,18 @@ flowchart TB
"servers": [
{
"tag": "google",
"type": "tls",
"server": "8.8.8.8"
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"type": "udp",
"server": "223.5.5.5"
"address": "223.5.5.5",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
}
]
},
@@ -165,8 +176,7 @@ flowchart TB
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/126",
"auto_route": true,
// "auto_redirect": true, // On linux
"strict_route": true
"strict_route": false
}
],
"outbounds": [
@@ -174,23 +184,25 @@ flowchart TB
{
"type": "direct",
"tag": "direct"
},
{
"type": "dns",
"tag": "dns-out"
}
],
"route": {
"rules": [
{
"action": "sniff"
},
{
"protocol": "dns",
"action": "hijack-dns"
"outbound": "dns-out"
},
{
"ip_is_private": true,
"geoip": [
"private"
],
"outbound": "direct"
}
],
"default_domain_resolver": "local",
"auto_detect_interface": true
}
}
@@ -204,22 +216,23 @@ flowchart TB
"servers": [
{
"tag": "google",
"type": "tls",
"server": "8.8.8.8"
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"type": "udp",
"server": "223.5.5.5"
"address": "223.5.5.5",
"detour": "direct"
},
{
"tag": "remote",
"type": "fakeip",
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
"address": "fakeip"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
},
{
"query_type": [
"A",
@@ -228,6 +241,11 @@ flowchart TB
"server": "remote"
}
],
"fakeip": {
"enabled": true,
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
},
"independent_cache": true
},
"inbounds": [
@@ -236,7 +254,6 @@ flowchart TB
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/126",
"auto_route": true,
// "auto_redirect": true, // On linux
"strict_route": true
}
],
@@ -245,23 +262,25 @@ flowchart TB
{
"type": "direct",
"tag": "direct"
},
{
"type": "dns",
"tag": "dns-out"
}
],
"route": {
"rules": [
{
"action": "sniff"
},
{
"protocol": "dns",
"action": "hijack-dns"
"outbound": "dns-out"
},
{
"ip_is_private": true,
"geoip": [
"private"
],
"outbound": "direct"
}
],
"default_domain_resolver": "local",
"auto_detect_interface": true
}
}
@@ -271,6 +290,54 @@ flowchart TB
=== ":material-dns: DNS rules"
```json
{
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"address": "223.5.5.5",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
},
{
"clash_mode": "Direct",
"server": "local"
},
{
"clash_mode": "Global",
"server": "google"
},
{
"rule_set": "geosite-geolocation-cn",
"server": "local"
}
]
},
"route": {
"rule_set": [
{
"type": "remote",
"tag": "geosite-geolocation-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs"
}
]
}
}
```
=== ":material-dns: DNS rules (Enhanced, but slower) (1.9.0+)"
=== ":material-shield-off: With DNS leaks"
```json
@@ -279,20 +346,35 @@ flowchart TB
"servers": [
{
"tag": "google",
"type": "tls",
"server": "8.8.8.8"
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"type": "https",
"server": "223.5.5.5"
"address": "https://223.5.5.5/dns-query",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
},
{
"clash_mode": "Direct",
"server": "local"
},
{
"clash_mode": "Global",
"server": "google"
},
{
"rule_set": "geosite-geolocation-cn",
"server": "local"
},
{
"clash_mode": "Default",
"server": "google"
},
{
"type": "logical",
"mode": "and",
@@ -310,7 +392,6 @@ flowchart TB
]
},
"route": {
"default_domain_resolver": "local",
"rule_set": [
{
"type": "remote",
@@ -344,24 +425,35 @@ flowchart TB
}
```
=== ":material-security: Without DNS leaks, but slower"
=== ":material-security: Without DNS leaks, but slower (1.9.0-alpha.2+)"
```json
{
"dns": {
"servers": [
{
"tag": "google",
"type": "tls",
"server": "8.8.8.8"
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"type": "https",
"server": "223.5.5.5"
"address": "https://223.5.5.5/dns-query",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
},
{
"clash_mode": "Direct",
"server": "local"
},
{
"clash_mode": "Global",
"server": "google"
},
{
"rule_set": "geosite-geolocation-cn",
"server": "local"
@@ -384,7 +476,6 @@ flowchart TB
]
},
"route": {
"default_domain_resolver": "local",
"rule_set": [
{
"type": "remote",
@@ -426,13 +517,14 @@ flowchart TB
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
}
],
"route": {
"rules": [
{
"action": "sniff"
},
{
"type": "logical",
"mode": "or",
@@ -444,12 +536,20 @@ flowchart TB
"port": 53
}
],
"action": "hijack-dns"
"outbound": "dns"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"clash_mode": "Direct",
"outbound": "direct"
},
{
"clash_mode": "Global",
"outbound": "default"
},
{
"type": "logical",
"mode": "or",
@@ -465,23 +565,12 @@ flowchart TB
"protocol": "stun"
}
],
"action": "reject"
"outbound": "block"
},
{
"rule_set": "geosite-geolocation-cn",
"outbound": "direct"
},
{
"type": "logical",
"mode": "and",
"rules": [
{
"rule_set": "geoip-cn"
},
{
"rule_set": "geosite-geolocation-!cn",
"invert": true
}
"rule_set": [
"geoip-cn",
"geosite-geolocation-cn"
],
"outbound": "direct"
}
@@ -502,4 +591,4 @@ flowchart TB
]
}
}
```
```

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.10-0.20250630100036-8763c24e4935
github.com/sagernet/sing-tun v0.6.10-0.20250620051458-5e343c4b66b2
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.10-0.20250630100036-8763c24e4935 h1:wha4BG4mrEKaIoouVyiU5BcPfKD1n0LkiL4vqdjaVps=
github.com/sagernet/sing-tun v0.6.10-0.20250630100036-8763c24e4935/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE=
github.com/sagernet/sing-tun v0.6.10-0.20250620051458-5e343c4b66b2 h1:ykbqGFHDNVvp0jhgLime/XBAtQpcOcFpT8Rs5Hcc5n4=
github.com/sagernet/sing-tun v0.6.10-0.20250620051458-5e343c4b66b2/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=

View File

@@ -91,7 +91,6 @@ type DialerOptions struct {
type _DomainResolveOptions struct {
Server string `json:"server"`
Strategy DomainStrategy `json:"strategy,omitempty"`
Timeout badoption.Duration `json:"timeout,omitempty"`
DisableCache bool `json:"disable_cache,omitempty"`
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
@@ -103,7 +102,6 @@ func (o DomainResolveOptions) MarshalJSON() ([]byte, error) {
if o.Server == "" {
return []byte("{}"), nil
} else if o.Strategy == DomainStrategy(C.DomainStrategyAsIS) &&
o.Timeout == 0 &&
!o.DisableCache &&
o.RewriteTTL == nil &&
o.ClientSubnet == nil {

View File

@@ -180,7 +180,6 @@ func (r *RouteOptionsActionOptions) UnmarshalJSON(data []byte) error {
type DNSRouteActionOptions struct {
Server string `json:"server,omitempty"`
Strategy DomainStrategy `json:"strategy,omitempty"`
Timeout badoption.Duration `json:"timeout,omitempty"`
DisableCache bool `json:"disable_cache,omitempty"`
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
@@ -188,7 +187,6 @@ type DNSRouteActionOptions struct {
type _DNSRouteOptionsActionOptions struct {
Strategy DomainStrategy `json:"strategy,omitempty"`
Timeout badoption.Duration `json:"timeout,omitempty"`
DisableCache bool `json:"disable_cache,omitempty"`
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`

View File

@@ -205,10 +205,6 @@ func (h *inboundTransportHandler) NewConnectionEx(ctx context.Context, conn net.
var metadata adapter.InboundContext
metadata.Source = source
metadata.Destination = destination
//nolint:staticcheck
metadata.InboundDetour = h.listener.ListenOptions().Detour
//nolint:staticcheck
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
(*Inbound)(h).NewConnectionEx(ctx, conn, metadata, onClose)
}

View File

@@ -219,10 +219,6 @@ func (h *inboundTransportHandler) NewConnectionEx(ctx context.Context, conn net.
var metadata adapter.InboundContext
metadata.Source = source
metadata.Destination = destination
//nolint:staticcheck
metadata.InboundDetour = h.listener.ListenOptions().Detour
//nolint:staticcheck
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
(*Inbound)(h).NewConnectionEx(ctx, conn, metadata, onClose)
}

View File

@@ -76,7 +76,6 @@ func NewNetworkManager(ctx context.Context, logger logger.ContextLogger, routeOp
DomainResolver: defaultDomainResolver.Server,
DomainResolveOptions: adapter.DNSQueryOptions{
Strategy: C.DomainStrategy(defaultDomainResolver.Strategy),
Timeout: time.Duration(defaultDomainResolver.Timeout),
DisableCache: defaultDomainResolver.DisableCache,
RewriteTTL: defaultDomainResolver.RewriteTTL,
ClientSubnet: defaultDomainResolver.ClientSubnet.Build(netip.Prefix{}),

View File

@@ -501,9 +501,6 @@ func (r *Router) actionSniff(
if inputConn != nil {
if len(action.StreamSniffers) == 0 && len(action.PacketSniffers) > 0 {
return
} else if metadata.SniffError != nil && !errors.Is(metadata.SniffError, sniff.ErrNeedMoreData) {
r.logger.DebugContext(ctx, "packet sniff skipped due to previous error: ", metadata.SniffError)
return
}
var streamSniffers []sniff.StreamSniffer
if len(action.StreamSniffers) > 0 {
@@ -528,7 +525,6 @@ func (r *Router) actionSniff(
action.Timeout,
streamSniffers...,
)
metadata.SniffError = err
if err == nil {
//goland:noinspection GoDeprecation
if action.OverrideDestination && M.IsDomainName(metadata.Domain) {
@@ -553,8 +549,8 @@ func (r *Router) actionSniff(
} else if inputPacketConn != nil {
if len(action.PacketSniffers) == 0 && len(action.StreamSniffers) > 0 {
return
} else if metadata.SniffError != nil && !errors.Is(metadata.SniffError, sniff.ErrNeedMoreData) {
r.logger.DebugContext(ctx, "packet sniff skipped due to previous error: ", metadata.SniffError)
} else if metadata.PacketSniffError != nil && !errors.Is(metadata.PacketSniffError, sniff.ErrNeedMoreData) {
r.logger.DebugContext(ctx, "packet sniff skipped due to previous error: ", metadata.PacketSniffError)
return
}
var packetSniffers []sniff.PacketSniffer
@@ -602,7 +598,7 @@ func (r *Router) actionSniff(
return
}
} else {
if len(packetBuffers) > 0 || metadata.SniffError != nil {
if len(packetBuffers) > 0 || metadata.PacketSniffError != nil {
err = sniff.PeekPacket(
ctx,
metadata,
@@ -622,7 +618,7 @@ func (r *Router) actionSniff(
Destination: destination,
}
packetBuffers = append(packetBuffers, packetBuffer)
metadata.SniffError = err
metadata.PacketSniffError = err
if errors.Is(err, sniff.ErrNeedMoreData) {
// TODO: replace with generic message when there are more multi-packet protocols
r.logger.DebugContext(ctx, "attempt to sniff fragmented QUIC client hello")
@@ -666,7 +662,6 @@ func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundCon
addresses, err := r.dns.Lookup(adapter.WithContext(ctx, metadata), metadata.Destination.Fqdn, adapter.DNSQueryOptions{
Transport: transport,
Strategy: action.Strategy,
Timeout: action.Timeout,
DisableCache: action.DisableCache,
RewriteTTL: action.RewriteTTL,
ClientSubnet: action.ClientSubnet,

View File

@@ -113,7 +113,6 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
Server: action.RouteOptions.Server,
RuleActionDNSRouteOptions: RuleActionDNSRouteOptions{
Strategy: C.DomainStrategy(action.RouteOptions.Strategy),
Timeout: time.Duration(action.RouteOptions.Timeout),
DisableCache: action.RouteOptions.DisableCache,
RewriteTTL: action.RouteOptions.RewriteTTL,
ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptions.ClientSubnet)),
@@ -122,7 +121,6 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
case C.RuleActionTypeRouteOptions:
return &RuleActionDNSRouteOptions{
Strategy: C.DomainStrategy(action.RouteOptionsOptions.Strategy),
Timeout: time.Duration(action.RouteOptionsOptions.Timeout),
DisableCache: action.RouteOptionsOptions.DisableCache,
RewriteTTL: action.RouteOptionsOptions.RewriteTTL,
ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptionsOptions.ClientSubnet)),
@@ -237,13 +235,20 @@ func (r *RuleActionDNSRoute) Type() string {
func (r *RuleActionDNSRoute) String() string {
var descriptions []string
descriptions = append(descriptions, r.Server)
descriptions = append(descriptions, r.Descriptions()...)
if r.DisableCache {
descriptions = append(descriptions, "disable-cache")
}
if r.RewriteTTL != nil {
descriptions = append(descriptions, F.ToString("rewrite-ttl=", *r.RewriteTTL))
}
if r.ClientSubnet.IsValid() {
descriptions = append(descriptions, F.ToString("client-subnet=", r.ClientSubnet))
}
return F.ToString("route(", strings.Join(descriptions, ","), ")")
}
type RuleActionDNSRouteOptions struct {
Strategy C.DomainStrategy
Timeout time.Duration
DisableCache bool
RewriteTTL *uint32
ClientSubnet netip.Prefix
@@ -254,17 +259,7 @@ func (r *RuleActionDNSRouteOptions) Type() string {
}
func (r *RuleActionDNSRouteOptions) String() string {
return F.ToString("route-options(", strings.Join(r.Descriptions(), ","), ")")
}
func (r *RuleActionDNSRouteOptions) Descriptions() []string {
var descriptions []string
if r.Strategy != C.DomainStrategyAsIS {
descriptions = append(descriptions, F.ToString("strategy=", option.DomainStrategy(r.Strategy)))
}
if r.Timeout > 0 {
descriptions = append(descriptions, F.ToString("timeout=", r.Timeout.String()))
}
if r.DisableCache {
descriptions = append(descriptions, "disable-cache")
}
@@ -274,7 +269,7 @@ func (r *RuleActionDNSRouteOptions) Descriptions() []string {
if r.ClientSubnet.IsValid() {
descriptions = append(descriptions, F.ToString("client-subnet=", r.ClientSubnet))
}
return descriptions
return F.ToString("route-options(", strings.Join(descriptions, ","), ")")
}
type RuleActionDirect struct {
@@ -426,7 +421,6 @@ func (r *RuleActionSniff) String() string {
type RuleActionResolve struct {
Server string
Strategy C.DomainStrategy
Timeout time.Duration
DisableCache bool
RewriteTTL *uint32
ClientSubnet netip.Prefix
@@ -444,9 +438,6 @@ func (r *RuleActionResolve) String() string {
if r.Strategy != C.DomainStrategyAsIS {
options = append(options, F.ToString(option.DomainStrategy(r.Strategy)))
}
if r.Timeout > 0 {
options = append(options, F.ToString("timeout=", r.Timeout.String()))
}
if r.DisableCache {
options = append(options, "disable_cache")
}