github.com/imannamdari/v2ray-core/v5@v5.0.5/transport/internet/sockopt_darwin.go (about)

     1  package internet
     2  
     3  import (
     4  	"net"
     5  
     6  	"golang.org/x/sys/unix"
     7  )
     8  
     9  const (
    10  	// TCP_FASTOPEN_SERVER is the value to enable TCP fast open on darwin for server connections.
    11  	TCP_FASTOPEN_SERVER = 0x01 // nolint: revive,stylecheck
    12  	// TCP_FASTOPEN_CLIENT is the value to enable TCP fast open on darwin for client connections.
    13  	TCP_FASTOPEN_CLIENT = 0x02 // nolint: revive,stylecheck
    14  )
    15  
    16  func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
    17  	if isTCPSocket(network) {
    18  		switch config.Tfo {
    19  		case SocketConfig_Enable:
    20  			if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_FASTOPEN, TCP_FASTOPEN_CLIENT); err != nil {
    21  				return err
    22  			}
    23  		case SocketConfig_Disable:
    24  			if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_FASTOPEN, 0); err != nil {
    25  				return err
    26  			}
    27  		}
    28  
    29  		if config.TcpKeepAliveInterval > 0 {
    30  			if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil {
    31  				return newError("failed to set TCP_KEEPINTVL").Base(err)
    32  			}
    33  		}
    34  		if config.TcpKeepAliveIdle > 0 {
    35  			if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveIdle)); err != nil {
    36  				return newError("failed to set TCP_KEEPALIVE (TCP keepalive idle time on Darwin)").Base(err)
    37  			}
    38  		}
    39  
    40  		if config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 {
    41  			if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil {
    42  				return newError("failed to set SO_KEEPALIVE").Base(err)
    43  			}
    44  		}
    45  	}
    46  
    47  	if config.BindToDevice != "" {
    48  		iface, err := net.InterfaceByName(config.BindToDevice)
    49  		if err != nil {
    50  			return newError("failed to get interface ", config.BindToDevice).Base(err)
    51  		}
    52  		if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index); err != nil {
    53  			return newError("failed to set IP_BOUND_IF", err)
    54  		}
    55  		if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, iface.Index); err != nil {
    56  			return newError("failed to set IPV6_BOUND_IF", err)
    57  		}
    58  	}
    59  
    60  	if config.TxBufSize != 0 {
    61  		if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF, int(config.TxBufSize)); err != nil {
    62  			return newError("failed to set SO_SNDBUF").Base(err)
    63  		}
    64  	}
    65  
    66  	if config.RxBufSize != 0 {
    67  		if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF, int(config.RxBufSize)); err != nil {
    68  			return newError("failed to set SO_RCVBUF").Base(err)
    69  		}
    70  	}
    71  
    72  	return nil
    73  }
    74  
    75  func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
    76  	if isTCPSocket(network) {
    77  		switch config.Tfo {
    78  		case SocketConfig_Enable:
    79  			if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_FASTOPEN, TCP_FASTOPEN_SERVER); err != nil {
    80  				return err
    81  			}
    82  		case SocketConfig_Disable:
    83  			if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_FASTOPEN, 0); err != nil {
    84  				return err
    85  			}
    86  		}
    87  		if config.TcpKeepAliveInterval > 0 {
    88  			if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil {
    89  				return newError("failed to set TCP_KEEPINTVL").Base(err)
    90  			}
    91  		}
    92  		if config.TcpKeepAliveIdle > 0 {
    93  			if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveIdle)); err != nil {
    94  				return newError("failed to set TCP_KEEPALIVE (TCP keepalive idle time on Darwin)").Base(err)
    95  			}
    96  		}
    97  		if config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 {
    98  			if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil {
    99  				return newError("failed to set SO_KEEPALIVE").Base(err)
   100  			}
   101  		}
   102  	}
   103  
   104  	if config.BindToDevice != "" {
   105  		iface, err := net.InterfaceByName(config.BindToDevice)
   106  		if err != nil {
   107  			return newError("failed to get interface ", config.BindToDevice).Base(err)
   108  		}
   109  		if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index); err != nil {
   110  			return newError("failed to set IP_BOUND_IF", err)
   111  		}
   112  		if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, iface.Index); err != nil {
   113  			return newError("failed to set IPV6_BOUND_IF", err)
   114  		}
   115  	}
   116  
   117  	if config.TxBufSize != 0 {
   118  		if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF, int(config.TxBufSize)); err != nil {
   119  			return newError("failed to set SO_SNDBUF/SO_SNDBUFFORCE").Base(err)
   120  		}
   121  	}
   122  
   123  	if config.RxBufSize != 0 {
   124  		if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF, int(config.RxBufSize)); err != nil {
   125  			return newError("failed to set SO_RCVBUF/SO_RCVBUFFORCE").Base(err)
   126  		}
   127  	}
   128  	return nil
   129  }
   130  
   131  func bindAddr(fd uintptr, address []byte, port uint32) error {
   132  	return nil
   133  }
   134  
   135  func setReuseAddr(fd uintptr) error {
   136  	return nil
   137  }
   138  
   139  func setReusePort(fd uintptr) error {
   140  	return nil
   141  }