From 263d06d17655d2a89abd57d93a3d76e5c47ca050 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Sat, 16 May 2026 21:20:02 +0800 Subject: [PATCH] chore: allow passing tunnel when creating the proxy --- adapter/outbound/base.go | 5 +++++ adapter/parser.go | 8 ++++++++ adapter/provider/parser.go | 4 ++-- adapter/provider/provider.go | 4 ++-- config/config.go | 4 ++-- listener/inbound/anytls_test.go | 1 + listener/inbound/common_test.go | 3 +++ listener/inbound/hysteria2_test.go | 1 + listener/inbound/mieru_test.go | 1 + listener/inbound/shadowsocks_test.go | 1 + listener/inbound/sudoku_test.go | 1 + listener/inbound/trojan_test.go | 1 + listener/inbound/trusttunnel_test.go | 1 + listener/inbound/tuic_test.go | 1 + listener/inbound/vless_test.go | 1 + listener/inbound/vmess_test.go | 1 + 16 files changed, 32 insertions(+), 6 deletions(-) diff --git a/adapter/outbound/base.go b/adapter/outbound/base.go index f5ba4dbe..188af6e1 100644 --- a/adapter/outbound/base.go +++ b/adapter/outbound/base.go @@ -202,6 +202,7 @@ type BasicOption struct { // The following parameters are used internally, assign value by the structure decoder are disallowed // DialerForAPI C.Dialer `proxy:"-"` // the dialer used for API usage has higher priority than all the above configurations. + TunnelForAPI C.Tunnel `proxy:"-"` ProviderName string `proxy:"-"` } @@ -217,6 +218,10 @@ func (b *BasicOption) NewDialer(opts []dialer.Option) C.Dialer { return cDialer } +func (b *BasicOption) NewTunnel() C.Tunnel { + return b.TunnelForAPI +} + type conn struct { N.ExtendedConn chain C.Chain diff --git a/adapter/parser.go b/adapter/parser.go index 5d1433ab..2e9b347c 100644 --- a/adapter/parser.go +++ b/adapter/parser.go @@ -18,6 +18,7 @@ func ParseProxy(mapping map[string]any, options ...ProxyOption) (C.Proxy, error) opt := applyProxyOptions(options...) basicOption := outbound.BasicOption{ DialerForAPI: opt.DialerForAPI, + TunnelForAPI: opt.TunnelForAPI, ProviderName: opt.ProviderName, } @@ -215,6 +216,7 @@ func ParseProxy(mapping map[string]any, options ...ProxyOption) (C.Proxy, error) type proxyOption struct { DialerForAPI C.Dialer + TunnelForAPI C.Tunnel ProviderName string } @@ -234,6 +236,12 @@ func WithDialerForAPI(dialer C.Dialer) ProxyOption { } } +func WithTunnelForAPI(tunnel C.Tunnel) ProxyOption { + return func(opt *proxyOption) { + opt.TunnelForAPI = tunnel + } +} + func WithProviderName(name string) ProxyOption { return func(opt *proxyOption) { opt.ProviderName = name diff --git a/adapter/provider/parser.go b/adapter/provider/parser.go index 1668ccf9..c400068c 100644 --- a/adapter/provider/parser.go +++ b/adapter/provider/parser.go @@ -43,7 +43,7 @@ type proxyProviderSchema struct { Header map[string][]string `provider:"header,omitempty"` } -func ParseProxyProvider(name string, mapping map[string]any) (P.ProxyProvider, error) { +func ParseProxyProvider(name string, mapping map[string]any, tunnel C.Tunnel) (P.ProxyProvider, error) { decoder := structure.NewDecoder(structure.Option{TagName: "provider", WeaklyTypedInput: true}) schema := &proxyProviderSchema{ @@ -69,7 +69,7 @@ func ParseProxyProvider(name string, mapping map[string]any) (P.ProxyProvider, e } hc := NewHealthCheck([]C.Proxy{}, schema.HealthCheck.URL, uint(schema.HealthCheck.TestTimeout), hcInterval, schema.HealthCheck.Lazy, expectedStatus) - parser, err := NewProxiesParser(name, schema.Filter, schema.ExcludeFilter, schema.ExcludeType, schema.DialerProxy, schema.Override) + parser, err := NewProxiesParser(name, tunnel, schema.Filter, schema.ExcludeFilter, schema.ExcludeType, schema.DialerProxy, schema.Override) if err != nil { return nil, err } diff --git a/adapter/provider/provider.go b/adapter/provider/provider.go index 1faa2147..dddaf37c 100644 --- a/adapter/provider/provider.go +++ b/adapter/provider/provider.go @@ -339,7 +339,7 @@ func (cp *CompatibleProvider) Close() error { return cp.compatibleProvider.Close() } -func NewProxiesParser(pdName string, filter string, excludeFilter string, excludeType string, dialerProxy string, override overrideSchema) (resource.Parser[[]C.Proxy], error) { +func NewProxiesParser(pdName string, tunnel C.Tunnel, filter string, excludeFilter string, excludeType string, dialerProxy string, override overrideSchema) (resource.Parser[[]C.Proxy], error) { var excludeTypeArray []string if excludeType != "" { excludeTypeArray = strings.Split(excludeType, "|") @@ -433,7 +433,7 @@ func NewProxiesParser(pdName string, filter string, excludeFilter string, exclud return nil, fmt.Errorf("proxy %d override error: %w", idx, err) } - proxy, err := adapter.ParseProxy(mapping, adapter.WithProviderName(pdName)) + proxy, err := adapter.ParseProxy(mapping, adapter.WithTunnelForAPI(tunnel), adapter.WithProviderName(pdName)) if err != nil { return nil, fmt.Errorf("proxy %d error: %w", idx, err) } diff --git a/config/config.go b/config/config.go index 6805e991..d08dd713 100644 --- a/config/config.go +++ b/config/config.go @@ -876,7 +876,7 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[ // parse proxy for idx, mapping := range proxiesConfig { - proxy, err := adapter.ParseProxy(mapping) + proxy, err := adapter.ParseProxy(mapping, adapter.WithTunnelForAPI(T.Tunnel)) if err != nil { return nil, nil, fmt.Errorf("proxy %d: %w", idx, err) } @@ -913,7 +913,7 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[ return nil, nil, fmt.Errorf("can not defined a provider called `%s`", provider.ReservedName) } - pd, err := provider.ParseProxyProvider(name, mapping) + pd, err := provider.ParseProxyProvider(name, mapping, T.Tunnel) if err != nil { return nil, nil, fmt.Errorf("parse proxy provider %s error: %w", name, err) } diff --git a/listener/inbound/anytls_test.go b/listener/inbound/anytls_test.go index 5d9ac8ba..cf49cb51 100644 --- a/listener/inbound/anytls_test.go +++ b/listener/inbound/anytls_test.go @@ -42,6 +42,7 @@ func testInboundAnyTLS(t *testing.T, inboundOptions inbound.AnyTLSOption, outbou outboundOptions.Port = int(addrPort.Port()) outboundOptions.Password = userUUID outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewAnyTLS(outboundOptions) if !assert.NoError(t, err) { diff --git a/listener/inbound/common_test.go b/listener/inbound/common_test.go index 74df75a2..c19953ac 100644 --- a/listener/inbound/common_test.go +++ b/listener/inbound/common_test.go @@ -354,6 +354,9 @@ func NewHttpTestTunnel() *TestTunnel { } <-c.ch }, + HandleUDPPacketFn: func(packet C.UDPPacket, metadata *C.Metadata) { + // TODO + }, CloseFn: ln.Close, DoSequentialTestFn: sequentialTestFn, DoConcurrentTestFn: concurrentTestFn, diff --git a/listener/inbound/hysteria2_test.go b/listener/inbound/hysteria2_test.go index b0132fa9..9da650b2 100644 --- a/listener/inbound/hysteria2_test.go +++ b/listener/inbound/hysteria2_test.go @@ -42,6 +42,7 @@ func testInboundHysteria2(t *testing.T, inboundOptions inbound.Hysteria2Option, outboundOptions.Port = int(addrPort.Port()) outboundOptions.Password = userUUID outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewHysteria2(outboundOptions) if !assert.NoError(t, err) { diff --git a/listener/inbound/mieru_test.go b/listener/inbound/mieru_test.go index 97742186..ac57f823 100644 --- a/listener/inbound/mieru_test.go +++ b/listener/inbound/mieru_test.go @@ -238,6 +238,7 @@ func testInboundMieruTCP(t *testing.T, handshakeMode string) { HandshakeMode: handshakeMode, } outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewMieru(outboundOptions) if !assert.NoError(t, err) { return diff --git a/listener/inbound/shadowsocks_test.go b/listener/inbound/shadowsocks_test.go index 27f9fa87..e6276aab 100644 --- a/listener/inbound/shadowsocks_test.go +++ b/listener/inbound/shadowsocks_test.go @@ -86,6 +86,7 @@ func testInboundShadowSocks0(t *testing.T, inboundOptions inbound.ShadowSocksOpt outboundOptions.Port = int(addrPort.Port()) outboundOptions.Password = password outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewShadowSocks(outboundOptions) if !assert.NoError(t, err) { diff --git a/listener/inbound/sudoku_test.go b/listener/inbound/sudoku_test.go index 41348008..0075d338 100644 --- a/listener/inbound/sudoku_test.go +++ b/listener/inbound/sudoku_test.go @@ -44,6 +44,7 @@ func testInboundSudoku(t *testing.T, inboundOptions inbound.SudokuOption, outbou outboundOptions.Server = addrPort.Addr().String() outboundOptions.Port = int(addrPort.Port()) outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewSudoku(outboundOptions) if !assert.NoError(t, err) { diff --git a/listener/inbound/trojan_test.go b/listener/inbound/trojan_test.go index 14c36e82..96914e91 100644 --- a/listener/inbound/trojan_test.go +++ b/listener/inbound/trojan_test.go @@ -44,6 +44,7 @@ func testInboundTrojan(t *testing.T, inboundOptions inbound.TrojanOption, outbou outboundOptions.Port = int(addrPort.Port()) outboundOptions.Password = userUUID outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewTrojan(outboundOptions) if !assert.NoError(t, err) { diff --git a/listener/inbound/trusttunnel_test.go b/listener/inbound/trusttunnel_test.go index 5573e6fe..509c5d59 100644 --- a/listener/inbound/trusttunnel_test.go +++ b/listener/inbound/trusttunnel_test.go @@ -43,6 +43,7 @@ func testInboundTrustTunnel(t *testing.T, inboundOptions inbound.TrustTunnelOpti outboundOptions.UserName = "test" outboundOptions.Password = userUUID outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewTrustTunnel(outboundOptions) if !assert.NoError(t, err) { diff --git a/listener/inbound/tuic_test.go b/listener/inbound/tuic_test.go index 34bf8e4d..0a1f1bd2 100644 --- a/listener/inbound/tuic_test.go +++ b/listener/inbound/tuic_test.go @@ -70,6 +70,7 @@ func testInboundTuic0(t *testing.T, inboundOptions inbound.TuicOption, outboundO outboundOptions.Server = addrPort.Addr().String() outboundOptions.Port = int(addrPort.Port()) outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewTuic(outboundOptions) if !assert.NoError(t, err) { diff --git a/listener/inbound/vless_test.go b/listener/inbound/vless_test.go index 834b1d28..98c841aa 100644 --- a/listener/inbound/vless_test.go +++ b/listener/inbound/vless_test.go @@ -45,6 +45,7 @@ func testInboundVless(t *testing.T, inboundOptions inbound.VlessOption, outbound outboundOptions.Port = int(addrPort.Port()) outboundOptions.UUID = userUUID outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewVless(outboundOptions) if !assert.NoError(t, err) { diff --git a/listener/inbound/vmess_test.go b/listener/inbound/vmess_test.go index 175d9803..a03d387a 100644 --- a/listener/inbound/vmess_test.go +++ b/listener/inbound/vmess_test.go @@ -46,6 +46,7 @@ func testInboundVMess(t *testing.T, inboundOptions inbound.VmessOption, outbound outboundOptions.AlterID = 0 outboundOptions.Cipher = "auto" outboundOptions.DialerForAPI = tunnel.NewDialer() + outboundOptions.TunnelForAPI = tunnel out, err := outbound.NewVmess(outboundOptions) if !assert.NoError(t, err) {