github.com/yaling888/clash@v1.53.0/component/dialer/bind_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  type controlFn = func(network, address string, c syscall.RawConn) error
    12  
    13  func bindControl(ifaceName string, chain controlFn) controlFn {
    14  	return func(network, address string, c syscall.RawConn) (err error) {
    15  		defer func() {
    16  			if err == nil && chain != nil {
    17  				err = chain(network, address, c)
    18  			}
    19  		}()
    20  
    21  		addrPort, err := netip.ParseAddrPort(address)
    22  		if err == nil && !addrPort.Addr().IsGlobalUnicast() {
    23  			return
    24  		}
    25  
    26  		var innerErr error
    27  		err = c.Control(func(fd uintptr) {
    28  			innerErr = unix.BindToDevice(int(fd), ifaceName)
    29  		})
    30  
    31  		if innerErr != nil {
    32  			err = innerErr
    33  		}
    34  
    35  		return
    36  	}
    37  }
    38  
    39  func bindIfaceToDialer(ifaceName string, dialer *net.Dialer, _ string, _ netip.Addr) error {
    40  	dialer.Control = bindControl(ifaceName, dialer.Control)
    41  
    42  	return nil
    43  }
    44  
    45  func bindIfaceToListenConfig(ifaceName string, lc *net.ListenConfig, _, address string) (string, error) {
    46  	lc.Control = bindControl(ifaceName, lc.Control)
    47  
    48  	return address, nil
    49  }
    50  
    51  func WithBindToInterfaceControlFn(interfaceName string) func(network, address string, c syscall.RawConn) (err error) {
    52  	return func(network, address string, c syscall.RawConn) (err error) {
    53  		if interfaceName == "" {
    54  			return nil
    55  		}
    56  
    57  		var innerErr error
    58  		err = c.Control(func(fd uintptr) {
    59  			innerErr = unix.BindToDevice(int(fd), interfaceName)
    60  		})
    61  
    62  		if innerErr != nil {
    63  			err = innerErr
    64  		}
    65  
    66  		return
    67  	}
    68  }