From e839beb73bef368880fc474a44d82f68e809da28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sat, 20 Aug 2022 13:31:15 +0800 Subject: [PATCH] Skip bind connection with private destination to interface --- common/dialer/bind.go | 19 +++++++++++++++++++ common/dialer/default.go | 12 ++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 common/dialer/bind.go diff --git a/common/dialer/bind.go b/common/dialer/bind.go new file mode 100644 index 00000000..14922471 --- /dev/null +++ b/common/dialer/bind.go @@ -0,0 +1,19 @@ +package dialer + +import ( + "syscall" + + "github.com/sagernet/sing/common/control" + M "github.com/sagernet/sing/common/metadata" + N "github.com/sagernet/sing/common/network" +) + +func skipIfPrivate(next control.Func) control.Func { + return func(network, address string, conn syscall.RawConn) error { + destination := M.ParseSocksaddr(address) + if !N.IsPublicAddr(destination.Addr) { + return nil + } + return next(network, address, conn) + } +} diff --git a/common/dialer/default.go b/common/dialer/default.go index 837abe4c..a5642174 100644 --- a/common/dialer/default.go +++ b/common/dialer/default.go @@ -61,25 +61,25 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia var listener net.ListenConfig if options.BindInterface != "" { warnBindInterfaceOnUnsupportedPlatform.Check() - bindFunc := control.BindToInterface(router.InterfaceBindManager(), options.BindInterface) + bindFunc := skipIfPrivate(control.BindToInterface(router.InterfaceBindManager(), options.BindInterface)) dialer.Control = control.Append(dialer.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc) } else if router.AutoDetectInterface() { if C.IsWindows { - bindFunc := control.BindToInterfaceIndexFunc(func() int { + bindFunc := skipIfPrivate(control.BindToInterfaceIndexFunc(func() int { return router.InterfaceMonitor().DefaultInterfaceIndex() - }) + })) dialer.Control = control.Append(dialer.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc) } else { - bindFunc := control.BindToInterfaceFunc(router.InterfaceBindManager(), func() string { + bindFunc := skipIfPrivate(control.BindToInterfaceFunc(router.InterfaceBindManager(), func() string { return router.InterfaceMonitor().DefaultInterfaceName() - }) + })) dialer.Control = control.Append(dialer.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc) } } else if router.DefaultInterface() != "" { - bindFunc := control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface()) + bindFunc := skipIfPrivate(control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface())) dialer.Control = control.Append(dialer.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc) }