tailscale: Use system dialer for system interface

* Revert "Fix netstack TCP connections with system interface
This commit is contained in:
世界
2026-03-10 16:56:09 +08:00
parent 4d6fb1d38d
commit 65875e6dac
3 changed files with 61 additions and 15 deletions

2
go.mod
View File

@@ -42,7 +42,7 @@ require (
github.com/sagernet/sing-tun v0.8.2 github.com/sagernet/sing-tun v0.8.2
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1
github.com/sagernet/smux v1.5.50-sing-box-mod.1 github.com/sagernet/smux v1.5.50-sing-box-mod.1
github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260303140313-3bcf9a4b9349 github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260310072802-158edadd59bd
github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854
github.com/spf13/cobra v1.10.2 github.com/spf13/cobra v1.10.2

4
go.sum
View File

@@ -254,8 +254,8 @@ github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkV
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY= 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= github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478=
github.com/sagernet/smux v1.5.50-sing-box-mod.1/go.mod h1:NjhsCEWedJm7eFLyhuBgIEzwfhRmytrUoiLluxs5Sk8= github.com/sagernet/smux v1.5.50-sing-box-mod.1/go.mod h1:NjhsCEWedJm7eFLyhuBgIEzwfhRmytrUoiLluxs5Sk8=
github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260303140313-3bcf9a4b9349 h1:ju7aTbndj2sqK4NplE97ynLdhuCtel5OS4e0NrT71nk= github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260310072802-158edadd59bd h1:WUVQsTUCr0OEWXoB6uPXaqup7SjMUFOkOHe0XBcpLn4=
github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260303140313-3bcf9a4b9349/go.mod h1:m87GAn4UcesHQF3leaPFEINZETO5za1LGn1GJdNDgNc= github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6.0.20260310072802-158edadd59bd/go.mod h1:m87GAn4UcesHQF3leaPFEINZETO5za1LGn1GJdNDgNc=
github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c h1:f9cXNB+IOOPnR8DOLMTpr42jf7naxh5Un5Y09BBf5Cg= github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c h1:f9cXNB+IOOPnR8DOLMTpr42jf7naxh5Un5Y09BBf5Cg=
github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c/go.mod h1:WUxgxUDZoCF2sxVmW+STSxatP02Qn3FcafTiI2BLtE0= github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c/go.mod h1:WUxgxUDZoCF2sxVmW+STSxatP02Qn3FcafTiI2BLtE0=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=

View File

@@ -110,6 +110,7 @@ type Endpoint struct {
systemInterfaceName string systemInterfaceName string
systemInterfaceMTU uint32 systemInterfaceMTU uint32
systemTun tun.Tun systemTun tun.Tun
systemDialer *dialer.DefaultDialer
fallbackTCPCloser func() fallbackTCPCloser func()
} }
@@ -324,8 +325,19 @@ func (t *Endpoint) Start(stage adapter.StartStage) error {
_ = systemTun.Close() _ = systemTun.Close()
return err return err
} }
systemDialer, err := dialer.NewDefault(t.ctx, option.DialerOptions{
BindInterface: tunName,
})
if err != nil {
_ = systemTun.Close()
return err
}
t.systemTun = systemTun t.systemTun = systemTun
t.systemDialer = systemDialer
t.server.TunDevice = wgTunDevice t.server.TunDevice = wgTunDevice
t.server.RouterWrapper = func(inner router.Router) router.Router {
return &exitRouteFilteringRouter{Router: inner}
}
} }
err := t.server.Start() err := t.server.Start()
if err != nil { if err != nil {
@@ -459,6 +471,10 @@ func (t *Endpoint) Close() error {
t.fallbackTCPCloser() t.fallbackTCPCloser()
t.fallbackTCPCloser = nil t.fallbackTCPCloser = nil
} }
if t.systemTun != nil {
_ = t.systemTun.Close()
t.systemTun = nil
}
return common.Close(common.PtrOrNil(t.server)) return common.Close(common.PtrOrNil(t.server))
} }
@@ -476,6 +492,9 @@ func (t *Endpoint) DialContext(ctx context.Context, network string, destination
} }
return N.DialSerial(ctx, t, network, destination, destinationAddresses) return N.DialSerial(ctx, t, network, destination, destinationAddresses)
} }
if t.systemDialer != nil {
return t.systemDialer.DialContext(ctx, network, destination)
}
addr4, addr6 := t.server.TailscaleIPs() addr4, addr6 := t.server.TailscaleIPs()
remoteAddr := tcpip.FullAddress{ remoteAddr := tcpip.FullAddress{
NIC: 1, NIC: 1,
@@ -522,6 +541,9 @@ func (t *Endpoint) DialContext(ctx context.Context, network string, destination
} }
func (t *Endpoint) listenPacketWithAddress(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (t *Endpoint) listenPacketWithAddress(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
if t.systemDialer != nil {
return t.systemDialer.ListenPacket(ctx, destination)
}
addr4, addr6 := t.server.TailscaleIPs() addr4, addr6 := t.server.TailscaleIPs()
bind := tcpip.FullAddress{ bind := tcpip.FullAddress{
NIC: 1, NIC: 1,
@@ -679,19 +701,29 @@ func (t *Endpoint) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
} }
func (t *Endpoint) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) { func (t *Endpoint) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
inet4Address, inet6Address := t.server.TailscaleIPs()
if metadata.Destination.Addr.Is4() && !inet4Address.IsValid() || metadata.Destination.Addr.Is6() && !inet6Address.IsValid() {
return nil, E.New("Tailscale is not ready yet")
}
ctx := log.ContextWithNewID(t.ctx) ctx := log.ContextWithNewID(t.ctx)
destination, err := ping.ConnectGVisor( var destination tun.DirectRouteDestination
ctx, t.logger, var err error
metadata.Source.Addr, metadata.Destination.Addr, if t.systemDialer != nil {
routeContext, destination, err = ping.ConnectDestination(
t.stack, ctx, t.logger,
inet4Address, inet6Address, t.systemDialer.DialerForICMPDestination(metadata.Destination.Addr).Control,
timeout, metadata.Destination.Addr, routeContext, timeout,
) )
} else {
inet4Address, inet6Address := t.server.TailscaleIPs()
if metadata.Destination.Addr.Is4() && !inet4Address.IsValid() || metadata.Destination.Addr.Is6() && !inet6Address.IsValid() {
return nil, E.New("Tailscale is not ready yet")
}
destination, err = ping.ConnectGVisor(
ctx, t.logger,
metadata.Source.Addr, metadata.Destination.Addr,
routeContext,
t.stack,
inet4Address, inet6Address,
timeout,
)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -808,3 +840,17 @@ func (c *dnsConfigurtor) GetBaseConfig() (tsDNS.OSConfig, error) {
func (c *dnsConfigurtor) Close() error { func (c *dnsConfigurtor) Close() error {
return nil return nil
} }
type exitRouteFilteringRouter struct {
router.Router
}
func (r *exitRouteFilteringRouter) Set(config *router.Config) error {
if config != nil {
config = config.Clone()
config.Routes = common.Filter(config.Routes, func(prefix netip.Prefix) bool {
return !tsaddr.IsExitRoute(prefix)
})
}
return r.Router.Set(config)
}