diff --git a/component/dialer/bind.go b/component/dialer/bind.go index 55e5f163..0ad52068 100644 --- a/component/dialer/bind.go +++ b/component/dialer/bind.go @@ -3,8 +3,14 @@ package dialer import ( "errors" "net" + "time" + + "github.com/Dreamacro/clash/common/singledo" ) +// In some OS, such as Windows, it takes a little longer to get interface information +var ifaceSingle = singledo.NewSingle(time.Second * 20) + var ( errPlatformNotSupport = errors.New("unsupport platform") ) @@ -56,12 +62,14 @@ func fallbackBindToDialer(dialer *net.Dialer, network string, ip net.IP, name st return nil } - iface, err := net.InterfaceByName(name) + iface, err, _ := ifaceSingle.Do(func() (interface{}, error) { + return net.InterfaceByName(name) + }) if err != nil { return err } - addrs, err := iface.Addrs() + addrs, err := iface.(*net.Interface).Addrs() if err != nil { return err } @@ -85,12 +93,14 @@ func fallbackBindToDialer(dialer *net.Dialer, network string, ip net.IP, name st } func fallbackBindToListenConfig(name string) (string, error) { - iface, err := net.InterfaceByName(name) + iface, err, _ := ifaceSingle.Do(func() (interface{}, error) { + return net.InterfaceByName(name) + }) if err != nil { return "", err } - addrs, err := iface.Addrs() + addrs, err := iface.(*net.Interface).Addrs() if err != nil { return "", err } diff --git a/component/dialer/bind_darwin.go b/component/dialer/bind_darwin.go index 469054ca..0ce50541 100644 --- a/component/dialer/bind_darwin.go +++ b/component/dialer/bind_darwin.go @@ -29,23 +29,25 @@ func bindControl(ifaceIdx int) controlFn { } func bindIfaceToDialer(dialer *net.Dialer, ifaceName string) error { - iface, err := net.InterfaceByName(ifaceName) + iface, err, _ := ifaceSingle.Do(func() (interface{}, error) { + return net.InterfaceByName(ifaceName) + }) if err != nil { return err } - dialer.Control = bindControl(iface.Index) - + dialer.Control = bindControl(iface.(*net.Interface).Index) return nil } func bindIfaceToListenConfig(lc *net.ListenConfig, ifaceName string) error { - iface, err := net.InterfaceByName(ifaceName) + iface, err, _ := ifaceSingle.Do(func() (interface{}, error) { + return net.InterfaceByName(ifaceName) + }) if err != nil { return err } - lc.Control = bindControl(iface.Index) - + lc.Control = bindControl(iface.(*net.Interface).Index) return nil }