github.com/kelleygo/clashcore@v1.0.2/component/dialer/mark_linux.go (about)

     1  //go:build linux
     2  
     3  package dialer
     4  
     5  import (
     6  	"context"
     7  	"net"
     8  	"net/netip"
     9  	"syscall"
    10  )
    11  
    12  func bindMarkToDialer(mark int, dialer *net.Dialer, _ string, _ netip.Addr) {
    13  	addControlToDialer(dialer, bindMarkToControl(mark))
    14  }
    15  
    16  func bindMarkToListenConfig(mark int, lc *net.ListenConfig, _, _ string) {
    17  	addControlToListenConfig(lc, bindMarkToControl(mark))
    18  }
    19  
    20  func bindMarkToControl(mark int) controlFn {
    21  	return func(ctx context.Context, network, address string, c syscall.RawConn) (err error) {
    22  
    23  		addrPort, err := netip.ParseAddrPort(address)
    24  		if err == nil && !addrPort.Addr().IsGlobalUnicast() {
    25  			return
    26  		}
    27  
    28  		var innerErr error
    29  		err = c.Control(func(fd uintptr) {
    30  			innerErr = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, mark)
    31  		})
    32  		if innerErr != nil {
    33  			err = innerErr
    34  		}
    35  		return
    36  	}
    37  }