tailscale: Revert dialer deprecation and remove control_http_client

This commit is contained in:
世界
2026-05-20 14:50:36 +08:00
parent cf06742014
commit 8785b39b15
7 changed files with 55 additions and 120 deletions
+51 -63
View File
@@ -4,6 +4,7 @@ package tailscale
import (
"context"
"crypto/tls"
"fmt"
"net"
"net/http"
@@ -27,7 +28,6 @@ import (
"github.com/sagernet/sing-box/adapter/endpoint"
"github.com/sagernet/sing-box/common/dialer"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/route/rule"
@@ -41,6 +41,7 @@ import (
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/ntp"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/filemanager"
_ "github.com/sagernet/tailscale/feature/relayserver"
@@ -116,45 +117,6 @@ type Endpoint struct {
fallbackTCPCloser func()
}
func (t *Endpoint) registerNetstackHandlers() {
netstack := t.server.ExportNetstack()
if netstack == nil {
return
}
previousTCP := netstack.GetTCPHandlerForFlow
netstack.GetTCPHandlerForFlow = func(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool) {
if previousTCP != nil {
handler, intercept = previousTCP(src, dst)
if handler != nil || !intercept {
return handler, intercept
}
}
return func(conn net.Conn) {
ctx := log.ContextWithNewID(t.ctx)
source := M.SocksaddrFrom(src.Addr(), src.Port())
destination := M.SocksaddrFrom(dst.Addr(), dst.Port())
t.NewConnectionEx(ctx, conn, source, destination, nil)
}, true
}
previousUDP := netstack.GetUDPHandlerForFlow
netstack.GetUDPHandlerForFlow = func(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
if previousUDP != nil {
handler, intercept = previousUDP(src, dst)
if handler != nil || !intercept {
return handler, intercept
}
}
return func(conn nettype.ConnPacketConn) {
ctx := log.ContextWithNewID(t.ctx)
source := M.SocksaddrFrom(src.Addr(), src.Port())
destination := M.SocksaddrFrom(dst.Addr(), dst.Port())
packetConn := bufio.NewUnbindPacketConnWithAddr(conn, destination)
t.NewPacketConnectionEx(ctx, packetConn, source, destination, nil)
}, true
}
}
func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TailscaleEndpointOptions) (adapter.Endpoint, error) {
stateDirectory := options.StateDirectory
if stateDirectory == "" {
@@ -196,19 +158,6 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
// controlplane.tailscale.com
remoteIsDomain = true
}
hasLegacyDialer := !reflect.DeepEqual(options.DialerOptions, option.DialerOptions{})
hasControlHTTPClient := options.ControlHTTPClient != nil && !options.ControlHTTPClient.IsEmpty()
if hasLegacyDialer && hasControlHTTPClient {
return nil, E.New("control_http_client is conflict with deprecated dialer options")
}
controlHTTPClientOptions := common.PtrValueOrDefault(options.ControlHTTPClient)
if hasLegacyDialer {
deprecated.Report(ctx, deprecated.OptionLegacyTailscaleEndpointDialer)
controlHTTPClientOptions.DialerOptions = options.DialerOptions
}
if remoteIsDomain {
controlHTTPClientOptions.ResolveOnDetour = true
}
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
Context: ctx,
Options: options.DialerOptions,
@@ -220,12 +169,6 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
return nil, err
}
dnsRouter := service.FromContext[adapter.DNSRouter](ctx)
httpClientManager := service.FromContext[adapter.HTTPClientManager](ctx)
controlTransport, err := httpClientManager.ResolveTransport(ctx, logger, controlHTTPClientOptions)
if err != nil {
return nil, E.Cause(err, "create control HTTP client")
}
controlHTTPClient := &http.Client{Transport: controlTransport}
server := &tsnet.Server{
Dir: stateDirectory,
Hostname: hostname,
@@ -243,11 +186,22 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
LookupHook: func(ctx context.Context, host string) ([]netip.Addr, error) {
return dnsRouter.Lookup(ctx, host, outboundDialer.(dialer.ResolveDialer).QueryOptions())
},
DNS: &dnsConfigurtor{},
HTTPClient: controlHTTPClient,
DNS: &dnsConfigurtor{},
HTTPClient: &http.Client{
Transport: &http.Transport{
ForceAttemptHTTP2: true,
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
return outboundDialer.DialContext(ctx, network, M.ParseSocksaddr(address))
},
TLSClientConfig: &tls.Config{
RootCAs: adapter.RootPoolFromContext(ctx),
Time: ntp.TimeFuncFromContext(ctx),
},
},
},
}
return &Endpoint{
Adapter: endpoint.NewAdapterWithDialerOptions(C.TypeTailscale, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, controlHTTPClientOptions.DialerOptions),
Adapter: endpoint.NewAdapter(C.TypeTailscale, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, nil),
ctx: ctx,
router: router,
logger: logger,
@@ -401,7 +355,41 @@ func (t *Endpoint) postStart() error {
ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber6, icmpForwarder.HandlePacket)
t.stack = ipStack
t.icmpForwarder = icmpForwarder
t.registerNetstackHandlers()
netstack := t.server.ExportNetstack()
if netstack != nil {
previousTCP := netstack.GetTCPHandlerForFlow
netstack.GetTCPHandlerForFlow = func(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool) {
if previousTCP != nil {
handler, intercept = previousTCP(src, dst)
if handler != nil || !intercept {
return handler, intercept
}
}
return func(conn net.Conn) {
ctx := log.ContextWithNewID(t.ctx)
source := M.SocksaddrFrom(src.Addr(), src.Port())
destination := M.SocksaddrFrom(dst.Addr(), dst.Port())
t.NewConnectionEx(ctx, conn, source, destination, nil)
}, true
}
previousUDP := netstack.GetUDPHandlerForFlow
netstack.GetUDPHandlerForFlow = func(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
if previousUDP != nil {
handler, intercept = previousUDP(src, dst)
if handler != nil || !intercept {
return handler, intercept
}
}
return func(conn nettype.ConnPacketConn) {
ctx := log.ContextWithNewID(t.ctx)
source := M.SocksaddrFrom(src.Addr(), src.Port())
destination := M.SocksaddrFrom(dst.Addr(), dst.Port())
packetConn := bufio.NewUnbindPacketConnWithAddr(conn, destination)
t.NewPacketConnectionEx(ctx, packetConn, source, destination, nil)
}, true
}
}
localBackend := t.server.ExportLocalBackend()
perfs := &ipn.MaskedPrefs{