binding socket interface to sockopt_darwin.go

This commit is contained in:
Hossin Asaadi 2023-09-20 19:08:48 +04:00 committed by yuhan6665
parent 4f6042c69f
commit 07ae08126c

View File

@ -1,6 +1,7 @@
package internet package internet
import ( import (
network "net"
"os" "os"
"syscall" "syscall"
"unsafe" "unsafe"
@ -106,6 +107,14 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
return err 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 newError("failed to set Interface").Base(err)
}
}
}
if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 {
if config.TcpKeepAliveIdle > 0 { if config.TcpKeepAliveIdle > 0 {
@ -148,6 +157,15 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
return err 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 newError("failed to set Interface").Base(err)
}
}
}
if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 {
if config.TcpKeepAliveIdle > 0 { if config.TcpKeepAliveIdle > 0 {
if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveInterval)); err != nil { if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveInterval)); err != nil {
@ -183,3 +201,24 @@ func setReuseAddr(fd uintptr) error {
func setReusePort(fd uintptr) error { func setReusePort(fd uintptr) error {
return nil 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
}