github.com/sagernet/sing-box@v1.2.7/experimental/libbox/monitor.go (about)

     1  package libbox
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"net/netip"
     7  	"sync"
     8  
     9  	"github.com/sagernet/sing-tun"
    10  	"github.com/sagernet/sing/common"
    11  	E "github.com/sagernet/sing/common/exceptions"
    12  	M "github.com/sagernet/sing/common/metadata"
    13  	"github.com/sagernet/sing/common/x/list"
    14  )
    15  
    16  var (
    17  	_ tun.DefaultInterfaceMonitor = (*platformDefaultInterfaceMonitor)(nil)
    18  	_ InterfaceUpdateListener     = (*platformDefaultInterfaceMonitor)(nil)
    19  )
    20  
    21  type platformDefaultInterfaceMonitor struct {
    22  	*platformInterfaceWrapper
    23  	errorHandler          E.Handler
    24  	networkAddresses      []networkAddress
    25  	defaultInterfaceName  string
    26  	defaultInterfaceIndex int
    27  	element               *list.Element[tun.NetworkUpdateCallback]
    28  	access                sync.Mutex
    29  	callbacks             list.List[tun.DefaultInterfaceUpdateCallback]
    30  }
    31  
    32  type networkAddress struct {
    33  	interfaceName  string
    34  	interfaceIndex int
    35  	addresses      []netip.Prefix
    36  }
    37  
    38  func (m *platformDefaultInterfaceMonitor) Start() error {
    39  	return m.iif.StartDefaultInterfaceMonitor(m)
    40  }
    41  
    42  func (m *platformDefaultInterfaceMonitor) Close() error {
    43  	return m.iif.CloseDefaultInterfaceMonitor(m)
    44  }
    45  
    46  func (m *platformDefaultInterfaceMonitor) DefaultInterfaceName(destination netip.Addr) string {
    47  	for _, address := range m.networkAddresses {
    48  		for _, prefix := range address.addresses {
    49  			if prefix.Contains(destination) {
    50  				return address.interfaceName
    51  			}
    52  		}
    53  	}
    54  	return m.defaultInterfaceName
    55  }
    56  
    57  func (m *platformDefaultInterfaceMonitor) DefaultInterfaceIndex(destination netip.Addr) int {
    58  	for _, address := range m.networkAddresses {
    59  		for _, prefix := range address.addresses {
    60  			if prefix.Contains(destination) {
    61  				return address.interfaceIndex
    62  			}
    63  		}
    64  	}
    65  	return m.defaultInterfaceIndex
    66  }
    67  
    68  func (m *platformDefaultInterfaceMonitor) OverrideAndroidVPN() bool {
    69  	return false
    70  }
    71  
    72  func (m *platformDefaultInterfaceMonitor) AndroidVPNEnabled() bool {
    73  	return false
    74  }
    75  
    76  func (m *platformDefaultInterfaceMonitor) RegisterCallback(callback tun.DefaultInterfaceUpdateCallback) *list.Element[tun.DefaultInterfaceUpdateCallback] {
    77  	m.access.Lock()
    78  	defer m.access.Unlock()
    79  	return m.callbacks.PushBack(callback)
    80  }
    81  
    82  func (m *platformDefaultInterfaceMonitor) UnregisterCallback(element *list.Element[tun.DefaultInterfaceUpdateCallback]) {
    83  	m.access.Lock()
    84  	defer m.access.Unlock()
    85  	m.callbacks.Remove(element)
    86  }
    87  
    88  func (m *platformDefaultInterfaceMonitor) UpdateDefaultInterface(interfaceName string, interfaceIndex32 int32) {
    89  	var err error
    90  	if m.iif.UsePlatformInterfaceGetter() {
    91  		err = m.updateInterfacesPlatform()
    92  	} else {
    93  		err = m.updateInterfaces()
    94  	}
    95  	if err == nil {
    96  		err = m.router.UpdateInterfaces()
    97  	}
    98  	if err != nil {
    99  		m.errorHandler.NewError(context.Background(), E.Cause(err, "update interfaces"))
   100  	}
   101  	interfaceIndex := int(interfaceIndex32)
   102  	if interfaceName == "" {
   103  		for _, netIf := range m.networkAddresses {
   104  			if netIf.interfaceIndex == interfaceIndex {
   105  				interfaceName = netIf.interfaceName
   106  				break
   107  			}
   108  		}
   109  	} else if interfaceIndex == -1 {
   110  		for _, netIf := range m.networkAddresses {
   111  			if netIf.interfaceName == interfaceName {
   112  				interfaceIndex = netIf.interfaceIndex
   113  				break
   114  			}
   115  		}
   116  	}
   117  	if interfaceName == "" {
   118  		m.errorHandler.NewError(context.Background(), E.New("invalid interface name for ", interfaceIndex))
   119  		return
   120  	} else if interfaceIndex == -1 {
   121  		m.errorHandler.NewError(context.Background(), E.New("invalid interface index for ", interfaceName))
   122  		return
   123  	}
   124  	if m.defaultInterfaceName == interfaceName && m.defaultInterfaceIndex == interfaceIndex {
   125  		return
   126  	}
   127  	m.defaultInterfaceName = interfaceName
   128  	m.defaultInterfaceIndex = interfaceIndex
   129  	m.access.Lock()
   130  	callbacks := m.callbacks.Array()
   131  	m.access.Unlock()
   132  	for _, callback := range callbacks {
   133  		err = callback(tun.EventInterfaceUpdate)
   134  		if err != nil {
   135  			m.errorHandler.NewError(context.Background(), err)
   136  		}
   137  	}
   138  }
   139  
   140  func (m *platformDefaultInterfaceMonitor) updateInterfaces() error {
   141  	interfaces, err := net.Interfaces()
   142  	if err != nil {
   143  		return err
   144  	}
   145  	var addresses []networkAddress
   146  	for _, iif := range interfaces {
   147  		var netAddresses []net.Addr
   148  		netAddresses, err = iif.Addrs()
   149  		if err != nil {
   150  			return err
   151  		}
   152  		var address networkAddress
   153  		address.interfaceName = iif.Name
   154  		address.interfaceIndex = iif.Index
   155  		address.addresses = common.Map(common.FilterIsInstance(netAddresses, func(it net.Addr) (*net.IPNet, bool) {
   156  			value, loaded := it.(*net.IPNet)
   157  			return value, loaded
   158  		}), func(it *net.IPNet) netip.Prefix {
   159  			bits, _ := it.Mask.Size()
   160  			return netip.PrefixFrom(M.AddrFromIP(it.IP), bits)
   161  		})
   162  		addresses = append(addresses, address)
   163  	}
   164  	m.networkAddresses = addresses
   165  	return nil
   166  }
   167  
   168  func (m *platformDefaultInterfaceMonitor) updateInterfacesPlatform() error {
   169  	interfaces, err := m.Interfaces()
   170  	if err != nil {
   171  		return err
   172  	}
   173  	var addresses []networkAddress
   174  	for _, iif := range interfaces {
   175  		var address networkAddress
   176  		address.interfaceName = iif.Name
   177  		address.interfaceIndex = iif.Index
   178  		// address.addresses = common.Map(iif.Addresses, netip.MustParsePrefix)
   179  		addresses = append(addresses, address)
   180  	}
   181  	m.networkAddresses = addresses
   182  	return nil
   183  }