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