github.com/igoogolx/clash@v1.19.8/component/dialer/mark_linux.go (about) 1 //go:build linux 2 3 package dialer 4 5 import ( 6 "net" 7 "syscall" 8 ) 9 10 func bindMarkToDialer(mark int, dialer *net.Dialer, _ string, _ net.IP) { 11 dialer.Control = bindMarkToControl(mark, dialer.Control) 12 } 13 14 func bindMarkToListenConfig(mark int, lc *net.ListenConfig, _, address string) { 15 lc.Control = bindMarkToControl(mark, lc.Control) 16 } 17 18 func bindMarkToControl(mark int, chain controlFn) controlFn { 19 return func(network, address string, c syscall.RawConn) (err error) { 20 defer func() { 21 if err == nil && chain != nil { 22 err = chain(network, address, c) 23 } 24 }() 25 26 ipStr, _, err := net.SplitHostPort(address) 27 if err == nil { 28 ip := net.ParseIP(ipStr) 29 if ip != nil && !ip.IsGlobalUnicast() { 30 return 31 } 32 } 33 34 var innerErr error 35 err = c.Control(func(fd uintptr) { 36 innerErr = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, mark) 37 }) 38 if innerErr != nil { 39 err = innerErr 40 } 41 return 42 } 43 }