github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/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) 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.logger.Error(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.logger.Error(E.New("invalid interface name for ", interfaceIndex)) 119 return 120 } else if interfaceIndex == -1 { 121 m.logger.Error(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 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 }