peerapi_macios_ext.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // This file's built on iOS and on two of three macOS build variants:
  4. // the two GUI variants that both use Extensions (Network Extension
  5. // and System Extension). It's not used on tailscaled-on-macOS.
  6. //go:build ts_macext && (darwin || ios)
  7. package tsdial
  8. import (
  9. "errors"
  10. "net"
  11. "syscall"
  12. "tailscale.com/net/netns"
  13. )
  14. func init() {
  15. peerDialControlFunc = peerDialControlFuncNetworkExtension
  16. }
  17. func peerDialControlFuncNetworkExtension(d *Dialer) func(network, address string, c syscall.RawConn) error {
  18. d.mu.Lock()
  19. defer d.mu.Unlock()
  20. index := -1
  21. if x, ok := interfaceIndexLocked(d); ok {
  22. index = x
  23. }
  24. var lc net.ListenConfig
  25. netns.SetListenConfigInterfaceIndex(&lc, index)
  26. return func(network, address string, c syscall.RawConn) error {
  27. if index == -1 {
  28. return errors.New("failed to find TUN interface to bind to")
  29. }
  30. return lc.Control(network, address, c)
  31. }
  32. }
  33. func interfaceIndexLocked(d *Dialer) (index int, ok bool) {
  34. if d.netMon == nil {
  35. return 0, false
  36. }
  37. st := d.netMon.InterfaceState()
  38. iface, ok := st.Interface[d.tunName]
  39. if !ok {
  40. return 0, false
  41. }
  42. return iface.Index, true
  43. }