From 7385616cca14c28d121457782c197481351a46c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 8 Apr 2025 21:51:35 +0800 Subject: [PATCH] Fix DNS dialer --- common/dialer/default.go | 34 ++++++++++++++++++++-------------- route/network.go | 12 +++++++++++- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/common/dialer/default.go b/common/dialer/default.go index 2fa2725c..c4f6c16b 100644 --- a/common/dialer/default.go +++ b/common/dialer/default.go @@ -71,18 +71,8 @@ func NewDefault(ctx context.Context, options option.DialerOptions) (*DefaultDial listener.Control = control.Append(listener.Control, bindFunc) } if options.RoutingMark > 0 { - dialer.Control = control.Append(dialer.Control, control.RoutingMark(uint32(options.RoutingMark))) - listener.Control = control.Append(listener.Control, control.RoutingMark(uint32(options.RoutingMark))) - } - if networkManager != nil { - autoRedirectOutputMark := networkManager.AutoRedirectOutputMark() - if autoRedirectOutputMark > 0 { - if options.RoutingMark > 0 { - return nil, E.New("`routing_mark` is conflict with `tun.auto_redirect` with `tun.route_[_exclude]_address_set") - } - dialer.Control = control.Append(dialer.Control, control.RoutingMark(autoRedirectOutputMark)) - listener.Control = control.Append(listener.Control, control.RoutingMark(autoRedirectOutputMark)) - } + dialer.Control = control.Append(dialer.Control, setMarkWrapper(networkManager, uint32(options.RoutingMark), false)) + listener.Control = control.Append(listener.Control, setMarkWrapper(networkManager, uint32(options.RoutingMark), false)) } disableDefaultBind := options.BindInterface != "" || options.Inet4BindAddress != nil || options.Inet6BindAddress != nil if disableDefaultBind || options.TCPFastOpen { @@ -127,8 +117,8 @@ func NewDefault(ctx context.Context, options option.DialerOptions) (*DefaultDial } } if options.RoutingMark == 0 && defaultOptions.RoutingMark != 0 { - dialer.Control = control.Append(dialer.Control, control.RoutingMark(defaultOptions.RoutingMark)) - listener.Control = control.Append(listener.Control, control.RoutingMark(defaultOptions.RoutingMark)) + dialer.Control = control.Append(dialer.Control, setMarkWrapper(networkManager, defaultOptions.RoutingMark, true)) + listener.Control = control.Append(listener.Control, setMarkWrapper(networkManager, defaultOptions.RoutingMark, true)) } } if options.ReuseAddr { @@ -210,6 +200,22 @@ func NewDefault(ctx context.Context, options option.DialerOptions) (*DefaultDial }, nil } +func setMarkWrapper(networkManager adapter.NetworkManager, mark uint32, isDefault bool) control.Func { + if networkManager == nil { + return control.RoutingMark(mark) + } + return func(network, address string, conn syscall.RawConn) error { + if networkManager.AutoRedirectOutputMark() != 0 { + if isDefault { + return E.New("`route.default_mark` is conflict with `tun.auto_redirect`") + } else { + return E.New("`routing_mark` is conflict with `tun.auto_redirect`") + } + } + return control.RoutingMark(mark)(network, address, conn) + } +} + func (d *DefaultDialer) DialContext(ctx context.Context, network string, address M.Socksaddr) (net.Conn, error) { if !address.IsValid() { return nil, E.New("invalid address") diff --git a/route/network.go b/route/network.go index a494ce09..6c2e995f 100644 --- a/route/network.go +++ b/route/network.go @@ -303,7 +303,7 @@ func (r *NetworkManager) AutoDetectInterfaceFunc() control.Func { if r.interfaceMonitor == nil { return nil } - return control.BindToInterfaceFunc(r.interfaceFinder, func(network string, address string) (interfaceName string, interfaceIndex int, err error) { + bindFunc := control.BindToInterfaceFunc(r.interfaceFinder, func(network string, address string) (interfaceName string, interfaceIndex int, err error) { remoteAddr := M.ParseSocksaddr(address).Addr if remoteAddr.IsValid() { iif, err := r.interfaceFinder.ByAddr(remoteAddr) @@ -317,6 +317,16 @@ func (r *NetworkManager) AutoDetectInterfaceFunc() control.Func { } return defaultInterface.Name, defaultInterface.Index, nil }) + return func(network, address string, conn syscall.RawConn) error { + err := bindFunc(network, address, conn) + if err != nil { + return err + } + if r.autoRedirectOutputMark > 0 { + return control.RoutingMark(r.autoRedirectOutputMark)(network, address, conn) + } + return nil + } } }