chore: use singleDo to get interface info

This commit is contained in:
Dreamacro 2021-01-13 17:30:54 +08:00
parent b6ee47a541
commit e4cdea2111
2 changed files with 22 additions and 10 deletions

View file

@ -3,8 +3,14 @@ package dialer
import ( import (
"errors" "errors"
"net" "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 ( var (
errPlatformNotSupport = errors.New("unsupport platform") errPlatformNotSupport = errors.New("unsupport platform")
) )
@ -56,12 +62,14 @@ func fallbackBindToDialer(dialer *net.Dialer, network string, ip net.IP, name st
return nil return nil
} }
iface, err := net.InterfaceByName(name) iface, err, _ := ifaceSingle.Do(func() (interface{}, error) {
return net.InterfaceByName(name)
})
if err != nil { if err != nil {
return err return err
} }
addrs, err := iface.Addrs() addrs, err := iface.(*net.Interface).Addrs()
if err != nil { if err != nil {
return err return err
} }
@ -85,12 +93,14 @@ func fallbackBindToDialer(dialer *net.Dialer, network string, ip net.IP, name st
} }
func fallbackBindToListenConfig(name string) (string, error) { 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 { if err != nil {
return "", err return "", err
} }
addrs, err := iface.Addrs() addrs, err := iface.(*net.Interface).Addrs()
if err != nil { if err != nil {
return "", err return "", err
} }

View file

@ -29,23 +29,25 @@ func bindControl(ifaceIdx int) controlFn {
} }
func bindIfaceToDialer(dialer *net.Dialer, ifaceName string) error { 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 { if err != nil {
return err return err
} }
dialer.Control = bindControl(iface.Index) dialer.Control = bindControl(iface.(*net.Interface).Index)
return nil return nil
} }
func bindIfaceToListenConfig(lc *net.ListenConfig, ifaceName string) error { 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 { if err != nil {
return err return err
} }
lc.Control = bindControl(iface.Index) lc.Control = bindControl(iface.(*net.Interface).Index)
return nil return nil
} }