mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-05-18 16:08:04 +08:00
chore: don't retry when rejected loopback connection
This commit is contained in:
parent
d48517b29d
commit
40f5c5b987
@ -3,18 +3,18 @@ package outbound
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
N "github.com/metacubex/mihomo/common/net"
|
N "github.com/metacubex/mihomo/common/net"
|
||||||
"github.com/metacubex/mihomo/component/dialer"
|
"github.com/metacubex/mihomo/component/dialer"
|
||||||
|
"github.com/metacubex/mihomo/component/loopback"
|
||||||
"github.com/metacubex/mihomo/component/resolver"
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Direct struct {
|
type Direct struct {
|
||||||
*Base
|
*Base
|
||||||
loopBack *loopBackDetector
|
loopBack *loopback.Detector
|
||||||
}
|
}
|
||||||
|
|
||||||
type DirectOption struct {
|
type DirectOption struct {
|
||||||
@ -24,8 +24,8 @@ type DirectOption struct {
|
|||||||
|
|
||||||
// DialContext implements C.ProxyAdapter
|
// DialContext implements C.ProxyAdapter
|
||||||
func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
|
func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
|
||||||
if d.loopBack.CheckConn(metadata.SourceAddrPort()) {
|
if err := d.loopBack.CheckConn(metadata); err != nil {
|
||||||
return nil, fmt.Errorf("reject loopback connection to: %s", metadata.RemoteAddress())
|
return nil, err
|
||||||
}
|
}
|
||||||
opts = append(opts, dialer.WithResolver(resolver.DefaultResolver))
|
opts = append(opts, dialer.WithResolver(resolver.DefaultResolver))
|
||||||
c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
|
c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
|
||||||
@ -38,8 +38,8 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
|
|||||||
|
|
||||||
// ListenPacketContext implements C.ProxyAdapter
|
// ListenPacketContext implements C.ProxyAdapter
|
||||||
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
|
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
|
||||||
if d.loopBack.CheckPacketConn(metadata.SourceAddrPort()) {
|
if err := d.loopBack.CheckPacketConn(metadata); err != nil {
|
||||||
return nil, fmt.Errorf("reject loopback connection to: %s", metadata.RemoteAddress())
|
return nil, err
|
||||||
}
|
}
|
||||||
// net.UDPConn.WriteTo only working with *net.UDPAddr, so we need a net.UDPAddr
|
// net.UDPConn.WriteTo only working with *net.UDPAddr, so we need a net.UDPAddr
|
||||||
if !metadata.Resolved() {
|
if !metadata.Resolved() {
|
||||||
@ -68,7 +68,7 @@ func NewDirectWithOption(option DirectOption) *Direct {
|
|||||||
rmark: option.RoutingMark,
|
rmark: option.RoutingMark,
|
||||||
prefer: C.NewDNSPrefer(option.IPVersion),
|
prefer: C.NewDNSPrefer(option.IPVersion),
|
||||||
},
|
},
|
||||||
loopBack: newLoopBackDetector(),
|
loopBack: loopback.NewDetector(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ func NewDirect() *Direct {
|
|||||||
udp: true,
|
udp: true,
|
||||||
prefer: C.DualStack,
|
prefer: C.DualStack,
|
||||||
},
|
},
|
||||||
loopBack: newLoopBackDetector(),
|
loopBack: loopback.NewDetector(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +92,6 @@ func NewCompatible() *Direct {
|
|||||||
udp: true,
|
udp: true,
|
||||||
prefer: C.DualStack,
|
prefer: C.DualStack,
|
||||||
},
|
},
|
||||||
loopBack: newLoopBackDetector(),
|
loopBack: loopback.NewDetector(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package outbound
|
package loopback
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/common/callback"
|
"github.com/metacubex/mihomo/common/callback"
|
||||||
@ -9,19 +11,21 @@ import (
|
|||||||
"github.com/puzpuzpuz/xsync/v3"
|
"github.com/puzpuzpuz/xsync/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type loopBackDetector struct {
|
var ErrReject = errors.New("reject loopback connection")
|
||||||
|
|
||||||
|
type Detector struct {
|
||||||
connMap *xsync.MapOf[netip.AddrPort, struct{}]
|
connMap *xsync.MapOf[netip.AddrPort, struct{}]
|
||||||
packetConnMap *xsync.MapOf[netip.AddrPort, struct{}]
|
packetConnMap *xsync.MapOf[netip.AddrPort, struct{}]
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLoopBackDetector() *loopBackDetector {
|
func NewDetector() *Detector {
|
||||||
return &loopBackDetector{
|
return &Detector{
|
||||||
connMap: xsync.NewMapOf[netip.AddrPort, struct{}](),
|
connMap: xsync.NewMapOf[netip.AddrPort, struct{}](),
|
||||||
packetConnMap: xsync.NewMapOf[netip.AddrPort, struct{}](),
|
packetConnMap: xsync.NewMapOf[netip.AddrPort, struct{}](),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopBackDetector) NewConn(conn C.Conn) C.Conn {
|
func (l *Detector) NewConn(conn C.Conn) C.Conn {
|
||||||
metadata := C.Metadata{}
|
metadata := C.Metadata{}
|
||||||
if metadata.SetRemoteAddr(conn.LocalAddr()) != nil {
|
if metadata.SetRemoteAddr(conn.LocalAddr()) != nil {
|
||||||
return conn
|
return conn
|
||||||
@ -36,7 +40,7 @@ func (l *loopBackDetector) NewConn(conn C.Conn) C.Conn {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopBackDetector) NewPacketConn(conn C.PacketConn) C.PacketConn {
|
func (l *Detector) NewPacketConn(conn C.PacketConn) C.PacketConn {
|
||||||
metadata := C.Metadata{}
|
metadata := C.Metadata{}
|
||||||
if metadata.SetRemoteAddr(conn.LocalAddr()) != nil {
|
if metadata.SetRemoteAddr(conn.LocalAddr()) != nil {
|
||||||
return conn
|
return conn
|
||||||
@ -51,18 +55,24 @@ func (l *loopBackDetector) NewPacketConn(conn C.PacketConn) C.PacketConn {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopBackDetector) CheckConn(connAddr netip.AddrPort) bool {
|
func (l *Detector) CheckConn(metadata *C.Metadata) error {
|
||||||
|
connAddr := metadata.SourceAddrPort()
|
||||||
if !connAddr.IsValid() {
|
if !connAddr.IsValid() {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
_, ok := l.connMap.Load(connAddr)
|
if _, ok := l.connMap.Load(connAddr); ok {
|
||||||
return ok
|
return fmt.Errorf("%w to: %s", ErrReject, metadata.RemoteAddress())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loopBackDetector) CheckPacketConn(connAddr netip.AddrPort) bool {
|
func (l *Detector) CheckPacketConn(metadata *C.Metadata) error {
|
||||||
|
connAddr := metadata.SourceAddrPort()
|
||||||
if !connAddr.IsValid() {
|
if !connAddr.IsValid() {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
_, ok := l.packetConnMap.Load(connAddr)
|
if _, ok := l.packetConnMap.Load(connAddr); ok {
|
||||||
return ok
|
return fmt.Errorf("%w to: %s", ErrReject, metadata.RemoteAddress())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
@ -12,6 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
N "github.com/metacubex/mihomo/common/net"
|
N "github.com/metacubex/mihomo/common/net"
|
||||||
|
"github.com/metacubex/mihomo/component/loopback"
|
||||||
"github.com/metacubex/mihomo/component/nat"
|
"github.com/metacubex/mihomo/component/nat"
|
||||||
P "github.com/metacubex/mihomo/component/process"
|
P "github.com/metacubex/mihomo/component/process"
|
||||||
"github.com/metacubex/mihomo/component/resolver"
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
@ -694,6 +695,9 @@ func shouldStopRetry(err error) bool {
|
|||||||
if errors.Is(err, resolver.ErrIPv6Disabled) {
|
if errors.Is(err, resolver.ErrIPv6Disabled) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if errors.Is(err, loopback.ErrReject) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user