Fix outbound start sequence

This commit is contained in:
世界 2023-06-13 22:38:05 +08:00
parent 4f12eba944
commit 8d5b9d240a
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
23 changed files with 197 additions and 105 deletions

View file

@ -13,6 +13,7 @@ type Outbound interface {
Type() string Type() string
Tag() string Tag() string
Network() []string Network() []string
Dependencies() []string
N.Dialer N.Dialer
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error

17
box.go
View file

@ -217,20 +217,9 @@ func (s *Box) preStart() error {
return E.Cause(err, "pre-starting ", serviceName) return E.Cause(err, "pre-starting ", serviceName)
} }
} }
for i, out := range s.outbounds { err := s.startOutbounds()
var tag string if err != nil {
if out.Tag() == "" { return err
tag = F.ToString(i)
} else {
tag = out.Tag()
}
if starter, isStarter := out.(common.Starter); isStarter {
s.logger.Trace("initializing outbound/", out.Type(), "[", tag, "]")
err := starter.Start()
if err != nil {
return E.Cause(err, "initialize outbound/", out.Type(), "[", tag, "]")
}
}
} }
return s.router.Start() return s.router.Start()
} }

76
box_outbound.go Normal file
View file

@ -0,0 +1,76 @@
package box
import (
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
func (s *Box) startOutbounds() error {
outboundTags := make(map[adapter.Outbound]string)
outbounds := make(map[string]adapter.Outbound)
for i, outboundToStart := range s.outbounds {
var outboundTag string
if outboundToStart.Tag() == "" {
outboundTag = F.ToString(i)
} else {
outboundTag = outboundToStart.Tag()
}
outboundTags[outboundToStart] = outboundTag
outbounds[outboundTag] = outboundToStart
}
started := make(map[string]bool)
for {
canContinue := false
startOne:
for _, outboundToStart := range s.outbounds {
outboundTag := outboundTags[outboundToStart]
if started[outboundTag] {
continue
}
dependencies := outboundToStart.Dependencies()
for _, dependency := range dependencies {
if !started[dependency] {
continue startOne
}
}
started[outboundTag] = true
canContinue = true
if starter, isStarter := outboundToStart.(common.Starter); isStarter {
s.logger.Trace("initializing outbound/", outboundToStart.Type(), "[", outboundTag, "]")
err := starter.Start()
if err != nil {
return E.Cause(err, "initialize outbound/", outboundToStart.Type(), "[", outboundTag, "]")
}
}
}
if len(started) == len(s.outbounds) {
break
}
if canContinue {
continue
}
currentOutbound := common.Find(s.outbounds, func(it adapter.Outbound) bool {
return !started[outboundTags[it]]
})
var lintOutbound func(oTree []string, oCurrent adapter.Outbound) error
lintOutbound = func(oTree []string, oCurrent adapter.Outbound) error {
problemOutboundTag := common.Find(oCurrent.Dependencies(), func(it string) bool {
return !started[it]
})
if common.Contains(oTree, problemOutboundTag) {
return E.New("circular outbound dependency: ", strings.Join(oTree, " -> "), " -> ", problemOutboundTag)
}
problemOutbound := outbounds[problemOutboundTag]
if problemOutbound == nil {
return E.New("dependency[", problemOutbound, "] not found for outbound[", outboundTags[oCurrent], "]")
}
return lintOutbound(append(oTree, problemOutboundTag), problemOutbound)
}
return lintOutbound([]string{outboundTags[currentOutbound]}, currentOutbound)
}
return nil
}

2
go.mod
View file

@ -25,7 +25,7 @@ require (
github.com/sagernet/gvisor v0.0.0-20230611140528-4411f7659a08 github.com/sagernet/gvisor v0.0.0-20230611140528-4411f7659a08
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.2.5-0.20230611070640-2812461739c3 github.com/sagernet/sing v0.2.5-0.20230613142554-a3b120b25eab
github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223 github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223
github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c

4
go.sum
View file

@ -118,8 +118,8 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byL
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.5-0.20230611070640-2812461739c3 h1:OnlfGM8HncECbFiV4s6uAX961fm2UpEKSCXYBLZ1Chg= github.com/sagernet/sing v0.2.5-0.20230613142554-a3b120b25eab h1:9AVUIqqz/UJCgIrcJBU9mb06JXzfQ/FgEmlgdPgo2dk=
github.com/sagernet/sing v0.2.5-0.20230611070640-2812461739c3/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= github.com/sagernet/sing v0.2.5-0.20230613142554-a3b120b25eab/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223 h1:L4eMuM07iSHY3UCknFnuFuHoe5clZuF2Xnf2wwA6Lwc= github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223 h1:L4eMuM07iSHY3UCknFnuFuHoe5clZuF2Xnf2wwA6Lwc=
github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY= github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY=
github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 h1:X3ADfMqeGns1Q1FlXc9kaL9FwW1UM6D6tEQo8jFstpc= github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 h1:X3ADfMqeGns1Q1FlXc9kaL9FwW1UM6D6tEQo8jFstpc=

View file

@ -11,6 +11,7 @@ import (
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
@ -20,11 +21,12 @@ import (
) )
type myOutboundAdapter struct { type myOutboundAdapter struct {
protocol string protocol string
network []string network []string
router adapter.Router router adapter.Router
logger log.ContextLogger logger log.ContextLogger
tag string tag string
dependencies []string
} }
func (a *myOutboundAdapter) Type() string { func (a *myOutboundAdapter) Type() string {
@ -39,10 +41,21 @@ func (a *myOutboundAdapter) Network() []string {
return a.network return a.network
} }
func (a *myOutboundAdapter) Dependencies() []string {
return a.dependencies
}
func (a *myOutboundAdapter) NewError(ctx context.Context, err error) { func (a *myOutboundAdapter) NewError(ctx context.Context, err error) {
NewError(a.logger, ctx, err) NewError(a.logger, ctx, err)
} }
func withDialerDependency(options option.DialerOptions) []string {
if options.Detour != "" {
return []string{options.Detour}
}
return nil
}
func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata adapter.InboundContext) error { func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata adapter.InboundContext) error {
ctx = adapter.WithContext(ctx, &metadata) ctx = adapter.WithContext(ctx, &metadata)
var outConn net.Conn var outConn net.Conn

View file

@ -40,11 +40,12 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti
options.UDPFragmentDefault = true options.UDPFragmentDefault = true
outbound := &Direct{ outbound := &Direct{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeDirect, protocol: C.TypeDirect,
network: []string{N.NetworkTCP, N.NetworkUDP}, network: []string{N.NetworkTCP, N.NetworkUDP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
domainStrategy: dns.DomainStrategy(options.DomainStrategy), domainStrategy: dns.DomainStrategy(options.DomainStrategy),
fallbackDelay: time.Duration(options.FallbackDelay), fallbackDelay: time.Duration(options.FallbackDelay),

View file

@ -39,11 +39,12 @@ func NewHTTP(router adapter.Router, logger log.ContextLogger, tag string, option
} }
return &HTTP{ return &HTTP{
myOutboundAdapter{ myOutboundAdapter{
protocol: C.TypeHTTP, protocol: C.TypeHTTP,
network: []string{N.NetworkTCP}, network: []string{N.NetworkTCP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
sHTTP.NewClient(sHTTP.Options{ sHTTP.NewClient(sHTTP.Options{
Dialer: detour, Dialer: detour,

View file

@ -119,11 +119,12 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL
} }
return &Hysteria{ return &Hysteria{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeHysteria, protocol: C.TypeHysteria,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
ctx: ctx, ctx: ctx,
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),

View file

@ -29,10 +29,11 @@ type Selector struct {
func NewSelector(router adapter.Router, logger log.ContextLogger, tag string, options option.SelectorOutboundOptions) (*Selector, error) { func NewSelector(router adapter.Router, logger log.ContextLogger, tag string, options option.SelectorOutboundOptions) (*Selector, error) {
outbound := &Selector{ outbound := &Selector{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeSelector, protocol: C.TypeSelector,
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: options.Outbounds,
}, },
tags: options.Outbounds, tags: options.Outbounds,
defaultTag: options.Default, defaultTag: options.Default,

View file

@ -41,11 +41,12 @@ func NewShadowsocks(ctx context.Context, router adapter.Router, logger log.Conte
} }
outbound := &Shadowsocks{ outbound := &Shadowsocks{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeShadowsocks, protocol: C.TypeShadowsocks,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
method: method, method: method,

View file

@ -39,11 +39,12 @@ type ShadowsocksR struct {
func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksROutboundOptions) (*ShadowsocksR, error) { func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksROutboundOptions) (*ShadowsocksR, error) {
outbound := &ShadowsocksR{ outbound := &ShadowsocksR{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeShadowsocksR, protocol: C.TypeShadowsocksR,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
serverAddr: options.ServerOptions.Build(), serverAddr: options.ServerOptions.Build(),

View file

@ -27,11 +27,12 @@ type ShadowTLS struct {
func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSOutboundOptions) (*ShadowTLS, error) { func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSOutboundOptions) (*ShadowTLS, error) {
outbound := &ShadowTLS{ outbound := &ShadowTLS{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeShadowTLS, protocol: C.TypeShadowTLS,
network: []string{N.NetworkTCP}, network: []string{N.NetworkTCP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
} }
if options.TLS == nil || !options.TLS.Enabled { if options.TLS == nil || !options.TLS.Enabled {

View file

@ -39,11 +39,12 @@ func NewSocks(router adapter.Router, logger log.ContextLogger, tag string, optio
} }
outbound := &Socks{ outbound := &Socks{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeSocks, protocol: C.TypeSocks,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
client: socks.NewClient(dialer.New(router, options.DialerOptions), options.ServerOptions.Build(), version, options.Username, options.Password), client: socks.NewClient(dialer.New(router, options.DialerOptions), options.ServerOptions.Build(), version, options.Username, options.Password),
resolve: version == socks.Version4, resolve: version == socks.Version4,

View file

@ -46,11 +46,12 @@ type SSH struct {
func NewSSH(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SSHOutboundOptions) (*SSH, error) { func NewSSH(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SSHOutboundOptions) (*SSH, error) {
outbound := &SSH{ outbound := &SSH{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeSSH, protocol: C.TypeSSH,
network: []string{N.NetworkTCP}, network: []string{N.NetworkTCP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
ctx: ctx, ctx: ctx,
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),

View file

@ -68,11 +68,12 @@ func NewTor(ctx context.Context, router adapter.Router, logger log.ContextLogger
} }
return &Tor{ return &Tor{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeTor, protocol: C.TypeTor,
network: []string{N.NetworkTCP}, network: []string{N.NetworkTCP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
ctx: ctx, ctx: ctx,
proxy: NewProxyListener(ctx, logger, dialer.New(router, options.DialerOptions)), proxy: NewProxyListener(ctx, logger, dialer.New(router, options.DialerOptions)),

View file

@ -35,11 +35,12 @@ type Trojan struct {
func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TrojanOutboundOptions) (*Trojan, error) { func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TrojanOutboundOptions) (*Trojan, error) {
outbound := &Trojan{ outbound := &Trojan{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeTrojan, protocol: C.TypeTrojan,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
serverAddr: options.ServerOptions.Build(), serverAddr: options.ServerOptions.Build(),

View file

@ -39,10 +39,11 @@ type URLTest struct {
func NewURLTest(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.URLTestOutboundOptions) (*URLTest, error) { func NewURLTest(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.URLTestOutboundOptions) (*URLTest, error) {
outbound := &URLTest{ outbound := &URLTest{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeURLTest, protocol: C.TypeURLTest,
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: options.Outbounds,
}, },
ctx: ctx, ctx: ctx,
tags: options.Outbounds, tags: options.Outbounds,

View file

@ -38,11 +38,12 @@ type VLESS struct {
func NewVLESS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VLESSOutboundOptions) (*VLESS, error) { func NewVLESS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VLESSOutboundOptions) (*VLESS, error) {
outbound := &VLESS{ outbound := &VLESS{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeVLESS, protocol: C.TypeVLESS,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
serverAddr: options.ServerOptions.Build(), serverAddr: options.ServerOptions.Build(),

View file

@ -37,11 +37,12 @@ type VMess struct {
func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VMessOutboundOptions) (*VMess, error) { func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VMessOutboundOptions) (*VMess, error) {
outbound := &VMess{ outbound := &VMess{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeVMess, protocol: C.TypeVMess,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
serverAddr: options.ServerOptions.Build(), serverAddr: options.ServerOptions.Build(),

View file

@ -40,11 +40,12 @@ type WireGuard struct {
func NewWireGuard(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardOutboundOptions) (*WireGuard, error) { func NewWireGuard(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardOutboundOptions) (*WireGuard, error) {
outbound := &WireGuard{ outbound := &WireGuard{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeWireGuard, protocol: C.TypeWireGuard,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
} }
var reserved [3]uint8 var reserved [3]uint8

View file

@ -8,13 +8,6 @@ import (
"net/netip" "net/netip"
"os" "os"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
wgTun "github.com/sagernet/wireguard-go/tun"
"github.com/sagernet/gvisor/pkg/buffer" "github.com/sagernet/gvisor/pkg/buffer"
"github.com/sagernet/gvisor/pkg/tcpip" "github.com/sagernet/gvisor/pkg/tcpip"
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet" "github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
@ -25,6 +18,12 @@ import (
"github.com/sagernet/gvisor/pkg/tcpip/transport/icmp" "github.com/sagernet/gvisor/pkg/tcpip/transport/icmp"
"github.com/sagernet/gvisor/pkg/tcpip/transport/tcp" "github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
"github.com/sagernet/gvisor/pkg/tcpip/transport/udp" "github.com/sagernet/gvisor/pkg/tcpip/transport/udp"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
wgTun "github.com/sagernet/wireguard-go/tun"
) )
var _ Device = (*StackDevice)(nil) var _ Device = (*StackDevice)(nil)

View file

@ -10,14 +10,13 @@ import (
"net/netip" "net/netip"
"time" "time"
"github.com/sagernet/sing-tun"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/gvisor/pkg/tcpip" "github.com/sagernet/gvisor/pkg/tcpip"
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet" "github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
"github.com/sagernet/gvisor/pkg/tcpip/stack" "github.com/sagernet/gvisor/pkg/tcpip/stack"
"github.com/sagernet/gvisor/pkg/tcpip/transport/tcp" "github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
"github.com/sagernet/gvisor/pkg/waiter" "github.com/sagernet/gvisor/pkg/waiter"
"github.com/sagernet/sing-tun"
M "github.com/sagernet/sing/common/metadata"
) )
func DialTCPWithBind(ctx context.Context, s *stack.Stack, localAddr, remoteAddr tcpip.FullAddress, network tcpip.NetworkProtocolNumber) (*gonet.TCPConn, error) { func DialTCPWithBind(ctx context.Context, s *stack.Stack, localAddr, remoteAddr tcpip.FullAddress, network tcpip.NetworkProtocolNumber) (*gonet.TCPConn, error) {