diff --git a/common/control/bind.go b/common/control/bind.go index b8451db..0dd2107 100644 --- a/common/control/bind.go +++ b/common/control/bind.go @@ -10,7 +10,7 @@ import ( func BindToInterface(finder InterfaceFinder, interfaceName string, interfaceIndex int) Func { return func(network, address string, conn syscall.RawConn) error { - return BindToInterface0(finder, conn, network, address, interfaceName, interfaceIndex) + return BindToInterface0(finder, conn, network, address, interfaceName, interfaceIndex, false) } } @@ -20,16 +20,16 @@ func BindToInterfaceFunc(finder InterfaceFinder, block func(network string, addr if err != nil { return err } - return BindToInterface0(finder, conn, network, address, interfaceName, interfaceIndex) + return BindToInterface0(finder, conn, network, address, interfaceName, interfaceIndex, false) } } -func BindToInterface0(finder InterfaceFinder, conn syscall.RawConn, network string, address string, interfaceName string, interfaceIndex int) error { +func BindToInterface0(finder InterfaceFinder, conn syscall.RawConn, network string, address string, interfaceName string, interfaceIndex int, preferInterfaceName bool) error { if interfaceName == "" && interfaceIndex == -1 { return E.New("interface not found: ", interfaceName) } if addr := M.ParseSocksaddr(address).Addr; addr.IsValid() && N.IsVirtual(addr) { return nil } - return bindToInterface(conn, network, address, finder, interfaceName, interfaceIndex) + return bindToInterface(conn, network, address, finder, interfaceName, interfaceIndex, preferInterfaceName) } diff --git a/common/control/bind_darwin.go b/common/control/bind_darwin.go index f5be42d..bff6c29 100644 --- a/common/control/bind_darwin.go +++ b/common/control/bind_darwin.go @@ -7,7 +7,7 @@ import ( "golang.org/x/sys/unix" ) -func bindToInterface(conn syscall.RawConn, network string, address string, finder InterfaceFinder, interfaceName string, interfaceIndex int) error { +func bindToInterface(conn syscall.RawConn, network string, address string, finder InterfaceFinder, interfaceName string, interfaceIndex int, preferInterfaceName bool) error { return Raw(conn, func(fd uintptr) error { var err error if interfaceIndex == -1 { diff --git a/common/control/bind_linux.go b/common/control/bind_linux.go index 51529a0..3e8c8a3 100644 --- a/common/control/bind_linux.go +++ b/common/control/bind_linux.go @@ -12,18 +12,19 @@ import ( var ifIndexDisabled atomic.Bool -func bindToInterface(conn syscall.RawConn, network string, address string, finder InterfaceFinder, interfaceName string, interfaceIndex int) error { +func bindToInterface(conn syscall.RawConn, network string, address string, finder InterfaceFinder, interfaceName string, interfaceIndex int, preferInterfaceName bool) error { return Raw(conn, func(fd uintptr) error { - var err error - if !ifIndexDisabled.Load() { - if interfaceIndex == -1 { - if finder == nil { - return os.ErrInvalid - } - interfaceIndex, err = finder.InterfaceIndexByName(interfaceName) - if err != nil { - return err - } + if interfaceIndex != -1 { + return unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_BINDTOIFINDEX, interfaceIndex) + } + if interfaceName == "" { + return os.ErrInvalid + } + if !preferInterfaceName && finder != nil && !ifIndexDisabled.Load() { + var err error + interfaceIndex, err = finder.InterfaceIndexByName(interfaceName) + if err != nil { + return err } err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_BINDTOIFINDEX, interfaceIndex) if err == nil { @@ -34,15 +35,6 @@ func bindToInterface(conn syscall.RawConn, network string, address string, finde return err } } - if interfaceName == "" { - if finder == nil { - return os.ErrInvalid - } - interfaceName, err = finder.InterfaceNameByIndex(interfaceIndex) - if err != nil { - return err - } - } return unix.BindToDevice(int(fd), interfaceName) }) } diff --git a/common/control/bind_other.go b/common/control/bind_other.go index 539ef1c..23a884f 100644 --- a/common/control/bind_other.go +++ b/common/control/bind_other.go @@ -4,6 +4,6 @@ package control import "syscall" -func bindToInterface(conn syscall.RawConn, network string, address string, finder InterfaceFinder, interfaceName string, interfaceIndex int) error { +func bindToInterface(conn syscall.RawConn, network string, address string, finder InterfaceFinder, interfaceName string, interfaceIndex int, preferInterfaceName bool) error { return nil } diff --git a/common/control/bind_windows.go b/common/control/bind_windows.go index 7029c80..a499556 100644 --- a/common/control/bind_windows.go +++ b/common/control/bind_windows.go @@ -9,7 +9,7 @@ import ( M "github.com/sagernet/sing/common/metadata" ) -func bindToInterface(conn syscall.RawConn, network string, address string, finder InterfaceFinder, interfaceName string, interfaceIndex int) error { +func bindToInterface(conn syscall.RawConn, network string, address string, finder InterfaceFinder, interfaceName string, interfaceIndex int, preferInterfaceName bool) error { return Raw(conn, func(fd uintptr) error { var err error if interfaceIndex == -1 {