github.com/sagernet/sing@v0.2.6/common/control/bind.go (about) 1 package control 2 3 import ( 4 "os" 5 "runtime" 6 "syscall" 7 8 M "github.com/sagernet/sing/common/metadata" 9 N "github.com/sagernet/sing/common/network" 10 ) 11 12 func BindToInterface(finder InterfaceFinder, interfaceName string, interfaceIndex int) Func { 13 return func(network, address string, conn syscall.RawConn) error { 14 return BindToInterface0(finder, conn, network, address, interfaceName, interfaceIndex) 15 } 16 } 17 18 func BindToInterfaceFunc(finder InterfaceFinder, block func(network string, address string) (interfaceName string, interfaceIndex int)) Func { 19 return func(network, address string, conn syscall.RawConn) error { 20 interfaceName, interfaceIndex := block(network, address) 21 return BindToInterface0(finder, conn, network, address, interfaceName, interfaceIndex) 22 } 23 } 24 25 const useInterfaceName = runtime.GOOS == "linux" || runtime.GOOS == "android" 26 27 func BindToInterface0(finder InterfaceFinder, conn syscall.RawConn, network string, address string, interfaceName string, interfaceIndex int) error { 28 if addr := M.ParseSocksaddr(address).Addr; addr.IsValid() && N.IsVirtual(addr) { 29 return nil 30 } 31 if interfaceName == "" && interfaceIndex == -1 { 32 return nil 33 } 34 if interfaceName != "" && useInterfaceName || interfaceIndex != -1 && !useInterfaceName { 35 return bindToInterface(conn, network, address, interfaceName, interfaceIndex) 36 } 37 if finder == nil { 38 return os.ErrInvalid 39 } 40 var err error 41 if useInterfaceName { 42 interfaceName, err = finder.InterfaceNameByIndex(interfaceIndex) 43 } else { 44 interfaceIndex, err = finder.InterfaceIndexByName(interfaceName) 45 } 46 if err != nil { 47 return err 48 } 49 if useInterfaceName { 50 if interfaceName == "" { 51 return nil 52 } 53 } else { 54 if interfaceIndex == -1 { 55 return nil 56 } 57 } 58 return bindToInterface(conn, network, address, interfaceName, interfaceIndex) 59 }