monitor.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package libbox
  2. import (
  3. "github.com/sagernet/sing-tun"
  4. "github.com/sagernet/sing/common/control"
  5. E "github.com/sagernet/sing/common/exceptions"
  6. "github.com/sagernet/sing/common/logger"
  7. "github.com/sagernet/sing/common/x/list"
  8. )
  9. var (
  10. _ tun.DefaultInterfaceMonitor = (*platformDefaultInterfaceMonitor)(nil)
  11. _ InterfaceUpdateListener = (*platformDefaultInterfaceMonitor)(nil)
  12. )
  13. type platformDefaultInterfaceMonitor struct {
  14. *platformInterfaceWrapper
  15. logger logger.Logger
  16. element *list.Element[tun.NetworkUpdateCallback]
  17. callbacks list.List[tun.DefaultInterfaceUpdateCallback]
  18. myInterface string
  19. }
  20. func (m *platformDefaultInterfaceMonitor) Start() error {
  21. return m.iif.StartDefaultInterfaceMonitor(m)
  22. }
  23. func (m *platformDefaultInterfaceMonitor) Close() error {
  24. return m.iif.CloseDefaultInterfaceMonitor(m)
  25. }
  26. func (m *platformDefaultInterfaceMonitor) DefaultInterface() *control.Interface {
  27. m.defaultInterfaceAccess.Lock()
  28. defer m.defaultInterfaceAccess.Unlock()
  29. return m.defaultInterface
  30. }
  31. func (m *platformDefaultInterfaceMonitor) OverrideAndroidVPN() bool {
  32. return false
  33. }
  34. func (m *platformDefaultInterfaceMonitor) AndroidVPNEnabled() bool {
  35. return false
  36. }
  37. func (m *platformDefaultInterfaceMonitor) RegisterCallback(callback tun.DefaultInterfaceUpdateCallback) *list.Element[tun.DefaultInterfaceUpdateCallback] {
  38. m.defaultInterfaceAccess.Lock()
  39. defer m.defaultInterfaceAccess.Unlock()
  40. return m.callbacks.PushBack(callback)
  41. }
  42. func (m *platformDefaultInterfaceMonitor) UnregisterCallback(element *list.Element[tun.DefaultInterfaceUpdateCallback]) {
  43. m.defaultInterfaceAccess.Lock()
  44. defer m.defaultInterfaceAccess.Unlock()
  45. m.callbacks.Remove(element)
  46. }
  47. func (m *platformDefaultInterfaceMonitor) UpdateDefaultInterface(interfaceName string, interfaceIndex32 int32, isExpensive bool, isConstrained bool) {
  48. if sFixAndroidStack {
  49. done := make(chan struct{})
  50. go func() {
  51. m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
  52. close(done)
  53. }()
  54. <-done
  55. } else {
  56. m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
  57. }
  58. }
  59. func (m *platformDefaultInterfaceMonitor) updateDefaultInterface(interfaceName string, interfaceIndex32 int32, isExpensive bool, isConstrained bool) {
  60. m.isExpensive = isExpensive
  61. m.isConstrained = isConstrained
  62. err := m.networkManager.UpdateInterfaces()
  63. if err != nil {
  64. m.logger.Error(E.Cause(err, "update interfaces"))
  65. }
  66. m.defaultInterfaceAccess.Lock()
  67. if interfaceIndex32 == -1 {
  68. m.defaultInterface = nil
  69. callbacks := m.callbacks.Array()
  70. m.defaultInterfaceAccess.Unlock()
  71. for _, callback := range callbacks {
  72. callback(nil, 0)
  73. }
  74. return
  75. }
  76. oldInterface := m.defaultInterface
  77. newInterface, err := m.networkManager.InterfaceFinder().ByIndex(int(interfaceIndex32))
  78. if err != nil {
  79. m.defaultInterfaceAccess.Unlock()
  80. m.logger.Error(E.Cause(err, "find updated interface: ", interfaceName))
  81. return
  82. }
  83. m.defaultInterface = newInterface
  84. if oldInterface != nil && oldInterface.Name == m.defaultInterface.Name && oldInterface.Index == m.defaultInterface.Index {
  85. m.defaultInterfaceAccess.Unlock()
  86. return
  87. }
  88. callbacks := m.callbacks.Array()
  89. m.defaultInterfaceAccess.Unlock()
  90. for _, callback := range callbacks {
  91. callback(newInterface, 0)
  92. }
  93. }
  94. func (m *platformDefaultInterfaceMonitor) RegisterMyInterface(interfaceName string) {
  95. m.defaultInterfaceAccess.Lock()
  96. defer m.defaultInterfaceAccess.Unlock()
  97. m.myInterface = interfaceName
  98. }
  99. func (m *platformDefaultInterfaceMonitor) MyInterface() string {
  100. m.defaultInterfaceAccess.Lock()
  101. defer m.defaultInterfaceAccess.Unlock()
  102. return m.myInterface
  103. }