diff --git a/transport/internet/sockopt_darwin.go b/transport/internet/sockopt_darwin.go index 79e2133a0b19..86af492a9219 100644 --- a/transport/internet/sockopt_darwin.go +++ b/transport/internet/sockopt_darwin.go @@ -1,7 +1,7 @@ package internet import ( - network "net" + gonet "net" "os" "syscall" "unsafe" @@ -108,14 +108,6 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf return err } } - if config.Interface != "" { - InterfaceIndex := getInterfaceIndexByName(config.Interface) - if InterfaceIndex != 0 { - if err := unix.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, InterfaceIndex); err != nil { - return errors.New("failed to set Interface").Base(err) - } - } - } if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { if config.TcpKeepAliveIdle > 0 { @@ -138,6 +130,23 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf } } + if config.Interface != "" { + iface, err := gonet.InterfaceByName(config.Interface) + + if err != nil { + return errors.New("failed to get interface ", config.Interface).Base(err) + } + if network == "tcp6" || network == "udp6" { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, iface.Index); err != nil { + return errors.New("failed to set IPV6_BOUND_IF").Base(err) + } + } else { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index); err != nil { + return errors.New("failed to set IP_BOUND_IF").Base(err) + } + } + } + return nil } @@ -152,14 +161,6 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) return err } } - if config.Interface != "" { - InterfaceIndex := getInterfaceIndexByName(config.Interface) - if InterfaceIndex != 0 { - if err := unix.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, InterfaceIndex); err != nil { - return errors.New("failed to set Interface").Base(err) - } - } - } if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { if config.TcpKeepAliveIdle > 0 { @@ -182,6 +183,23 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) } } + if config.Interface != "" { + iface, err := gonet.InterfaceByName(config.Interface) + + if err != nil { + return errors.New("failed to get interface ", config.Interface).Base(err) + } + if network == "tcp6" || network == "udp6" { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, iface.Index); err != nil { + return errors.New("failed to set IPV6_BOUND_IF").Base(err) + } + } else { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index); err != nil { + return errors.New("failed to set IP_BOUND_IF").Base(err) + } + } + } + return nil } @@ -224,24 +242,3 @@ func setReusePort(fd uintptr) error { } return nil } -func getInterfaceIndexByName(name string) int { - ifaces, err := network.Interfaces() - if err == nil { - for _, iface := range ifaces { - if (iface.Flags&network.FlagUp == network.FlagUp) && (iface.Flags&network.FlagLoopback != network.FlagLoopback) { - addrs, _ := iface.Addrs() - for _, addr := range addrs { - if ipnet, ok := addr.(*network.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To4() != nil { - if iface.Name == name { - return iface.Index - } - } - } - } - } - - } - } - return 0 -}