From 99093346758e6fa1eae88b4caed1656e7bbdf985 Mon Sep 17 00:00:00 2001 From: hiddifydeveloper Date: Mon, 20 Jul 2026 20:04:27 +0330 Subject: [PATCH] Add TrustTunnel Cherry-picked from xchacha20-poly1305/sing-box@45d3fe09f66cab657cfb9a037ebf7412c12845d9. Also fixes test/go.mod, which was missing three replace directives present in the root go.mod (kianmhz/GooseRelayVPN, sagernet/sing-vmess, Diniboy1123/connect-ip-go) and had stale indirect dependency versions. This pre-existing drift blocked any `go vet`/`go test` in test/ entirely, independent of TrustTunnel; fixing it was required to verify this change. (cherry picked from commit 45d3fe09f66cab657cfb9a037ebf7412c12845d9) --- constant/proxy.go | 3 + docs/configuration/inbound/index.md | 4 +- docs/configuration/inbound/index.zh.md | 4 +- docs/configuration/inbound/trusttunnel.md | 80 +++++++++ docs/configuration/inbound/trusttunnel.zh.md | 80 +++++++++ docs/configuration/outbound/index.md | 1 + docs/configuration/outbound/index.zh.md | 1 + docs/configuration/outbound/trusttunnel.md | 85 ++++++++++ docs/configuration/outbound/trusttunnel.zh.md | 85 ++++++++++ go.mod | 1 + go.sum | 2 + include/registry.go | 3 + option/trusttunnel.go | 24 +++ protocol/trusttunnel/inbound.go | 157 ++++++++++++++++++ protocol/trusttunnel/outbound.go | 136 +++++++++++++++ test/go.mod | 111 +++++++------ test/go.sum | 78 +++++++++ test/trusttunnel_quic_test.go | 104 ++++++++++++ test/trusttunnel_test.go | 101 +++++++++++ 19 files changed, 1009 insertions(+), 51 deletions(-) create mode 100644 docs/configuration/inbound/trusttunnel.md create mode 100644 docs/configuration/inbound/trusttunnel.zh.md create mode 100644 docs/configuration/outbound/trusttunnel.md create mode 100644 docs/configuration/outbound/trusttunnel.zh.md create mode 100644 option/trusttunnel.go create mode 100644 protocol/trusttunnel/inbound.go create mode 100644 protocol/trusttunnel/outbound.go create mode 100644 test/trusttunnel_quic_test.go create mode 100644 test/trusttunnel_test.go diff --git a/constant/proxy.go b/constant/proxy.go index 65c2654e49..2c8083479f 100644 --- a/constant/proxy.go +++ b/constant/proxy.go @@ -56,6 +56,7 @@ const ( TypeDNSTT = "dnstt" //H TypeGooseRelay = "gooserelay" //H TypeSmartDNSPool = "smart_dns_pool" //H — local recursive-resolver pool with AIMD throttling + recovery probing (github.com/hiddify/hmrd_multi_resolver_dns) + TypeTrustTunnel = "trusttunnel" ) const ( @@ -145,6 +146,8 @@ func ProxyDisplayName(proxyType string) string { return "DNSTT" case TypeGooseRelay: return "GooseRelay" + case TypeTrustTunnel: + return "TrustTunnel" case TypeSelector: return "Selector" case TypeURLTest: diff --git a/docs/configuration/inbound/index.md b/docs/configuration/inbound/index.md index 3041a9e716..19a1596983 100644 --- a/docs/configuration/inbound/index.md +++ b/docs/configuration/inbound/index.md @@ -32,7 +32,7 @@ | `hysteria2` | [Hysteria2](./hysteria2/) | :material-close: | | `vless` | [VLESS](./vless/) | TCP | | `anytls` | [AnyTLS](./anytls/) | TCP | -| `snell` | [Snell](./snell/) | TCP | +| `trusttunnel` | [TrustTunnel](./trusttunnel/) | TCP | | `tun` | [Tun](./tun/) | :material-close: | | `redirect` | [Redirect](./redirect/) | :material-close: | | `tproxy` | [TProxy](./tproxy/) | :material-close: | @@ -40,4 +40,4 @@ #### tag -The tag of the inbound. \ No newline at end of file +The tag of the inbound. diff --git a/docs/configuration/inbound/index.zh.md b/docs/configuration/inbound/index.zh.md index 0baf7ed963..628e072cd7 100644 --- a/docs/configuration/inbound/index.zh.md +++ b/docs/configuration/inbound/index.zh.md @@ -32,7 +32,7 @@ | `hysteria2` | [Hysteria2](./hysteria2/) | :material-close: | | `vless` | [VLESS](./vless/) | TCP | | `anytls` | [AnyTLS](./anytls/) | TCP | -| `snell` | [Snell](./snell/) | TCP | +| `trusttunnel` | [TrustTunnel](./trusttunnel/) | TCP | | `tun` | [Tun](./tun/) | :material-close: | | `redirect` | [Redirect](./redirect/) | :material-close: | | `tproxy` | [TProxy](./tproxy/) | :material-close: | @@ -40,4 +40,4 @@ #### tag -入站的标签。 \ No newline at end of file +入站的标签。 diff --git a/docs/configuration/inbound/trusttunnel.md b/docs/configuration/inbound/trusttunnel.md new file mode 100644 index 0000000000..9daa661d87 --- /dev/null +++ b/docs/configuration/inbound/trusttunnel.md @@ -0,0 +1,80 @@ +--- +icon: material/new-box +--- + +!!! question "Since sing-box 1.14.0" + +### Structure + +```json +{ + "type": "trusttunnel", + "tag": "trusttunnel-in", + + ... // Listen Fields + + "users": [ + { + "username": "trust", + "password": "tunnel" + } + ], + "quic_congestion_control": "bbr", + "network": "tcp,udp", + "tls": {} +} +``` + +### Listen Fields + +See [Listen Fields](/configuration/shared/listen/) for details. + +### Fields + +#### users + +==Required== + +TrustTunnel user list. + +#### users.username + +==Required== + +TrustTunnel username. + +#### users.password + +==Required== + +TrustTunnel user password. + +#### quic_congestion_control + +QUIC congestion control algorithm. + +| Algorithm | Description | +|-----------|-------------| +| `bbr` | BBR | +| `bbr_standard` | BBR (Standard version) | +| `bbr2` | BBRv2 | +| `bbr_variant` | BBRv2 (An experimental variant) | +| `cubic` | CUBIC | +| `reno` | New Reno | + +`bbr` is used by default. + +#### network + +Network list. + +Available values: + +- `tcp` (HTTP/2) +- `udp` (HTTP/3) + +When `udp` is enabled, `tls` must be enabled. + +#### tls + +Inbound TLS configuration, see [TLS](/configuration/shared/tls/#inbound). diff --git a/docs/configuration/inbound/trusttunnel.zh.md b/docs/configuration/inbound/trusttunnel.zh.md new file mode 100644 index 0000000000..c007503eee --- /dev/null +++ b/docs/configuration/inbound/trusttunnel.zh.md @@ -0,0 +1,80 @@ +--- +icon: material/new-box +--- + +!!! question "自 sing-box 1.14.0 起" + +### 结构 + +```json +{ + "type": "trusttunnel", + "tag": "trusttunnel-in", + + ... // 监听字段 + + "users": [ + { + "username": "trust", + "password": "tunnel" + } + ], + "quic_congestion_control": "bbr", + "network": "tcp,udp", + "tls": {} +} +``` + +### 监听字段 + +监听字段参阅 [监听字段](/zh/configuration/shared/listen/)。 + +### 字段 + +#### users + +==必填== + +TrustTunnel 用户列表。 + +#### users.username + +==必填== + +TrustTunnel 用户名。 + +#### users.password + +==必填== + +TrustTunnel 用户密码。 + +#### quic_congestion_control + +QUIC 拥塞控制算法。 + +| 算法 | 描述 | +|------|------| +| `bbr` | BBR | +| `bbr_standard` | BBR (标准版) | +| `bbr2` | BBRv2 | +| `bbr_variant` | BBRv2 (一种试验变体) | +| `cubic` | CUBIC | +| `reno` | New Reno | + +默认使用 `bbr`。 + +#### network + +网络列表。 + +可选值: + +- `tcp` (HTTP/2) +- `udp` (HTTP/3) + +当启用 `udp` 时,必须启用 `tls`。 + +#### tls + +入站 TLS 配置,参阅 [TLS](/zh/configuration/shared/tls/#inbound)。 diff --git a/docs/configuration/outbound/index.md b/docs/configuration/outbound/index.md index 5ef0476ef5..b69f404c45 100644 --- a/docs/configuration/outbound/index.md +++ b/docs/configuration/outbound/index.md @@ -41,6 +41,7 @@ | `selector` | [Selector](./selector/) | | `urltest` | [URLTest](./urltest/) | | `naive` | [NaiveProxy](./naive/) | +| `trusttunnel` | [TrustTunnel](./trusttunnel/) | #### tag diff --git a/docs/configuration/outbound/index.zh.md b/docs/configuration/outbound/index.zh.md index a4bcbc8a83..db75cce2b7 100644 --- a/docs/configuration/outbound/index.zh.md +++ b/docs/configuration/outbound/index.zh.md @@ -41,6 +41,7 @@ | `selector` | [Selector](./selector/) | | `urltest` | [URLTest](./urltest/) | | `naive` | [NaiveProxy](./naive/) | +| `trusttunnel` | [TrustTunnel](./trusttunnel/) | #### tag diff --git a/docs/configuration/outbound/trusttunnel.md b/docs/configuration/outbound/trusttunnel.md new file mode 100644 index 0000000000..ba18894fa0 --- /dev/null +++ b/docs/configuration/outbound/trusttunnel.md @@ -0,0 +1,85 @@ +--- +icon: material/new-box +--- + +!!! question "Since sing-box 1.14.0" + +### Structure + +```json +{ + "type": "trusttunnel", + "tag": "trusttunnel-out", + + "server": "127.0.0.1", + "server_port": 443, + "username": "trust", + "password": "tunnel", + "health_check": true, + "quic": false, + "quic_congestion_control": "bbr", + "tls": {}, + + ... // Dial Fields +} +``` + +### Fields + +#### server + +==Required== + +The server address. + +#### server_port + +==Required== + +The server port. + +#### username + +==Required== + +Authentication username. + +#### password + +Authentication password. + +#### health_check + +Enable periodic health check. + +#### quic + +Use QUIC transport. + +- `false`: Use HTTP/2 over TCP. +- `true`: Use HTTP/3 over UDP. + +#### quic_congestion_control + +QUIC congestion control algorithm. + +| Algorithm | Description | +|-----------|-------------| +| `bbr` | BBR | +| `bbr_standard` | BBR (Standard version) | +| `bbr2` | BBRv2 | +| `bbr_variant` | BBRv2 (An experimental variant) | +| `cubic` | CUBIC | +| `reno` | New Reno | + +`bbr` is used by default. + +#### tls + +==Required== + +Outbound TLS configuration, see [TLS](/configuration/shared/tls/#outbound). + +### Dial Fields + +See [Dial Fields](/configuration/shared/dial/) for details. diff --git a/docs/configuration/outbound/trusttunnel.zh.md b/docs/configuration/outbound/trusttunnel.zh.md new file mode 100644 index 0000000000..d779855db7 --- /dev/null +++ b/docs/configuration/outbound/trusttunnel.zh.md @@ -0,0 +1,85 @@ +--- +icon: material/new-box +--- + +!!! question "自 sing-box 1.14.0 起" + +### 结构 + +```json +{ + "type": "trusttunnel", + "tag": "trusttunnel-out", + + "server": "127.0.0.1", + "server_port": 443, + "username": "trust", + "password": "tunnel", + "health_check": true, + "quic": false, + "quic_congestion_control": "bbr", + "tls": {}, + + ... // 拨号字段 +} +``` + +### 字段 + +#### server + +==必填== + +服务器地址。 + +#### server_port + +==必填== + +服务器端口。 + +#### username + +==必填== + +认证用户名。 + +#### password + +认证密码。 + +#### health_check + +启用周期性健康检查。 + +#### quic + +使用 QUIC 传输。 + +- `false`:使用基于 TCP 的 HTTP/2。 +- `true`:使用基于 UDP 的 HTTP/3。 + +#### quic_congestion_control + +QUIC 拥塞控制算法。 + +| 算法 | 描述 | +|------|------| +| `bbr` | BBR | +| `bbr_standard` | BBR (标准版) | +| `bbr2` | BBRv2 | +| `bbr_variant` | BBRv2 (一种试验变体) | +| `cubic` | CUBIC | +| `reno` | New Reno | + +默认使用 `bbr`。 + +#### tls + +==必填== + +出站 TLS 配置,参阅 [TLS](/zh/configuration/shared/tls/#outbound)。 + +### 拨号字段 + +拨号字段参阅 [拨号字段](/zh/configuration/shared/dial/)。 diff --git a/go.mod b/go.mod index 16f7c0081c..b5e7bd7b7c 100644 --- a/go.mod +++ b/go.mod @@ -72,6 +72,7 @@ require ( github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 github.com/vishvananda/netns v0.0.5 + github.com/xchacha20-poly1305/sing-trusttunnel v0.2.1 github.com/yosida95/uritemplate/v3 v3.0.2 go.uber.org/zap v1.27.1 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba diff --git a/go.sum b/go.sum index b2f3075e26..2eddbf4fc4 100644 --- a/go.sum +++ b/go.sum @@ -603,6 +603,8 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xchacha20-poly1305/sing-trusttunnel v0.2.1 h1:3Hqp6hP3l8X4153tGrKLA5Uonh/66zhbp7HgaeC0lyE= +github.com/xchacha20-poly1305/sing-trusttunnel v0.2.1/go.mod h1:DwhGZ+Xy+r2LCoqVgGgk4opoiCRbrwNzcn41OePwIrU= github.com/xtaci/kcp-go/v5 v5.6.70 h1:AYX0QZl6PqmNj2IdYGZGuBfZuDUkUfl+eHYNijCqaO0= github.com/xtaci/kcp-go/v5 v5.6.70/go.mod h1:9O3D8WR+cyyUjGiTILYfg17vn72otWuXK2AFfqIe6CM= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM= diff --git a/include/registry.go b/include/registry.go index 3ec27574ab..e2a5fe874c 100644 --- a/include/registry.go +++ b/include/registry.go @@ -43,6 +43,7 @@ import ( "github.com/sagernet/sing-box/protocol/ssh" "github.com/sagernet/sing-box/protocol/tor" "github.com/sagernet/sing-box/protocol/trojan" + "github.com/sagernet/sing-box/protocol/trusttunnel" "github.com/sagernet/sing-box/protocol/tun" "github.com/sagernet/sing-box/protocol/tunnel" "github.com/sagernet/sing-box/protocol/vless" @@ -82,6 +83,7 @@ func InboundRegistry() *inbound.Registry { anytls.RegisterInbound(registry) mieru.RegisterInbound(registry) ssh.RegisterInbound(registry) + trusttunnel.RegistryInbound(registry) registerQUICInbounds(registry) registerCloudflaredInbound(registry) @@ -122,6 +124,7 @@ func OutboundRegistry() *outbound.Registry { balancer.RegisterLoadBalance(registry) registerMASQUEOutbound(registry) legacyWireguard.RegisterOutbound(registry) //H + trusttunnel.RegisterOutbound(registry) registerQUICOutbounds(registry) registerStubForRemovedOutbounds(registry) diff --git a/option/trusttunnel.go b/option/trusttunnel.go new file mode 100644 index 0000000000..98e0e46466 --- /dev/null +++ b/option/trusttunnel.go @@ -0,0 +1,24 @@ +package option + +import ( + "github.com/sagernet/sing/common/auth" +) + +type TrustTunnelInboundOptions struct { + ListenOptions + Users []auth.User `json:"users,omitempty"` + QUICCongestionControl string `json:"quic_congestion_control,omitempty"` + Network NetworkList `json:"network,omitempty"` + InboundTLSOptionsContainer +} + +type TrustTunnelOutboundOptions struct { + DialerOptions + ServerOptions + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + HealthCheck bool `json:"health_check,omitempty"` + QUIC bool `json:"quic,omitempty"` + QUICCongestionControl string `json:"quic_congestion_control,omitempty"` + OutboundTLSOptionsContainer +} diff --git a/protocol/trusttunnel/inbound.go b/protocol/trusttunnel/inbound.go new file mode 100644 index 0000000000..03f1703a19 --- /dev/null +++ b/protocol/trusttunnel/inbound.go @@ -0,0 +1,157 @@ +package trusttunnel + +import ( + "context" + "net" + + "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing-box/adapter/inbound" + "github.com/sagernet/sing-box/common/listener" + "github.com/sagernet/sing-box/common/tls" + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/auth" + E "github.com/sagernet/sing/common/exceptions" + M "github.com/sagernet/sing/common/metadata" + N "github.com/sagernet/sing/common/network" + + "github.com/xchacha20-poly1305/sing-trusttunnel" +) + +func RegistryInbound(registry *inbound.Registry) { + inbound.Register[option.TrustTunnelInboundOptions](registry, C.TypeTrustTunnel, NewInbound) +} + +type Inbound struct { + inbound.Adapter + ctx context.Context + logger log.ContextLogger + router adapter.ConnectionRouterEx + listener *listener.Listener + service *trusttunnel.Service + tlsConfig tls.ServerConfig + network []string +} + +func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TrustTunnelInboundOptions) (adapter.Inbound, error) { + network := options.Network.Build() + if common.Contains(network, N.NetworkUDP) { + if options.TLS == nil || !options.TLS.Enabled { + return nil, C.ErrTLSRequired + } + } + if len(options.Users) == 0 { + return nil, E.New("missing users") + } + if invalidIndex := common.Index(options.Users, func(it auth.User) bool { + return it.Username == "" || it.Password == "" + }); invalidIndex >= 0 { + return nil, E.New("missing username or password of user ", invalidIndex) + } + inbound := &Inbound{ + Adapter: inbound.NewAdapter(C.TypeTrustTunnel, tag), + ctx: ctx, + logger: logger, + router: router, + listener: listener.New(listener.Options{ + Context: ctx, + Logger: logger, + Listen: options.ListenOptions, + }), + network: network, + } + inbound.service = trusttunnel.NewService(trusttunnel.ServiceOptions{ + Ctx: ctx, + Logger: logger, + Handler: inbound, + ICMPHandler: nil, + QUICCongestionControl: options.QUICCongestionControl, + }) + if options.TLS != nil { + tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS)) + if err != nil { + return nil, err + } + inbound.tlsConfig = tlsConfig + } + inbound.service.UpdateUsers(options.Users) + return inbound, nil +} + +func (h *Inbound) Start(stage adapter.StartStage) (err error) { + if stage != adapter.StartStateStart { + return + } + if h.tlsConfig != nil { + err = h.tlsConfig.Start() + if err != nil { + err = E.Cause(err, "start TLS config") + return + } + } + var ( + tcpListener net.Listener + udpConn net.PacketConn + ) + if common.Contains(h.network, N.NetworkTCP) { + tcpListener, err = h.listener.ListenTCP() + if err != nil { + _ = common.Close(h.listener) + return + } + } + if common.Contains(h.network, N.NetworkUDP) { + udpConn, err = h.listener.ListenUDP() + if err != nil { + _ = common.Close(h.tlsConfig, tcpListener) + return + } + } + err = h.service.Start(tcpListener, udpConn, h.tlsConfig) + if err != nil { + _ = common.Close(h.tlsConfig, tcpListener, udpConn) + return + } + return +} + +func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) { + ctx = log.ContextWithNewID(ctx) + username, _ := auth.UserFromContext[string](ctx) + metadata := adapter.InboundContext{ + Inbound: h.Tag(), + InboundType: h.Type(), + //nolint:staticcheck + InboundDetour: h.listener.ListenOptions().Detour, + OriginDestination: h.listener.UDPAddr(), + Source: source, + Destination: destination, + User: username, + } + h.router.RouteConnectionEx(ctx, conn, metadata, onClose) +} + +func (h *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) { + ctx = log.ContextWithNewID(ctx) + username, _ := auth.UserFromContext[string](ctx) + metadata := adapter.InboundContext{ + Inbound: h.Tag(), + InboundType: h.Type(), + //nolint:staticcheck + InboundDetour: h.listener.ListenOptions().Detour, + //nolint:staticcheck + Source: source, + Destination: destination, + User: username, + } + h.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose) +} + +func (h *Inbound) Close() error { + return common.Close( + h.service, + h.tlsConfig, + ) +} diff --git a/protocol/trusttunnel/outbound.go b/protocol/trusttunnel/outbound.go new file mode 100644 index 0000000000..78d3cdf467 --- /dev/null +++ b/protocol/trusttunnel/outbound.go @@ -0,0 +1,136 @@ +package trusttunnel + +import ( + "context" + "net" + "net/netip" + + "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing-box/adapter/outbound" + "github.com/sagernet/sing-box/common/dialer" + "github.com/sagernet/sing-box/common/tls" + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/bufio" + E "github.com/sagernet/sing/common/exceptions" + M "github.com/sagernet/sing/common/metadata" + N "github.com/sagernet/sing/common/network" + "github.com/sagernet/sing/service" + + "github.com/xchacha20-poly1305/sing-trusttunnel" +) + +func init() { + trusttunnel.ErrQUICNotIncluded = C.ErrQUICNotIncluded +} + +func RegisterOutbound(registry *outbound.Registry) { + outbound.Register[option.TrustTunnelOutboundOptions](registry, C.TypeTrustTunnel, NewOutbound) +} + +type Outbound struct { + outbound.Adapter + ctx context.Context + logger log.ContextLogger + client *trusttunnel.Client + dnsRouter adapter.DNSRouter +} + +func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TrustTunnelOutboundOptions) (adapter.Outbound, error) { + if options.TLS == nil || !options.TLS.Enabled { + return nil, C.ErrTLSRequired + } + if options.Username == "" || options.Password == "" { + return nil, E.New("require auth") + } + detour, err := dialer.New(ctx, options.DialerOptions, options.ServerIsDomain()) + if err != nil { + return nil, err + } + server := options.ServerOptions.Build() + tlsConfig, err := tls.NewClient(ctx, logger, server.String(), *options.TLS) + if err != nil { + return nil, err + } + dnsRouter := service.FromContext[adapter.DNSRouter](ctx) + client, err := trusttunnel.NewClient(trusttunnel.ClientOptions{ + Ctx: ctx, + Detour: detour, + Server: server, + Auth: auth.User{ + Username: options.Username, + Password: options.Password, + }, + TLSConfig: tlsConfig, + QUIC: options.QUIC, + QUICCongestionControl: options.QUICCongestionControl, + HealthCheck: options.HealthCheck, + ResolveFunc: func(fqdn string) (netip.Addr, error) { + addresses, lookupErr := dnsRouter.Lookup(ctx, fqdn, adapter.DNSQueryOptions{}) + if lookupErr != nil { + return netip.Addr{}, lookupErr + } + return addresses[0], nil + }, + }) + if err != nil { + return nil, err + } + return &Outbound{ + Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTrustTunnel, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.DialerOptions), + ctx: ctx, + logger: logger, + client: client, + dnsRouter: dnsRouter, + }, nil +} + +func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { + switch network { + case N.NetworkTCP: + ctx, metadata := adapter.ExtendContext(ctx) + metadata.Outbound = h.Tag() + metadata.Destination = destination + h.logger.InfoContext(ctx, "outbound connection to ", destination) + return h.client.Dial(ctx, destination) + case N.NetworkUDP: + if destination.IsDomain() { + addresses, err := h.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{}) + if err != nil { + return nil, err + } + destination = M.Socksaddr{ + Addr: addresses[0], + Port: destination.Port, + } + } + packetConn, err := h.ListenPacket(ctx, destination) + if err != nil { + return nil, err + } + return bufio.NewBindPacketConn(packetConn, destination), nil + default: + return nil, E.Extend(N.ErrUnknownNetwork, network) + } +} + +func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { + ctx, metadata := adapter.ExtendContext(ctx) + metadata.Outbound = h.Tag() + metadata.Destination = destination + h.logger.InfoContext(ctx, "outbound packet connection to ", destination) + return h.client.ListenPacket(ctx) +} + +func (h *Outbound) InterfaceUpdated() { + h.client.ResetConnections() +} + +func (h *Outbound) Close() error { + return common.Close( + common.PtrOrNil(h.client), + ) +} diff --git a/test/go.mod b/test/go.mod index 41c73441ac..cbbfb833a0 100644 --- a/test/go.mod +++ b/test/go.mod @@ -1,6 +1,6 @@ module test -go 1.24.7 +go 1.25.6 require github.com/sagernet/sing-box v0.0.0 @@ -20,13 +20,19 @@ replace github.com/Psiphon-Labs/psiphon-tls => ../replace/psiphon-tls replace github.com/net2share/vaydns => github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9 +replace github.com/kianmhz/GooseRelayVPN => github.com/hiddify/GooseRelayVPN v0.0.0-20260429125124-0e68c2a3ae4c + +replace github.com/sagernet/sing-vmess => github.com/starifly/sing-vmess v0.2.7-mod.9 + +replace github.com/Diniboy1123/connect-ip-go => github.com/shtorm-7/connect-ip-go v1.0.0-extended-1.0.0 + require ( github.com/docker/docker v27.3.1+incompatible github.com/docker/go-connections v0.5.0 github.com/gofrs/uuid/v5 v5.4.0 github.com/sagernet/quic-go v0.59.0-sing-box-mod.4 - github.com/sagernet/sing v0.8.7-0.20260417135631-0d22698ed386 - github.com/sagernet/sing-quic v0.6.2-0.20260412143638-8f65b6be7cd6 + github.com/sagernet/sing v0.8.12-0.20260702081104-2ded2af32d3d + github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 github.com/spyzhov/ajson v0.9.4 @@ -41,7 +47,7 @@ require ( filippo.io/keygen v0.0.0-20230306160926-5201437acf8e // indirect github.com/AdguardTeam/golibs v0.32.7 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/Jigsaw-Code/outline-sdk v0.0.16 // indirect + github.com/Jigsaw-Code/outline-sdk v0.0.20 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Psiphon-Labs/bolt v0.0.0-20200624191537-23cedaef7ad7 // indirect github.com/Psiphon-Labs/consistent v0.0.0-20240322131436-20aaa4e05737 // indirect @@ -55,7 +61,7 @@ require ( github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect github.com/ameshkov/dnscrypt/v2 v2.4.0 // indirect github.com/ameshkov/dnsstamps v1.0.3 // indirect - github.com/amnezia-vpn/amneziawg-go v0.2.16 // indirect + github.com/amnezia-vpn/amneziawg-go v0.2.17-0.20251219021448-449d7cffd4ad // indirect github.com/andybalholm/brotli v1.2.0 // indirect github.com/anthropics/anthropic-sdk-go v1.26.0 // indirect github.com/anytls/sing-anytls v0.0.11 // indirect @@ -65,7 +71,7 @@ require ( github.com/biter777/countries v1.7.5 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/bits-and-blooms/bloom/v3 v3.6.0 // indirect - github.com/caddyserver/certmagic v0.25.2 // indirect + github.com/caddyserver/certmagic v0.25.3-0.20260421143802-60d9d8b415d6 // indirect github.com/caddyserver/zerossl v0.1.5 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -87,12 +93,12 @@ require ( github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/ebitengine/purego v0.9.1 // indirect + github.com/ebitengine/purego v0.10.0 // indirect github.com/enfein/mieru/v3 v3.27.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/florianl/go-nfqueue/v2 v2.0.2 // indirect github.com/flynn/noise v1.1.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gaissmai/bart v0.18.0 // indirect github.com/go-chi/chi/v5 v5.2.5 // indirect @@ -110,23 +116,31 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/google/gopacket v1.1.19 // indirect github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grafov/m3u8 v0.0.0-20171211212457-6ab8f28ed427 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect + github.com/hiddify/hmrd_multi_resolver_dns v0.0.0-20260429114007-8d809dc33d0e // indirect + github.com/huin/goupnp v1.2.0 // indirect github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 // indirect github.com/jsimonetti/rtnetlink v1.4.0 // indirect github.com/kamstrup/intmap v0.5.2 // indirect github.com/keybase/go-keychain v0.0.1 // indirect + github.com/kianmhz/GooseRelayVPN v0.0.0-20260429125124-0e68c2a3ae4c // indirect github.com/klauspost/compress v1.18.3 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/reedsolomon v1.13.0 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/libdns/acmedns v0.5.0 // indirect github.com/libdns/alidns v1.0.6 // indirect github.com/libdns/cloudflare v0.2.2 // indirect github.com/libdns/libdns v1.1.1 // indirect + github.com/libp2p/go-nat v1.0.1-0.20250821073202-01afc089f138 // indirect + github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.4.0 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/marusama/semaphore v0.0.0-20171214154724-565ffd8e868a // indirect @@ -175,49 +189,50 @@ require ( github.com/safchain/ethtool v0.3.0 // indirect github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a // indirect github.com/sagernet/cors v1.2.1 // indirect - github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa // indirect - github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa // indirect - github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect - github.com/sagernet/fswatch v0.1.1 // indirect + github.com/sagernet/cronet-go v0.0.0-20260620140045-05ab0dc17597 // indirect + github.com/sagernet/cronet-go/all v0.0.0-20260620140045-05ab0dc17597 // indirect + github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260620135226-def9ff0fb992 // indirect + github.com/sagernet/fswatch v0.1.2 // indirect github.com/sagernet/gvisor v0.0.0-20250822052253-5558536cf237 // indirect github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect - github.com/sagernet/nftables v0.3.0-beta.4 // indirect - github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9 // indirect - github.com/sagernet/sing-mux v0.3.4 // indirect - github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 // indirect - github.com/sagernet/sing-tun v0.8.8-0.20260410061515-018f5eaae695 // indirect + github.com/sagernet/nftables v0.3.0-mod.3 // indirect + github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3 // indirect + github.com/sagernet/sing-mux v0.3.5 // indirect + github.com/sagernet/sing-shadowtls v0.2.1 // indirect + github.com/sagernet/sing-snell v0.0.0-20260710094516-a4e97ee24beb // indirect + github.com/sagernet/sing-tun v0.8.12-0.20260711072757-9e647fcd6b38 // indirect github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 // indirect github.com/sagernet/smux v1.5.50-sing-box-mod.1 // indirect - github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7 // indirect - github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c // indirect + github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7.0.20260711004045-7d3e867147ad // indirect + github.com/sagernet/wireguard-go v0.0.5-0.20260706153856-2c27bbf4f97f // indirect github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 // indirect github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507 // indirect github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect @@ -230,6 +245,7 @@ require ( github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 // indirect github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 // indirect + github.com/things-go/go-socks5 v0.1.1 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect @@ -240,6 +256,7 @@ require ( github.com/wader/filtertransport v0.0.0-20200316221534-bdd9e61eee78 // indirect github.com/wlynxg/anet v0.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect + github.com/xchacha20-poly1305/sing-trusttunnel v0.2.1 // indirect github.com/xtaci/kcp-go/v5 v5.6.70 // indirect github.com/xtaci/smux v1.5.50 // indirect github.com/zeebo/blake3 v0.2.4 // indirect diff --git a/test/go.sum b/test/go.sum index 097fc845e7..236970c712 100644 --- a/test/go.sum +++ b/test/go.sum @@ -18,6 +18,8 @@ github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/k github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Jigsaw-Code/outline-sdk v0.0.16 h1:WbHmv80FKDIpzEmR3GehTbq5CibYTLvcxIIpMMILiEs= github.com/Jigsaw-Code/outline-sdk v0.0.16/go.mod h1:e1oQZbSdLJBBuHgfeQsgEkvkuyIePPwstUeZRGq0KO8= +github.com/Jigsaw-Code/outline-sdk v0.0.20 h1:4ep7MK9lFmcyPIRIbn4xrP1VKdJNsqR6+iJEOHDKnNg= +github.com/Jigsaw-Code/outline-sdk v0.0.20/go.mod h1:CFDKyGZA4zatKE4vMLe8TyQpZCyINOeRFbMAmYHxodw= github.com/Jigsaw-Code/outline-ss-server v1.8.0 h1:6h7CZsyl1vQLz3nvxmL9FbhDug4QxJ1YTxm534eye1E= github.com/Jigsaw-Code/outline-ss-server v1.8.0/go.mod h1:slnHH3OZsQmZx/DRKhxvvaGE/8+n3Lkd6363h1ev71E= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -48,6 +50,7 @@ github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1O github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A= github.com/amnezia-vpn/amneziawg-go v0.2.16 h1:XY6HOq/xtqH8ZXMncRWkjFs85EKdN10NLNnw23kTpE0= github.com/amnezia-vpn/amneziawg-go v0.2.16/go.mod h1:nRkPpIzjCxMW8pZKXTRkpqAQVlmFJdVOGkeQSC7wbms= +github.com/amnezia-vpn/amneziawg-go v0.2.17-0.20251219021448-449d7cffd4ad/go.mod h1:aMgOk9MuX0xI7b5TKAYp8pLM54RlXcOPzDvYw3YEO5A= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/anthropics/anthropic-sdk-go v1.26.0 h1:oUTzFaUpAevfuELAP1sjL6CQJ9HHAfT7CoSYSac11PY= @@ -68,6 +71,8 @@ github.com/bits-and-blooms/bloom/v3 v3.6.0 h1:dTU0OVLJSoOhz9m68FTXMFfA39nR8U/nTC github.com/bits-and-blooms/bloom/v3 v3.6.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg= github.com/caddyserver/certmagic v0.25.2 h1:D7xcS7ggX/WEY54x0czj7ioTkmDWKIgxtIi2OcQclUc= github.com/caddyserver/certmagic v0.25.2/go.mod h1:llW/CvsNmza8S6hmsuggsZeiX+uS27dkqY27wDIuBWg= +github.com/caddyserver/certmagic v0.25.3-0.20260421143802-60d9d8b415d6 h1:LYSB6VgWzKtNrcxElw3c97BP40Oc7bizKxA9K1Vi/5k= +github.com/caddyserver/certmagic v0.25.3-0.20260421143802-60d9d8b415d6/go.mod h1:llW/CvsNmza8S6hmsuggsZeiX+uS27dkqY27wDIuBWg= github.com/caddyserver/zerossl v0.1.5 h1:dkvOjBAEEtY6LIGAHei7sw2UgqSD6TrWweXpV7lvEvE= github.com/caddyserver/zerossl v0.1.5/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= @@ -132,6 +137,7 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A= github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d h1:rtM8HsT3NG37YPjz8sYSbUSdElP9lUsQENYzJDZDUBE= github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20200809112317-0581fc3aee2d h1:st1tmvy+4duoRj+RaeeJoECWCWM015fBtf/4aR+hhqk= @@ -153,6 +159,8 @@ github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gaissmai/bart v0.18.0 h1:jQLBT/RduJu0pv/tLwXE+xKPgtWJejbxuXAR+wLJafo= @@ -232,10 +240,18 @@ github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8 github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/hiddify/GooseRelayVPN v0.0.0-20260429125124-0e68c2a3ae4c h1:9Zc0hJ14G+SNJvGxtaSCSsvGB/RdLltrgjgR//9zgTQ= +github.com/hiddify/GooseRelayVPN v0.0.0-20260429125124-0e68c2a3ae4c/go.mod h1:LI/1qA7FDU3MumegfyFOHGZCXcOw6rjIk7NPXga3/pQ= +github.com/hiddify/hmrd_multi_resolver_dns v0.0.0-20260429114007-8d809dc33d0e h1:GsHpSccRtSFe1l3hq0WtBjqsKjJdU+an2D+uCsXm+xk= +github.com/hiddify/hmrd_multi_resolver_dns v0.0.0-20260429114007-8d809dc33d0e/go.mod h1:7u9Ece+I3gvMFzcpqhROWaykNUyoE21g/fYQMBasAWY= github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9 h1:KXnaABX8hHmkcL0jbL769hEIGI5+z/DajCrlO+Bkzcc= github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9/go.mod h1:+8kEfQsZJn7/4aIppVekrSuqhrKjGBIgnacTJkdAlS8= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91 h1:u9i04mGE3iliBh0EFuWaKsmcwrLacqGmq1G3XoaM7gY= github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91/go.mod h1:qfvBmyDNp+/liLEYWRvqny/PEz9hGe2Dz833eXILSmo= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0WwEDBeqxKwb7WB62QX8bvZ/FJnVXIfk= github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86/go.mod h1:aFAMtuldEgx/4q7iSGazk22+IcgvtiC+HIimFO9XlS8= github.com/jsimonetti/rtnetlink v1.4.0 h1:Z1BF0fRgcETPEa0Kt0MRk3yV5+kF1FWTni6KUFKrq2I= @@ -252,6 +268,8 @@ github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzh github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/klauspost/reedsolomon v1.13.0 h1:E0Cmgf2kMuhZTj6eefnvpKC4/Q4jhCi9YIjcZjK4arc= github.com/klauspost/reedsolomon v1.13.0/go.mod h1:ggJT9lc71Vu+cSOPBlxGvBN6TfAS77qB4fp8vJ05NSA= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -274,6 +292,10 @@ github.com/libdns/cloudflare v0.2.2 h1:XWHv+C1dDcApqazlh08Q6pjytYLgR2a+Y3xrXFu0v github.com/libdns/cloudflare v0.2.2/go.mod h1:w9uTmRCDlAoafAsTPnn2nJ0XHK/eaUMh86DUk8BWi60= github.com/libdns/libdns v1.1.1 h1:wPrHrXILoSHKWJKGd0EiAVmiJbFShguILTg9leS/P/U= github.com/libdns/libdns v1.1.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= +github.com/libp2p/go-nat v1.0.1-0.20250821073202-01afc089f138 h1:YohuNPT/1k3VcThCQlBZ43PCPWPfMRS1zcxWBF2SLK8= +github.com/libp2p/go-nat v1.0.1-0.20250821073202-01afc089f138/go.mod h1:TXQg5tfSy+bUjnhT5728j5j/MBj7keIYqqZ1+8k/ui8= +github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= +github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= @@ -411,92 +433,139 @@ github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ= github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI= github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa h1:7SehNSF1UHbLZa5dk+1rW1aperffJzl5r6TCJIXtAaY= github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa/go.mod h1:hwFHBEjjthyEquDULbr4c4ucMedp8Drb6Jvm2kt/0Bw= +github.com/sagernet/cronet-go v0.0.0-20260620140045-05ab0dc17597/go.mod h1:T/mwtrpC4JlWfScw73CmSBvHzIvc7BatQ1MhRr+cYNw= github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa h1:ijk5v9N/akiMgqu734yMpv7Pk9F4Qmjh8Vfdcb4uJHE= github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa/go.mod h1:+FENo4+0AOvH9e3oY6/iO7yy7USNt61dgbnI5W0TDZ0= +github.com/sagernet/cronet-go/all v0.0.0-20260620140045-05ab0dc17597/go.mod h1:zVHZ5tgDTwbNvUGffAgLmouYs4in0grEzhSdaggoZOw= github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b h1:O+PkYT88ayVWESX5tqxeMeS9OnzC3ZTic8gYiPJNXT8= github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw= +github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw= github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:o0MsgbsJwYkbqlbfaCvmAwb8/LAXeoSP8NE/aNvR/yY= github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM= +github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM= github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b h1:JEQnc7cRMUahWJFtWY6n0hs1LE0KgyRv3pD0RWS8Yo8= github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc= +github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260620135226-def9ff0fb992/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc= github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:69+AKzuUW9hzw2nU79c2DWfuzrIZ3PJm1KAwXh+7xr0= github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ= +github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ= github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:jp9FHUVTCJQ67Ecw3Inoct6/z1VTFXPtNYpXt47pa4E= github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs= +github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs= github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:WN3DZoECd2UbhmYQGpOA4jx4QBXiZuN1DvL/35NT61g= github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0= +github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0= github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:H4RKicwrIa4PwTXZOmXOg85hiCrpeFja4daOlX180pE= github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:hkQzRE5GDbaH1/ioqYh0Taho4L6i0yLRCVEZ5xHz5M0= +github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260620135226-def9ff0fb992/go.mod h1:hkQzRE5GDbaH1/ioqYh0Taho4L6i0yLRCVEZ5xHz5M0= github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:Rwi+Cu+Hgwj28F1lh837gGqSqn7oU8+r5i3UJyLPkKc= github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4= +github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4= github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:v2wcnPX3gt0PngFYXjXYAiarFckwx3pVAP6ETSpbSWE= github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:M/pN6m3j0HFU6/y83n0HU6GLYys3tYdr/xTE8hVEGMo= +github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260620135226-def9ff0fb992/go.mod h1:M/pN6m3j0HFU6/y83n0HU6GLYys3tYdr/xTE8hVEGMo= github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b h1:Bl0zZ3QZq6pPJMbQlYHDhhaGngVefRlFzxWc0p48eHo= github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ= +github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ= github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b h1:vf+MbGv6RvvmXUNvganykBOnDIVXxy8XgtKOOqOcxtE= github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU= +github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260620135226-def9ff0fb992/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU= github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:2IAc1bVFYF+B6hof34ChQKVhw7LElBxEEx7S0n+7o78= github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI= +github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI= github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b h1:NrJaiOS0VLmWTbUHhXDsLTqelmCW4y3xJqptPs4Sx0s= github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ= +github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260620135226-def9ff0fb992/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ= github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b h1:A+ubSkca1nl2cT8pYUqCo1O7M41suNrKpWhZKCM/aIQ= github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0= +github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260620135226-def9ff0fb992/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0= github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:WrhGH5FDXlCAoXwN6N44yCMvy6EbIurmTmptkz3mmms= github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s= +github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s= github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b h1:kgwB5p5e0gdVX5iYRE7VbZS/On4qnb4UKonkGPwhkDI= github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ= +github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260620135226-def9ff0fb992/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ= github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b h1:Z3dOeFlRIOeQhSh+mCYDHui1yR3S/Uw8eupczzBvxqw= github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow= +github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260620135226-def9ff0fb992/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow= github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b h1:LPi6jz1k11Q67hm3Pw6aaPJ/Z6e3VtNhzrRjr5/5AQo= github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:Wt5uFdU3tnmm8YzobYewwdF7Mt6SucRQg6xeTNWC3Tk= +github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:Wt5uFdU3tnmm8YzobYewwdF7Mt6SucRQg6xeTNWC3Tk= github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b h1:55sqihyfXWN7y7p7gOEgtUz9cm1mV3SDQ90/v6ROFaA= github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:lyIF6wKBLwWa5ZXaAKbAoewewl+yCHo2iYev39Mbj4E= +github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260620135226-def9ff0fb992/go.mod h1:lyIF6wKBLwWa5ZXaAKbAoewewl+yCHo2iYev39Mbj4E= github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b h1:OTA1cbv5YIDVsYA8AAXHC4NgEc7b6pDiY+edujLWfJU= github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:H46PnSTTZNcZokLLiDeMDaHiS1l14PH3tzWi0eykjD8= +github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260620135226-def9ff0fb992/go.mod h1:H46PnSTTZNcZokLLiDeMDaHiS1l14PH3tzWi0eykjD8= github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b h1:B/rdD/1A+RgqUYUZcoGhLeMqijnBd1mUt8+5LhOH7j8= github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:RBhSUDAKWq7fswtV4nQUQhuaTLcX3ettR7teA7/yf2w= +github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260620135226-def9ff0fb992/go.mod h1:RBhSUDAKWq7fswtV4nQUQhuaTLcX3ettR7teA7/yf2w= github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b h1:QFRWi6FucrODS4xQ8e9GYIzGSeMFO/DAMtTCVeJiCvM= github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:wRzoIOGG4xbpp3Gh3triLKwMwYriScXzFtunLYhY4w0= +github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260620135226-def9ff0fb992/go.mod h1:wRzoIOGG4xbpp3Gh3triLKwMwYriScXzFtunLYhY4w0= github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b h1:2WJjPKZHLNIB4D17c3o9S+SP9kb3Qh0D26oWlun1+pE= github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:LNiZXmWil1OPwKCheqQjtakZlJuKGFz+iv2eGF76Hhs= +github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:LNiZXmWil1OPwKCheqQjtakZlJuKGFz+iv2eGF76Hhs= github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b h1:cUNTe4gNncRpYL28jzQf6qcJej40zzGQsH0o6CLUGws= github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:YFDGKTkpkJGc5+hnX/RYosZyTWg9h+68VB55fYRRLYc= +github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260620135226-def9ff0fb992/go.mod h1:YFDGKTkpkJGc5+hnX/RYosZyTWg9h+68VB55fYRRLYc= github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:+sc1LJF0FjU2hVO5xBqqT+8qzoU08J2uHwxSle2m/Hw= github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:aaX0YGl8nhGmfRWI8bc3BtDjY8Vzx6O0cS/e1uqxDq4= +github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260620135226-def9ff0fb992/go.mod h1:aaX0YGl8nhGmfRWI8bc3BtDjY8Vzx6O0cS/e1uqxDq4= github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:+D/uhFxllI/KTLpeNEl8dwF3omPGmUFbrqt5tJkAyp0= github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:EdzMKA96xITc42QEI+ct4SwqX8Dn3ltKK8wzdkLWpSc= +github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:EdzMKA96xITc42QEI+ct4SwqX8Dn3ltKK8wzdkLWpSc= github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:nSUzzTUAZdqjGGckayk64sz+F0TGJPHvauTiAn27UKk= github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:qix4kv1TTAJ5tY4lJ9vjhe9EY4mM+B7H5giOhbxDVcc= +github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260620135226-def9ff0fb992/go.mod h1:qix4kv1TTAJ5tY4lJ9vjhe9EY4mM+B7H5giOhbxDVcc= github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:PE/fYBiHzB52gnQMg0soBfQyJCzmWHti48kCe2TBt9w= github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8= +github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8= github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:hy/3lPV11pKAAojDFnb95l9NpwOym6kME7FxS9p8sXs= github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw= +github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260620135226-def9ff0fb992/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw= github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs= github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o= +github.com/sagernet/fswatch v0.1.2 h1:/TT7k4mkce1qFPxamLO842WjqBgbTBiXP2mlUjp9PFk= +github.com/sagernet/fswatch v0.1.2/go.mod h1:5BpGmpUQVd3Mc5r313HRpvADHRg3/rKn5QbwFteB880= github.com/sagernet/gvisor v0.0.0-20250822052253-5558536cf237 h1:SUPFNB+vSP4RBPrSEgNII+HkfqC8hKMpYLodom4o4EU= github.com/sagernet/gvisor v0.0.0-20250822052253-5558536cf237/go.mod h1:QkkPEJLw59/tfxgapHta14UL5qMUah5NXhO0Kw2Kan4= github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis= github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I= github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= +github.com/sagernet/nftables v0.3.0-mod.3/go.mod h1:8kslHG4VvYNihcco+i6uxIX7qbT8A56T0y5q7U44ZaQ= github.com/sagernet/quic-go v0.59.0-sing-box-mod.4 h1:6qvrUW79S+CrPwWz6cMePXohgjHoKxLo3c+MDhNwc3o= github.com/sagernet/quic-go v0.59.0-sing-box-mod.4/go.mod h1:OqILvS182CyOol5zNNo6bguvOGgXzV459+chpRaUC+4= github.com/sagernet/sing v0.8.7-0.20260417135631-0d22698ed386 h1:gNonzIaoKi4MiEmK/5iJI+RoGof1PtYqzSaNE/lmWLw= github.com/sagernet/sing v0.8.7-0.20260417135631-0d22698ed386/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.8.12-0.20260702081104-2ded2af32d3d h1:BhsQU0Iug1tU4xR52cjm8Sc+LBo+KwdyLTRn3ie9moo= +github.com/sagernet/sing v0.8.12-0.20260702081104-2ded2af32d3d/go.mod h1:olXxWQNqRW/l2Q6JI3b2Qmz8iQnIFlOeeH8bx6JhgUA= github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9 h1:wWJexq4V7ope1c4XYSqT/hydqd9omdtbDRvSZIOhjfY= github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9/go.mod h1:bH2NKX+NpDTY1Zkxfboxw6MXB/ZywaNLmrDJYgKMJ2Y= +github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3/go.mod h1:XEqEDYRCAYLaoPjZ1ifVWJg5iWAJHL2gOAXe/PM28Cg= github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s= github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= +github.com/sagernet/sing-mux v0.3.5 h1:RHnhVEc+SFqkrK4xMygYjDwwLhzp2Bj3lztSukONfhI= +github.com/sagernet/sing-mux v0.3.5/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= github.com/sagernet/sing-quic v0.6.2-0.20260412143638-8f65b6be7cd6 h1:j3ISQRDyY5rs27NzUS/le+DHR0iOO0K0x+mWDLzu4Ok= github.com/sagernet/sing-quic v0.6.2-0.20260412143638-8f65b6be7cd6/go.mod h1:r5Adw0EMUyhGBCjPI2JEupDtC040DrrvreXtua7Ifdc= +github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc h1:zdc0fj4JdAdgAmQIoh7ZF+B/wPTEF2X75lYDqTmvlaw= +github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc/go.mod h1:9k+dzGsWMttUGldBzq3dU792YHXzW6NgfbOGltnXq+0= github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE= github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI= github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnqqs2gQ2/Qioo= 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-shadowtls v0.2.1 h1:ZiHZdnEnP+YS73NMsxiZmIFCwNd0M4k7PkGCKNXhbaM= +github.com/sagernet/sing-shadowtls v0.2.1/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= +github.com/sagernet/sing-snell v0.0.0-20260710094516-a4e97ee24beb h1:VvU2/PZqP5tbKTDq0BxkhRO8ZnKI4UJzziakgBiP2Qg= +github.com/sagernet/sing-snell v0.0.0-20260710094516-a4e97ee24beb/go.mod h1:PcwzX/Xvqky0EP3kGt8OCjYb3R1pydenPHNQZcPZmXY= github.com/sagernet/sing-tun v0.8.8-0.20260410061515-018f5eaae695 h1:2maqN3XuorEo5faXHIyYZQZ1/ybim4hImfCEWZwdPbk= github.com/sagernet/sing-tun v0.8.8-0.20260410061515-018f5eaae695/go.mod h1:pLCo4o+LacXEzz0bhwhJkKBjLlKOGPBNOAZ97ZVZWzs= +github.com/sagernet/sing-tun v0.8.12-0.20260711072757-9e647fcd6b38 h1:O+Ci3Re4JyPa19JqYqs116WOT29Nmo+QwTSlL3rV2Ao= +github.com/sagernet/sing-tun v0.8.12-0.20260711072757-9e647fcd6b38/go.mod h1:QvarqUtHfj1ULaRR+6kZOS/OoCE+pYGq67A5tyIy+dQ= github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkVyVvdmBSufR8/nRFonwJeKSIROxHcm5br9o= github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY= github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478= @@ -519,6 +588,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spyzhov/ajson v0.9.4 h1:MVibcTCgO7DY4IlskdqIlCmDOsUOZ9P7oKj8ifdcf84= github.com/spyzhov/ajson v0.9.4/go.mod h1:a6oSw0MMb7Z5aD2tPoPO+jq11ETKgXUr2XktHdT8Wt8= +github.com/starifly/sing-vmess v0.2.7-mod.9 h1:xobAmejSbBQ0A3f/EtJ9cJd3m6gK7dDPccPdeGz7tXY= +github.com/starifly/sing-vmess v0.2.7-mod.9/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -550,6 +621,8 @@ github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:U github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA= github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= +github.com/things-go/go-socks5 v0.1.1 h1:48hy9cHEXPKeG91G/g4n8zW4uynzPUQy/FkcrJ7r5AY= +github.com/things-go/go-socks5 v0.1.1/go.mod h1:1YBHVYG7Oli5ae+Pwkp630cPAwY1pjUPmohO1n0Emg0= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -581,6 +654,8 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xchacha20-poly1305/sing-trusttunnel v0.2.1 h1:3Hqp6hP3l8X4153tGrKLA5Uonh/66zhbp7HgaeC0lyE= +github.com/xchacha20-poly1305/sing-trusttunnel v0.2.1/go.mod h1:DwhGZ+Xy+r2LCoqVgGgk4opoiCRbrwNzcn41OePwIrU= github.com/xtaci/kcp-go/v5 v5.6.70 h1:AYX0QZl6PqmNj2IdYGZGuBfZuDUkUfl+eHYNijCqaO0= github.com/xtaci/kcp-go/v5 v5.6.70/go.mod h1:9O3D8WR+cyyUjGiTILYfg17vn72otWuXK2AFfqIe6CM= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM= @@ -660,6 +735,8 @@ golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -758,6 +835,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/test/trusttunnel_quic_test.go b/test/trusttunnel_quic_test.go new file mode 100644 index 0000000000..ca06dd4cdc --- /dev/null +++ b/test/trusttunnel_quic_test.go @@ -0,0 +1,104 @@ +//go:build with_quic + +package main + +import ( + "net/netip" + "testing" + + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/json/badoption" + "github.com/sagernet/sing/common/network" +) + +func TestTrustTunnelQUICSelf(t *testing.T) { + caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") + startInstance(t, option.Options{ + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "mixed-in", + Options: &option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: clientPort, + }, + }, + }, + { + Type: C.TypeTrustTunnel, + Tag: "trusttunnel-in", + Options: &option.TrustTunnelInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: serverPort, + }, + Users: []auth.User{ + { + Username: "sekai", + Password: "password", + }, + }, + Network: network.NetworkUDP, + InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{ + TLS: &option.InboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + ALPN: []string{"h3"}, + CertificatePath: certPem, + KeyPath: keyPem, + }, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + }, + { + Type: C.TypeTrustTunnel, + Tag: "trusttunnel-out", + Options: &option.TrustTunnelOutboundOptions{ + ServerOptions: option.ServerOptions{ + Server: "127.0.0.1", + ServerPort: serverPort, + }, + Username: "sekai", + Password: "password", + QUIC: true, + OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{ + TLS: &option.OutboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + ALPN: []string{"h3"}, + CertificatePath: caPem, + }, + }, + }, + }, + }, + Route: &option.RouteOptions{ + Rules: []option.Rule{ + { + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: []string{"mixed-in"}, + }, + RuleAction: option.RuleAction{ + Action: C.RuleActionTypeRoute, + RouteOptions: option.RouteActionOptions{ + Outbound: "trusttunnel-out", + }, + }, + }, + }, + }, + }, + }) + testSuit(t, clientPort, testPort) +} diff --git a/test/trusttunnel_test.go b/test/trusttunnel_test.go new file mode 100644 index 0000000000..8951221006 --- /dev/null +++ b/test/trusttunnel_test.go @@ -0,0 +1,101 @@ +package main + +import ( + "net/netip" + "testing" + + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/json/badoption" + "github.com/sagernet/sing/common/network" +) + +func TestTrustTunnelSelf(t *testing.T) { + _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") + startInstance(t, option.Options{ + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "mixed-in", + Options: &option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: clientPort, + }, + }, + }, + { + Type: C.TypeTrustTunnel, + Tag: "trusttunnel-in", + Options: &option.TrustTunnelInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: serverPort, + }, + Users: []auth.User{ + { + Username: "sekai", + Password: "password", + }, + }, + Network: network.NetworkTCP, + InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{ + TLS: &option.InboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + ALPN: []string{"h2"}, + CertificatePath: certPem, + KeyPath: keyPem, + }, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + }, + { + Type: C.TypeTrustTunnel, + Tag: "trusttunnel-out", + Options: &option.TrustTunnelOutboundOptions{ + ServerOptions: option.ServerOptions{ + Server: "127.0.0.1", + ServerPort: serverPort, + }, + Username: "sekai", + Password: "password", + OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{ + TLS: &option.OutboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + ALPN: []string{"h2"}, + CertificatePath: certPem, + }, + }, + }, + }, + }, + Route: &option.RouteOptions{ + Rules: []option.Rule{ + { + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: []string{"mixed-in"}, + }, + RuleAction: option.RuleAction{ + Action: C.RuleActionTypeRoute, + RouteOptions: option.RouteActionOptions{ + Outbound: "trusttunnel-out", + }, + }, + }, + }, + }, + }, + }) + testSuit(t, clientPort, testPort) +}