github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/transport/internet/sockopt_windows.go (about)

     1  package internet
     2  
     3  import (
     4  	"encoding/binary"
     5  	"net"
     6  	"syscall"
     7  	"unsafe"
     8  )
     9  
    10  const (
    11  	TCP_FASTOPEN    = 15
    12  	IP_UNICAST_IF   = 31
    13  	IPV6_UNICAST_IF = 31
    14  )
    15  
    16  func setTFO(fd syscall.Handle, tfo int) error {
    17  	if tfo > 0 {
    18  		tfo = 1
    19  	}
    20  	if tfo >= 0 {
    21  		if err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, TCP_FASTOPEN, tfo); err != nil {
    22  			return err
    23  		}
    24  	}
    25  	return nil
    26  }
    27  
    28  func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
    29  	if config.Interface != "" {
    30  		inf, err := net.InterfaceByName(config.Interface)
    31  		if err != nil {
    32  			return newError("failed to find the interface").Base(err)
    33  		}
    34  		isV4 := (network == "tcp4")
    35  		if isV4 {
    36  			var bytes [4]byte
    37  			binary.BigEndian.PutUint32(bytes[:], uint32(inf.Index))
    38  			idx := *(*uint32)(unsafe.Pointer(&bytes[0]))
    39  			if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, IP_UNICAST_IF, int(idx)); err != nil {
    40  				return newError("failed to set IP_UNICAST_IF").Base(err)
    41  			}
    42  		} else {
    43  			if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IPV6, IPV6_UNICAST_IF, inf.Index); err != nil {
    44  				return newError("failed to set IPV6_UNICAST_IF").Base(err)
    45  			}
    46  		}
    47  	}
    48  
    49  	if isTCPSocket(network) {
    50  		if err := setTFO(syscall.Handle(fd), config.ParseTFOValue()); err != nil {
    51  			return err
    52  		}
    53  		if config.TcpKeepAliveIdle > 0 {
    54  			if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {
    55  				return newError("failed to set SO_KEEPALIVE", err)
    56  			}
    57  		} else if config.TcpKeepAliveIdle < 0 {
    58  			if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 0); err != nil {
    59  				return newError("failed to unset SO_KEEPALIVE", err)
    60  			}
    61  		}
    62  		if config.TcpNoDelay {
    63  			if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_TCP, syscall.TCP_NODELAY, 1); err != nil {
    64  				return newError("failed to set TCP_NODELAY", err)
    65  			}
    66  		}
    67  	}
    68  
    69  	return nil
    70  }
    71  
    72  func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
    73  	if isTCPSocket(network) {
    74  		if err := setTFO(syscall.Handle(fd), config.ParseTFOValue()); err != nil {
    75  			return err
    76  		}
    77  		if config.TcpKeepAliveIdle > 0 {
    78  			if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {
    79  				return newError("failed to set SO_KEEPALIVE", err)
    80  			}
    81  		} else if config.TcpKeepAliveIdle < 0 {
    82  			if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 0); err != nil {
    83  				return newError("failed to unset SO_KEEPALIVE", err)
    84  			}
    85  		}
    86  	}
    87  
    88  	return nil
    89  }
    90  
    91  func bindAddr(fd uintptr, ip []byte, port uint32) error {
    92  	return nil
    93  }
    94  
    95  func setReuseAddr(fd uintptr) error {
    96  	return nil
    97  }
    98  
    99  func setReusePort(fd uintptr) error {
   100  	return nil
   101  }