github.com/apernet/sing-tun@v0.2.6-0.20240323130332-b9f6511036ad/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.Stop() 77 } 78 m.checkUpdateTimer = time.AfterFunc(time.Second, m.postCheckUpdate) 79 } 80 81 func (m *defaultInterfaceMonitor) postCheckUpdate() { 82 err := m.updateInterfaces() 83 if err != nil { 84 m.logger.Error("update interfaces: ", err) 85 } 86 err = m.checkUpdate() 87 if errors.Is(err, ErrNoRoute) { 88 m.defaultInterfaceName = "" 89 m.defaultInterfaceIndex = -1 90 m.emit(EventNoRoute) 91 } else if err != nil { 92 m.logger.Error("check interface: ", err) 93 } 94 } 95 96 func (m *defaultInterfaceMonitor) updateInterfaces() error { 97 interfaces, err := net.Interfaces() 98 if err != nil { 99 return err 100 } 101 var addresses []networkAddress 102 for _, iif := range interfaces { 103 var netAddresses []net.Addr 104 netAddresses, err = iif.Addrs() 105 if err != nil { 106 return err 107 } 108 var address networkAddress 109 address.interfaceName = iif.Name 110 address.interfaceIndex = iif.Index 111 address.addresses = common.Map(common.FilterIsInstance(netAddresses, func(it net.Addr) (*net.IPNet, bool) { 112 value, loaded := it.(*net.IPNet) 113 return value, loaded 114 }), func(it *net.IPNet) netip.Prefix { 115 bits, _ := it.Mask.Size() 116 return netip.PrefixFrom(M.AddrFromIP(it.IP), bits) 117 }) 118 addresses = append(addresses, address) 119 } 120 m.networkAddresses = addresses 121 return nil 122 } 123 124 func (m *defaultInterfaceMonitor) Close() error { 125 if m.element != nil { 126 m.networkMonitor.UnregisterCallback(m.element) 127 } 128 return nil 129 } 130 131 func (m *defaultInterfaceMonitor) DefaultInterfaceName(destination netip.Addr) string { 132 for _, address := range m.networkAddresses { 133 for _, prefix := range address.addresses { 134 if prefix.Contains(destination) { 135 return address.interfaceName 136 } 137 } 138 } 139 return m.defaultInterfaceName 140 } 141 142 func (m *defaultInterfaceMonitor) DefaultInterfaceIndex(destination netip.Addr) int { 143 for _, address := range m.networkAddresses { 144 for _, prefix := range address.addresses { 145 if prefix.Contains(destination) { 146 return address.interfaceIndex 147 } 148 } 149 } 150 return m.defaultInterfaceIndex 151 } 152 153 func (m *defaultInterfaceMonitor) DefaultInterface(destination netip.Addr) (string, int) { 154 for _, address := range m.networkAddresses { 155 for _, prefix := range address.addresses { 156 if prefix.Contains(destination) { 157 return address.interfaceName, address.interfaceIndex 158 } 159 } 160 } 161 return m.defaultInterfaceName, m.defaultInterfaceIndex 162 } 163 164 func (m *defaultInterfaceMonitor) OverrideAndroidVPN() bool { 165 return m.options.OverrideAndroidVPN 166 } 167 168 func (m *defaultInterfaceMonitor) AndroidVPNEnabled() bool { 169 return m.androidVPNEnabled 170 } 171 172 func (m *defaultInterfaceMonitor) RegisterCallback(callback DefaultInterfaceUpdateCallback) *list.Element[DefaultInterfaceUpdateCallback] { 173 m.access.Lock() 174 defer m.access.Unlock() 175 return m.callbacks.PushBack(callback) 176 } 177 178 func (m *defaultInterfaceMonitor) UnregisterCallback(element *list.Element[DefaultInterfaceUpdateCallback]) { 179 m.access.Lock() 180 defer m.access.Unlock() 181 m.callbacks.Remove(element) 182 } 183 184 func (m *defaultInterfaceMonitor) emit(event int) { 185 m.access.Lock() 186 callbacks := m.callbacks.Array() 187 m.access.Unlock() 188 for _, callback := range callbacks { 189 callback(event) 190 } 191 }