From d4478dbfa29328a62f1ce94d98e2e68490bcaa55 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Tue, 5 Nov 2024 09:29:01 +0800 Subject: [PATCH] chore: reduce the performance overhead of not enabling LoopBackDetector --- adapter/outbound/direct.go | 18 ++++-------------- component/loopback/detector.go | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/adapter/outbound/direct.go b/adapter/outbound/direct.go index 9ee237fa1..dbde55933 100644 --- a/adapter/outbound/direct.go +++ b/adapter/outbound/direct.go @@ -3,18 +3,12 @@ package outbound import ( "context" "errors" - "os" - "strconv" - "github.com/metacubex/mihomo/component/dialer" "github.com/metacubex/mihomo/component/loopback" "github.com/metacubex/mihomo/component/resolver" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/features" ) -var DisableLoopBackDetector, _ = strconv.ParseBool(os.Getenv("DISABLE_LOOPBACK_DETECTOR")) - type Direct struct { *Base loopBack *loopback.Detector @@ -27,10 +21,8 @@ type DirectOption struct { // DialContext implements C.ProxyAdapter func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) { - if !features.CMFA && !DisableLoopBackDetector { - if err := d.loopBack.CheckConn(metadata); err != nil { - return nil, err - } + if err := d.loopBack.CheckConn(metadata); err != nil { + return nil, err } opts = append(opts, dialer.WithResolver(resolver.DirectHostResolver)) c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...) @@ -42,10 +34,8 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ... // ListenPacketContext implements C.ProxyAdapter func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) { - if !features.CMFA && !DisableLoopBackDetector { - if err := d.loopBack.CheckPacketConn(metadata); err != nil { - return nil, err - } + if err := d.loopBack.CheckPacketConn(metadata); err != nil { + return nil, err } // net.UDPConn.WriteTo only working with *net.UDPAddr, so we need a net.UDPAddr if !metadata.Resolved() { diff --git a/component/loopback/detector.go b/component/loopback/detector.go index 8ec96a9dd..c639ab220 100644 --- a/component/loopback/detector.go +++ b/component/loopback/detector.go @@ -4,14 +4,25 @@ import ( "errors" "fmt" "net/netip" + "os" + "strconv" "github.com/metacubex/mihomo/common/callback" "github.com/metacubex/mihomo/component/iface" C "github.com/metacubex/mihomo/constant" + "github.com/metacubex/mihomo/constant/features" "github.com/puzpuzpuz/xsync/v3" ) +var disableLoopBackDetector, _ = strconv.ParseBool(os.Getenv("DISABLE_LOOPBACK_DETECTOR")) + +func init() { + if features.CMFA { + disableLoopBackDetector = true + } +} + var ErrReject = errors.New("reject loopback connection") type Detector struct { @@ -20,6 +31,9 @@ type Detector struct { } func NewDetector() *Detector { + if disableLoopBackDetector { + return nil + } return &Detector{ connMap: xsync.NewMapOf[netip.AddrPort, struct{}](), packetConnMap: xsync.NewMapOf[uint16, struct{}](), @@ -27,6 +41,9 @@ func NewDetector() *Detector { } func (l *Detector) NewConn(conn C.Conn) C.Conn { + if l == nil || l.connMap == nil { + return conn + } metadata := C.Metadata{} if metadata.SetRemoteAddr(conn.LocalAddr()) != nil { return conn @@ -42,6 +59,9 @@ func (l *Detector) NewConn(conn C.Conn) C.Conn { } func (l *Detector) NewPacketConn(conn C.PacketConn) C.PacketConn { + if l == nil || l.packetConnMap == nil { + return conn + } metadata := C.Metadata{} if metadata.SetRemoteAddr(conn.LocalAddr()) != nil { return conn @@ -58,6 +78,9 @@ func (l *Detector) NewPacketConn(conn C.PacketConn) C.PacketConn { } func (l *Detector) CheckConn(metadata *C.Metadata) error { + if l == nil || l.connMap == nil { + return nil + } connAddr := metadata.SourceAddrPort() if !connAddr.IsValid() { return nil @@ -69,6 +92,9 @@ func (l *Detector) CheckConn(metadata *C.Metadata) error { } func (l *Detector) CheckPacketConn(metadata *C.Metadata) error { + if l == nil || l.packetConnMap == nil { + return nil + } connAddr := metadata.SourceAddrPort() if !connAddr.IsValid() { return nil