network.go 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. package route
  2. import (
  3. "context"
  4. "errors"
  5. "net/netip"
  6. "os"
  7. "runtime"
  8. "syscall"
  9. "github.com/sagernet/sing-box/adapter"
  10. "github.com/sagernet/sing-box/common/conntrack"
  11. "github.com/sagernet/sing-box/common/taskmonitor"
  12. C "github.com/sagernet/sing-box/constant"
  13. "github.com/sagernet/sing-box/experimental/libbox/platform"
  14. "github.com/sagernet/sing-box/option"
  15. "github.com/sagernet/sing-tun"
  16. "github.com/sagernet/sing/common/control"
  17. E "github.com/sagernet/sing/common/exceptions"
  18. "github.com/sagernet/sing/common/logger"
  19. M "github.com/sagernet/sing/common/metadata"
  20. "github.com/sagernet/sing/common/winpowrprof"
  21. "github.com/sagernet/sing/service"
  22. "github.com/sagernet/sing/service/pause"
  23. )
  24. var _ adapter.NetworkManager = (*NetworkManager)(nil)
  25. type NetworkManager struct {
  26. logger logger.ContextLogger
  27. interfaceFinder *control.DefaultInterfaceFinder
  28. autoDetectInterface bool
  29. defaultInterface string
  30. defaultMark uint32
  31. autoRedirectOutputMark uint32
  32. networkMonitor tun.NetworkUpdateMonitor
  33. interfaceMonitor tun.DefaultInterfaceMonitor
  34. packageManager tun.PackageManager
  35. powerListener winpowrprof.EventListener
  36. pauseManager pause.Manager
  37. platformInterface platform.Interface
  38. outboundManager adapter.OutboundManager
  39. wifiState adapter.WIFIState
  40. started bool
  41. }
  42. func NewNetworkManager(ctx context.Context, logger logger.ContextLogger, routeOptions option.RouteOptions) (*NetworkManager, error) {
  43. nm := &NetworkManager{
  44. logger: logger,
  45. interfaceFinder: control.NewDefaultInterfaceFinder(),
  46. autoDetectInterface: routeOptions.AutoDetectInterface,
  47. defaultInterface: routeOptions.DefaultInterface,
  48. defaultMark: routeOptions.DefaultMark,
  49. pauseManager: service.FromContext[pause.Manager](ctx),
  50. platformInterface: service.FromContext[platform.Interface](ctx),
  51. outboundManager: service.FromContext[adapter.OutboundManager](ctx),
  52. }
  53. usePlatformDefaultInterfaceMonitor := nm.platformInterface != nil && nm.platformInterface.UsePlatformDefaultInterfaceMonitor()
  54. enforceInterfaceMonitor := routeOptions.AutoDetectInterface
  55. if !usePlatformDefaultInterfaceMonitor {
  56. networkMonitor, err := tun.NewNetworkUpdateMonitor(logger)
  57. if !((err != nil && !enforceInterfaceMonitor) || errors.Is(err, os.ErrInvalid)) {
  58. if err != nil {
  59. return nil, E.Cause(err, "create network monitor")
  60. }
  61. nm.networkMonitor = networkMonitor
  62. interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(nm.networkMonitor, logger, tun.DefaultInterfaceMonitorOptions{
  63. InterfaceFinder: nm.interfaceFinder,
  64. OverrideAndroidVPN: routeOptions.OverrideAndroidVPN,
  65. UnderNetworkExtension: nm.platformInterface != nil && nm.platformInterface.UnderNetworkExtension(),
  66. })
  67. if err != nil {
  68. return nil, E.New("auto_detect_interface unsupported on current platform")
  69. }
  70. interfaceMonitor.RegisterCallback(nm.notifyNetworkUpdate)
  71. nm.interfaceMonitor = interfaceMonitor
  72. }
  73. } else {
  74. interfaceMonitor := nm.platformInterface.CreateDefaultInterfaceMonitor(logger)
  75. interfaceMonitor.RegisterCallback(nm.notifyNetworkUpdate)
  76. nm.interfaceMonitor = interfaceMonitor
  77. }
  78. return nm, nil
  79. }
  80. func (r *NetworkManager) Start(stage adapter.StartStage) error {
  81. monitor := taskmonitor.New(r.logger, C.StartTimeout)
  82. switch stage {
  83. case adapter.StartStateInitialize:
  84. if r.interfaceMonitor != nil {
  85. monitor.Start("initialize interface monitor")
  86. err := r.interfaceMonitor.Start()
  87. monitor.Finish()
  88. if err != nil {
  89. return err
  90. }
  91. }
  92. if r.networkMonitor != nil {
  93. monitor.Start("initialize network monitor")
  94. err := r.networkMonitor.Start()
  95. monitor.Finish()
  96. if err != nil {
  97. return err
  98. }
  99. }
  100. case adapter.StartStateStart:
  101. if runtime.GOOS == "windows" {
  102. powerListener, err := winpowrprof.NewEventListener(r.notifyWindowsPowerEvent)
  103. if err == nil {
  104. r.powerListener = powerListener
  105. } else {
  106. r.logger.Warn("initialize power listener: ", err)
  107. }
  108. }
  109. if r.powerListener != nil {
  110. monitor.Start("start power listener")
  111. err := r.powerListener.Start()
  112. monitor.Finish()
  113. if err != nil {
  114. return E.Cause(err, "start power listener")
  115. }
  116. }
  117. if C.IsAndroid && r.platformInterface == nil {
  118. monitor.Start("initialize package manager")
  119. packageManager, err := tun.NewPackageManager(tun.PackageManagerOptions{
  120. Callback: r,
  121. Logger: r.logger,
  122. })
  123. monitor.Finish()
  124. if err != nil {
  125. return E.Cause(err, "create package manager")
  126. }
  127. monitor.Start("start package manager")
  128. err = packageManager.Start()
  129. monitor.Finish()
  130. if err != nil {
  131. r.logger.Warn("initialize package manager: ", err)
  132. } else {
  133. r.packageManager = packageManager
  134. }
  135. }
  136. case adapter.StartStatePostStart:
  137. r.started = true
  138. }
  139. return nil
  140. }
  141. func (r *NetworkManager) Close() error {
  142. monitor := taskmonitor.New(r.logger, C.StopTimeout)
  143. var err error
  144. if r.interfaceMonitor != nil {
  145. monitor.Start("close interface monitor")
  146. err = E.Append(err, r.interfaceMonitor.Close(), func(err error) error {
  147. return E.Cause(err, "close interface monitor")
  148. })
  149. monitor.Finish()
  150. }
  151. if r.networkMonitor != nil {
  152. monitor.Start("close network monitor")
  153. err = E.Append(err, r.networkMonitor.Close(), func(err error) error {
  154. return E.Cause(err, "close network monitor")
  155. })
  156. monitor.Finish()
  157. }
  158. if r.packageManager != nil {
  159. monitor.Start("close package manager")
  160. err = E.Append(err, r.packageManager.Close(), func(err error) error {
  161. return E.Cause(err, "close package manager")
  162. })
  163. monitor.Finish()
  164. }
  165. if r.powerListener != nil {
  166. monitor.Start("close power listener")
  167. err = E.Append(err, r.powerListener.Close(), func(err error) error {
  168. return E.Cause(err, "close power listener")
  169. })
  170. monitor.Finish()
  171. }
  172. return nil
  173. }
  174. func (r *NetworkManager) InterfaceFinder() control.InterfaceFinder {
  175. return r.interfaceFinder
  176. }
  177. func (r *NetworkManager) UpdateInterfaces() error {
  178. if r.platformInterface == nil || !r.platformInterface.UsePlatformInterfaceGetter() {
  179. return r.interfaceFinder.Update()
  180. } else {
  181. interfaces, err := r.platformInterface.Interfaces()
  182. if err != nil {
  183. return err
  184. }
  185. r.interfaceFinder.UpdateInterfaces(interfaces)
  186. return nil
  187. }
  188. }
  189. func (r *NetworkManager) DefaultInterface() string {
  190. return r.defaultInterface
  191. }
  192. func (r *NetworkManager) AutoDetectInterface() bool {
  193. return r.autoDetectInterface
  194. }
  195. func (r *NetworkManager) AutoDetectInterfaceFunc() control.Func {
  196. if r.platformInterface != nil && r.platformInterface.UsePlatformAutoDetectInterfaceControl() {
  197. return func(network, address string, conn syscall.RawConn) error {
  198. return control.Raw(conn, func(fd uintptr) error {
  199. return r.platformInterface.AutoDetectInterfaceControl(int(fd))
  200. })
  201. }
  202. } else {
  203. if r.interfaceMonitor == nil {
  204. return nil
  205. }
  206. return control.BindToInterfaceFunc(r.interfaceFinder, func(network string, address string) (interfaceName string, interfaceIndex int, err error) {
  207. remoteAddr := M.ParseSocksaddr(address).Addr
  208. if C.IsLinux {
  209. interfaceName, interfaceIndex = r.interfaceMonitor.DefaultInterface(remoteAddr)
  210. if interfaceIndex == -1 {
  211. err = tun.ErrNoRoute
  212. }
  213. } else {
  214. interfaceIndex = r.interfaceMonitor.DefaultInterfaceIndex(remoteAddr)
  215. if interfaceIndex == -1 {
  216. err = tun.ErrNoRoute
  217. }
  218. }
  219. return
  220. })
  221. }
  222. }
  223. func (r *NetworkManager) DefaultMark() uint32 {
  224. return r.defaultMark
  225. }
  226. func (r *NetworkManager) RegisterAutoRedirectOutputMark(mark uint32) error {
  227. if r.autoRedirectOutputMark > 0 {
  228. return E.New("only one auto-redirect can be configured")
  229. }
  230. r.autoRedirectOutputMark = mark
  231. return nil
  232. }
  233. func (r *NetworkManager) AutoRedirectOutputMark() uint32 {
  234. return r.autoRedirectOutputMark
  235. }
  236. func (r *NetworkManager) NetworkMonitor() tun.NetworkUpdateMonitor {
  237. return r.networkMonitor
  238. }
  239. func (r *NetworkManager) InterfaceMonitor() tun.DefaultInterfaceMonitor {
  240. return r.interfaceMonitor
  241. }
  242. func (r *NetworkManager) PackageManager() tun.PackageManager {
  243. return r.packageManager
  244. }
  245. func (r *NetworkManager) WIFIState() adapter.WIFIState {
  246. return r.wifiState
  247. }
  248. func (r *NetworkManager) ResetNetwork() {
  249. conntrack.Close()
  250. for _, outbound := range r.outboundManager.Outbounds() {
  251. listener, isListener := outbound.(adapter.InterfaceUpdateListener)
  252. if isListener {
  253. listener.InterfaceUpdated()
  254. }
  255. }
  256. }
  257. func (r *NetworkManager) notifyNetworkUpdate(event int) {
  258. if event == tun.EventNoRoute {
  259. r.pauseManager.NetworkPause()
  260. r.logger.Error("missing default interface")
  261. } else {
  262. r.pauseManager.NetworkWake()
  263. if C.IsAndroid && r.platformInterface == nil {
  264. var vpnStatus string
  265. if r.interfaceMonitor.AndroidVPNEnabled() {
  266. vpnStatus = "enabled"
  267. } else {
  268. vpnStatus = "disabled"
  269. }
  270. r.logger.Info("updated default interface ", r.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", r.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()), ", vpn ", vpnStatus)
  271. } else {
  272. r.logger.Info("updated default interface ", r.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", r.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()))
  273. }
  274. if r.platformInterface != nil {
  275. state := r.platformInterface.ReadWIFIState()
  276. if state != r.wifiState {
  277. r.wifiState = state
  278. if state.SSID == "" && state.BSSID == "" {
  279. r.logger.Info("updated WIFI state: disconnected")
  280. } else {
  281. r.logger.Info("updated WIFI state: SSID=", state.SSID, ", BSSID=", state.BSSID)
  282. }
  283. }
  284. }
  285. }
  286. if !r.started {
  287. return
  288. }
  289. r.ResetNetwork()
  290. }
  291. func (r *NetworkManager) notifyWindowsPowerEvent(event int) {
  292. switch event {
  293. case winpowrprof.EVENT_SUSPEND:
  294. r.pauseManager.DevicePause()
  295. r.ResetNetwork()
  296. case winpowrprof.EVENT_RESUME:
  297. if !r.pauseManager.IsDevicePaused() {
  298. return
  299. }
  300. fallthrough
  301. case winpowrprof.EVENT_RESUME_AUTOMATIC:
  302. r.pauseManager.DeviceWake()
  303. r.ResetNetwork()
  304. }
  305. }
  306. func (r *NetworkManager) OnPackagesUpdated(packages int, sharedUsers int) {
  307. r.logger.Info("updated packages list: ", packages, " packages, ", sharedUsers, " shared users")
  308. }