github.com/chwjbn/xclash@v0.2.0/listener/tproxy/setsockopt_linux.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  package tproxy
     5  
     6  import (
     7  	"net"
     8  	"syscall"
     9  )
    10  
    11  func setsockopt(rc syscall.RawConn, addr string) error {
    12  	isIPv6 := true
    13  	host, _, err := net.SplitHostPort(addr)
    14  	if err != nil {
    15  		return err
    16  	}
    17  	ip := net.ParseIP(host)
    18  	if ip != nil && ip.To4() != nil {
    19  		isIPv6 = false
    20  	}
    21  
    22  	rc.Control(func(fd uintptr) {
    23  		err = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
    24  
    25  		if err == nil {
    26  			err = syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1)
    27  		}
    28  		if err == nil && isIPv6 {
    29  			err = syscall.SetsockoptInt(int(fd), syscall.SOL_IPV6, IPV6_TRANSPARENT, 1)
    30  		}
    31  
    32  		if err == nil {
    33  			err = syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_RECVORIGDSTADDR, 1)
    34  		}
    35  		if err == nil && isIPv6 {
    36  			err = syscall.SetsockoptInt(int(fd), syscall.SOL_IPV6, IPV6_RECVORIGDSTADDR, 1)
    37  		}
    38  	})
    39  
    40  	return err
    41  }