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  }