github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/dialer/setopt_darwin.go (about) 1 package dialer 2 3 import ( 4 "net" 5 "syscall" 6 7 "golang.org/x/sys/unix" 8 ) 9 10 // syscall.TCP_KEEPINTVL is missing on some darwin architectures. 11 const sysTCP_KEEPINTVL = 0x101 12 13 func setSocketOptions(network, address string, c syscall.RawConn, opts *Options) (err error) { 14 if opts == nil || !isTCPSocket(network) && !isUDPSocket(network) { 15 return 16 } 17 18 var innerErr error 19 err = c.Control(func(fd uintptr) { 20 if opts.listener { 21 _ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF, SocketBufferSize) 22 _ = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF, SocketBufferSize) 23 } 24 25 if isTCPSocket(network) { 26 // _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, sysTCP_KEEPINTVL, int(15)) 27 // _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPALIVE, int(180)) 28 _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1) 29 } 30 31 host, _, _ := net.SplitHostPort(address) 32 if ip := net.ParseIP(host); ip != nil && !ip.IsGlobalUnicast() { 33 return 34 } 35 36 if opts.listener { 37 return 38 } 39 40 if opts.InterfaceIndex == 0 && opts.InterfaceName != "" { 41 if iface, err := net.InterfaceByName(opts.InterfaceName); err == nil { 42 opts.InterfaceIndex = iface.Index 43 } 44 } 45 46 if opts.InterfaceIndex != 0 { 47 switch network { 48 case "tcp4", "udp4": 49 innerErr = unix.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, opts.InterfaceIndex) 50 case "tcp6", "udp6": 51 innerErr = unix.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BOUND_IF, opts.InterfaceIndex) 52 } 53 if innerErr != nil { 54 return 55 } 56 } 57 }) 58 59 if innerErr != nil { 60 err = innerErr 61 } 62 return 63 }