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