github.com/sagernet/sing-box@v1.9.0-rc.20/experimental/libbox/monitor.go (about) 1 package libbox 2 3 import ( 4 "net" 5 "net/netip" 6 "sync" 7 8 "github.com/sagernet/sing-tun" 9 "github.com/sagernet/sing/common" 10 E "github.com/sagernet/sing/common/exceptions" 11 "github.com/sagernet/sing/common/logger" 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 networkAddresses []networkAddress 24 defaultInterfaceName string 25 defaultInterfaceIndex int 26 element *list.Element[tun.NetworkUpdateCallback] 27 access sync.Mutex 28 callbacks list.List[tun.DefaultInterfaceUpdateCallback] 29 logger logger.Logger 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) DefaultInterface(destination netip.Addr) (string, int) { 69 for _, address := range m.networkAddresses { 70 for _, prefix := range address.addresses { 71 if prefix.Contains(destination) { 72 return address.interfaceName, address.interfaceIndex 73 } 74 } 75 } 76 return m.defaultInterfaceName, m.defaultInterfaceIndex 77 } 78 79 func (m *platformDefaultInterfaceMonitor) OverrideAndroidVPN() bool { 80 return false 81 } 82 83 func (m *platformDefaultInterfaceMonitor) AndroidVPNEnabled() bool { 84 return false 85 } 86 87 func (m *platformDefaultInterfaceMonitor) RegisterCallback(callback tun.DefaultInterfaceUpdateCallback) *list.Element[tun.DefaultInterfaceUpdateCallback] { 88 m.access.Lock() 89 defer m.access.Unlock() 90 return m.callbacks.PushBack(callback) 91 } 92 93 func (m *platformDefaultInterfaceMonitor) UnregisterCallback(element *list.Element[tun.DefaultInterfaceUpdateCallback]) { 94 m.access.Lock() 95 defer m.access.Unlock() 96 m.callbacks.Remove(element) 97 } 98 99 func (m *platformDefaultInterfaceMonitor) UpdateDefaultInterface(interfaceName string, interfaceIndex32 int32) { 100 if interfaceName == "" || interfaceIndex32 == -1 { 101 m.defaultInterfaceName = "" 102 m.defaultInterfaceIndex = -1 103 m.access.Lock() 104 callbacks := m.callbacks.Array() 105 m.access.Unlock() 106 for _, callback := range callbacks { 107 callback(tun.EventNoRoute) 108 } 109 return 110 } 111 var err error 112 if m.iif.UsePlatformInterfaceGetter() { 113 err = m.updateInterfacesPlatform() 114 } else { 115 err = m.updateInterfaces() 116 } 117 if err == nil { 118 err = m.router.UpdateInterfaces() 119 } 120 if err != nil { 121 m.logger.Error(E.Cause(err, "update interfaces")) 122 } 123 interfaceIndex := int(interfaceIndex32) 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 callback(tun.EventInterfaceUpdate) 134 } 135 } 136 137 func (m *platformDefaultInterfaceMonitor) updateInterfaces() error { 138 interfaces, err := net.Interfaces() 139 if err != nil { 140 return err 141 } 142 var addresses []networkAddress 143 for _, iif := range interfaces { 144 var netAddresses []net.Addr 145 netAddresses, err = iif.Addrs() 146 if err != nil { 147 return err 148 } 149 var address networkAddress 150 address.interfaceName = iif.Name 151 address.interfaceIndex = iif.Index 152 address.addresses = common.Map(common.FilterIsInstance(netAddresses, func(it net.Addr) (*net.IPNet, bool) { 153 value, loaded := it.(*net.IPNet) 154 return value, loaded 155 }), func(it *net.IPNet) netip.Prefix { 156 bits, _ := it.Mask.Size() 157 return netip.PrefixFrom(M.AddrFromIP(it.IP), bits) 158 }) 159 addresses = append(addresses, address) 160 } 161 m.networkAddresses = addresses 162 return nil 163 } 164 165 func (m *platformDefaultInterfaceMonitor) updateInterfacesPlatform() error { 166 interfaces, err := m.Interfaces() 167 if err != nil { 168 return err 169 } 170 var addresses []networkAddress 171 for _, iif := range interfaces { 172 var address networkAddress 173 address.interfaceName = iif.Name 174 address.interfaceIndex = iif.Index 175 // address.addresses = common.Map(iif.Addresses, netip.MustParsePrefix) 176 addresses = append(addresses, address) 177 } 178 m.networkAddresses = addresses 179 return nil 180 }