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 }