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 }