github.com/metacubex/sing-tun@v0.2.7-0.20240512075008-89e7c6208eec/monitor_shared.go (about) 1 //go:build linux || windows || darwin 2 3 package tun 4 5 import ( 6 "errors" 7 "net" 8 "net/netip" 9 "sync" 10 "time" 11 12 "github.com/sagernet/sing/common" 13 "github.com/sagernet/sing/common/logger" 14 M "github.com/sagernet/sing/common/metadata" 15 "github.com/sagernet/sing/common/x/list" 16 ) 17 18 func (m *networkUpdateMonitor) RegisterCallback(callback NetworkUpdateCallback) *list.Element[NetworkUpdateCallback] { 19 m.access.Lock() 20 defer m.access.Unlock() 21 return m.callbacks.PushBack(callback) 22 } 23 24 func (m *networkUpdateMonitor) UnregisterCallback(element *list.Element[NetworkUpdateCallback]) { 25 m.access.Lock() 26 defer m.access.Unlock() 27 m.callbacks.Remove(element) 28 } 29 30 func (m *networkUpdateMonitor) emit() { 31 m.access.Lock() 32 callbacks := m.callbacks.Array() 33 m.access.Unlock() 34 for _, callback := range callbacks { 35 callback() 36 } 37 } 38 39 type defaultInterfaceMonitor struct { 40 options DefaultInterfaceMonitorOptions 41 networkAddresses []networkAddress 42 defaultInterfaceName string 43 defaultInterfaceIndex int 44 androidVPNEnabled bool 45 networkMonitor NetworkUpdateMonitor 46 checkUpdateTimer *time.Timer 47 element *list.Element[NetworkUpdateCallback] 48 access sync.Mutex 49 callbacks list.List[DefaultInterfaceUpdateCallback] 50 logger logger.Logger 51 } 52 53 type networkAddress struct { 54 interfaceName string 55 interfaceIndex int 56 addresses []netip.Prefix 57 } 58 59 func NewDefaultInterfaceMonitor(networkMonitor NetworkUpdateMonitor, logger logger.Logger, options DefaultInterfaceMonitorOptions) (DefaultInterfaceMonitor, error) { 60 return &defaultInterfaceMonitor{ 61 options: options, 62 networkMonitor: networkMonitor, 63 defaultInterfaceIndex: -1, 64 logger: logger, 65 }, nil 66 } 67 68 func (m *defaultInterfaceMonitor) Start() error { 69 _ = m.checkUpdate() 70 m.element = m.networkMonitor.RegisterCallback(m.delayCheckUpdate) 71 return nil 72 } 73 74 func (m *defaultInterfaceMonitor) delayCheckUpdate() { 75 if m.checkUpdateTimer == nil { 76 m.checkUpdateTimer = time.AfterFunc(time.Second, m.postCheckUpdate) 77 } else { 78 m.checkUpdateTimer.Reset(time.Second) 79 } 80 } 81 82 func (m *defaultInterfaceMonitor) postCheckUpdate() { 83 err := m.updateInterfaces() 84 if err != nil { 85 m.logger.Error("update interfaces: ", err) 86 } 87 err = m.checkUpdate() 88 if errors.Is(err, ErrNoRoute) { 89 m.defaultInterfaceName = "" 90 m.defaultInterfaceIndex = -1 91 m.emit(EventNoRoute) 92 } else if err != nil { 93 m.logger.Error("check interface: ", err) 94 } 95 } 96 97 func (m *defaultInterfaceMonitor) updateInterfaces() error { 98 interfaces, err := net.Interfaces() 99 if err != nil { 100 return err 101 } 102 var addresses []networkAddress 103 for _, iif := range interfaces { 104 var netAddresses []net.Addr 105 netAddresses, err = iif.Addrs() 106 if err != nil { 107 return err 108 } 109 var address networkAddress 110 address.interfaceName = iif.Name 111 address.interfaceIndex = iif.Index 112 address.addresses = common.Map(common.FilterIsInstance(netAddresses, func(it net.Addr) (*net.IPNet, bool) { 113 value, loaded := it.(*net.IPNet) 114 return value, loaded 115 }), func(it *net.IPNet) netip.Prefix { 116 bits, _ := it.Mask.Size() 117 return netip.PrefixFrom(M.AddrFromIP(it.IP), bits) 118 }) 119 addresses = append(addresses, address) 120 } 121 m.networkAddresses = addresses 122 return nil 123 } 124 125 func (m *defaultInterfaceMonitor) Close() error { 126 if m.element != nil { 127 m.networkMonitor.UnregisterCallback(m.element) 128 } 129 return nil 130 } 131 132 func (m *defaultInterfaceMonitor) DefaultInterfaceName(destination netip.Addr) string { 133 for _, address := range m.networkAddresses { 134 for _, prefix := range address.addresses { 135 if prefix.Contains(destination) { 136 return address.interfaceName 137 } 138 } 139 } 140 return m.defaultInterfaceName 141 } 142 143 func (m *defaultInterfaceMonitor) DefaultInterfaceIndex(destination netip.Addr) int { 144 for _, address := range m.networkAddresses { 145 for _, prefix := range address.addresses { 146 if prefix.Contains(destination) { 147 return address.interfaceIndex 148 } 149 } 150 } 151 return m.defaultInterfaceIndex 152 } 153 154 func (m *defaultInterfaceMonitor) DefaultInterface(destination netip.Addr) (string, int) { 155 for _, address := range m.networkAddresses { 156 for _, prefix := range address.addresses { 157 if prefix.Contains(destination) { 158 return address.interfaceName, address.interfaceIndex 159 } 160 } 161 } 162 return m.defaultInterfaceName, m.defaultInterfaceIndex 163 } 164 165 func (m *defaultInterfaceMonitor) OverrideAndroidVPN() bool { 166 return m.options.OverrideAndroidVPN 167 } 168 169 func (m *defaultInterfaceMonitor) AndroidVPNEnabled() bool { 170 return m.androidVPNEnabled 171 } 172 173 func (m *defaultInterfaceMonitor) RegisterCallback(callback DefaultInterfaceUpdateCallback) *list.Element[DefaultInterfaceUpdateCallback] { 174 m.access.Lock() 175 defer m.access.Unlock() 176 return m.callbacks.PushBack(callback) 177 } 178 179 func (m *defaultInterfaceMonitor) UnregisterCallback(element *list.Element[DefaultInterfaceUpdateCallback]) { 180 m.access.Lock() 181 defer m.access.Unlock() 182 m.callbacks.Remove(element) 183 } 184 185 func (m *defaultInterfaceMonitor) emit(event int) { 186 m.access.Lock() 187 callbacks := m.callbacks.Array() 188 m.access.Unlock() 189 for _, callback := range callbacks { 190 callback(event) 191 } 192 }