bind_linux.go 981 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. package dialer
  2. import (
  3. "context"
  4. "net"
  5. "net/netip"
  6. "syscall"
  7. "golang.org/x/sys/unix"
  8. )
  9. func bindControl(ifaceName string) controlFn {
  10. return func(ctx context.Context, network, address string, c syscall.RawConn) (err error) {
  11. addrPort, err := netip.ParseAddrPort(address)
  12. if err == nil && !addrPort.Addr().IsGlobalUnicast() {
  13. return
  14. }
  15. var innerErr error
  16. err = c.Control(func(fd uintptr) {
  17. innerErr = unix.BindToDevice(int(fd), ifaceName)
  18. })
  19. if innerErr != nil {
  20. err = innerErr
  21. }
  22. return
  23. }
  24. }
  25. func bindIfaceToDialer(ifaceName string, dialer *net.Dialer, _ string, _ netip.Addr) error {
  26. addControlToDialer(dialer, bindControl(ifaceName))
  27. return nil
  28. }
  29. func bindIfaceToListenConfig(ifaceName string, lc *net.ListenConfig, _, address string, rAddrPort netip.AddrPort) (string, error) {
  30. addControlToListenConfig(lc, bindControl(ifaceName))
  31. return address, nil
  32. }
  33. func ParseNetwork(network string, addr netip.Addr) string {
  34. return network
  35. }