github.com/metacubex/sing-tun@v0.2.7-0.20240512075008-89e7c6208eec/monitor_android.go (about)

     1  package tun
     2  
     3  import (
     4  	"github.com/sagernet/netlink"
     5  	E "github.com/sagernet/sing/common/exceptions"
     6  )
     7  
     8  func (m *defaultInterfaceMonitor) checkUpdate() error {
     9  	ruleList, err := netlink.RuleList(netlink.FAMILY_ALL)
    10  	if err != nil {
    11  		return err
    12  	}
    13  
    14  	oldVPNEnabled := m.androidVPNEnabled
    15  	var defaultTableIndex int
    16  	var vpnEnabled bool
    17  	for _, rule := range ruleList {
    18  		if rule.Mask == 0x20000 {
    19  			if rule.UIDRange == nil {
    20  				continue
    21  			}
    22  			vpnEnabled = true
    23  			if m.options.OverrideAndroidVPN {
    24  				defaultTableIndex = rule.Table
    25  				break
    26  			}
    27  		}
    28  		if rule.Mask == 0xFFFF {
    29  			defaultTableIndex = rule.Table
    30  			break
    31  		}
    32  	}
    33  	m.androidVPNEnabled = vpnEnabled
    34  
    35  	if defaultTableIndex == 0 {
    36  		return ErrNoRoute
    37  	}
    38  
    39  	routes, err := netlink.RouteListFiltered(netlink.FAMILY_ALL, &netlink.Route{Table: defaultTableIndex}, netlink.RT_FILTER_TABLE)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	if len(routes) == 0 {
    45  		return E.Extend(ErrNoRoute, "no route in default table ", defaultTableIndex)
    46  	}
    47  
    48  	var link netlink.Link
    49  	link, err = netlink.LinkByIndex(routes[0].LinkIndex)
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	oldInterface := m.defaultInterfaceName
    55  	oldIndex := m.defaultInterfaceIndex
    56  
    57  	m.defaultInterfaceName = link.Attrs().Name
    58  	m.defaultInterfaceIndex = link.Attrs().Index
    59  
    60  	var event int
    61  	if oldInterface != m.defaultInterfaceName || oldIndex != m.defaultInterfaceIndex {
    62  		event |= EventInterfaceUpdate
    63  	}
    64  	if oldVPNEnabled != m.androidVPNEnabled {
    65  		event |= EventAndroidVPNUpdate
    66  	}
    67  	if event != 0 {
    68  		m.emit(event)
    69  	}
    70  
    71  	return nil
    72  }