github.com/metacubex/mihomo@v1.18.5/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 if err == nil { 39 _ = setDSCPsockopt(fd, isIPv6) 40 } 41 }) 42 43 return err 44 } 45 46 func setDSCPsockopt(fd uintptr, isIPv6 bool) (err error) { 47 if err == nil { 48 err = syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_RECVTOS, 1) 49 } 50 51 if err == nil && isIPv6 { 52 err = syscall.SetsockoptInt(int(fd), syscall.SOL_IPV6, syscall.IPV6_RECVTCLASS, 1) 53 } 54 55 return 56 }