network.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. package route
  2. import (
  3. "context"
  4. "errors"
  5. "net"
  6. "os"
  7. "runtime"
  8. "strings"
  9. "syscall"
  10. "time"
  11. "github.com/sagernet/sing-box/adapter"
  12. "github.com/sagernet/sing-box/common/conntrack"
  13. "github.com/sagernet/sing-box/common/taskmonitor"
  14. C "github.com/sagernet/sing-box/constant"
  15. "github.com/sagernet/sing-box/experimental/libbox/platform"
  16. "github.com/sagernet/sing-box/option"
  17. "github.com/sagernet/sing-tun"
  18. "github.com/sagernet/sing/common"
  19. "github.com/sagernet/sing/common/atomic"
  20. "github.com/sagernet/sing/common/control"
  21. E "github.com/sagernet/sing/common/exceptions"
  22. F "github.com/sagernet/sing/common/format"
  23. "github.com/sagernet/sing/common/logger"
  24. M "github.com/sagernet/sing/common/metadata"
  25. "github.com/sagernet/sing/common/winpowrprof"
  26. "github.com/sagernet/sing/service"
  27. "github.com/sagernet/sing/service/pause"
  28. "golang.org/x/exp/slices"
  29. )
  30. var _ adapter.NetworkManager = (*NetworkManager)(nil)
  31. type NetworkManager struct {
  32. logger logger.ContextLogger
  33. tracker conntrack.Tracker
  34. interfaceFinder *control.DefaultInterfaceFinder
  35. networkInterfaces atomic.TypedValue[[]adapter.NetworkInterface]
  36. autoDetectInterface bool
  37. defaultOptions adapter.NetworkOptions
  38. autoRedirectOutputMark uint32
  39. networkMonitor tun.NetworkUpdateMonitor
  40. interfaceMonitor tun.DefaultInterfaceMonitor
  41. packageManager tun.PackageManager
  42. powerListener winpowrprof.EventListener
  43. pauseManager pause.Manager
  44. platformInterface platform.Interface
  45. endpoint adapter.EndpointManager
  46. inbound adapter.InboundManager
  47. outbound adapter.OutboundManager
  48. wifiState adapter.WIFIState
  49. started bool
  50. }
  51. func NewNetworkManager(ctx context.Context, logger logger.ContextLogger, routeOptions option.RouteOptions) (*NetworkManager, error) {
  52. nm := &NetworkManager{
  53. logger: logger,
  54. tracker: service.FromContext[conntrack.Tracker](ctx),
  55. interfaceFinder: control.NewDefaultInterfaceFinder(),
  56. autoDetectInterface: routeOptions.AutoDetectInterface,
  57. defaultOptions: adapter.NetworkOptions{
  58. BindInterface: routeOptions.DefaultInterface,
  59. RoutingMark: uint32(routeOptions.DefaultMark),
  60. NetworkStrategy: (*C.NetworkStrategy)(routeOptions.DefaultNetworkStrategy),
  61. NetworkType: common.Map(routeOptions.DefaultNetworkType, option.InterfaceType.Build),
  62. FallbackNetworkType: common.Map(routeOptions.DefaultFallbackNetworkType, option.InterfaceType.Build),
  63. FallbackDelay: time.Duration(routeOptions.DefaultFallbackDelay),
  64. },
  65. pauseManager: service.FromContext[pause.Manager](ctx),
  66. platformInterface: service.FromContext[platform.Interface](ctx),
  67. endpoint: service.FromContext[adapter.EndpointManager](ctx),
  68. inbound: service.FromContext[adapter.InboundManager](ctx),
  69. outbound: service.FromContext[adapter.OutboundManager](ctx),
  70. }
  71. if routeOptions.DefaultNetworkStrategy != nil {
  72. if routeOptions.DefaultInterface != "" {
  73. return nil, E.New("`default_network_strategy` is conflict with `default_interface`")
  74. }
  75. if !routeOptions.AutoDetectInterface {
  76. return nil, E.New("`auto_detect_interface` is required by `default_network_strategy`")
  77. }
  78. }
  79. usePlatformDefaultInterfaceMonitor := nm.platformInterface != nil
  80. enforceInterfaceMonitor := routeOptions.AutoDetectInterface
  81. if !usePlatformDefaultInterfaceMonitor {
  82. networkMonitor, err := tun.NewNetworkUpdateMonitor(logger)
  83. if !((err != nil && !enforceInterfaceMonitor) || errors.Is(err, os.ErrInvalid)) {
  84. if err != nil {
  85. return nil, E.Cause(err, "create network monitor")
  86. }
  87. nm.networkMonitor = networkMonitor
  88. interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(nm.networkMonitor, logger, tun.DefaultInterfaceMonitorOptions{
  89. InterfaceFinder: nm.interfaceFinder,
  90. OverrideAndroidVPN: routeOptions.OverrideAndroidVPN,
  91. UnderNetworkExtension: nm.platformInterface != nil && nm.platformInterface.UnderNetworkExtension(),
  92. })
  93. if err != nil {
  94. return nil, E.New("auto_detect_interface unsupported on current platform")
  95. }
  96. interfaceMonitor.RegisterCallback(nm.notifyInterfaceUpdate)
  97. nm.interfaceMonitor = interfaceMonitor
  98. }
  99. } else {
  100. interfaceMonitor := nm.platformInterface.CreateDefaultInterfaceMonitor(logger)
  101. interfaceMonitor.RegisterCallback(nm.notifyInterfaceUpdate)
  102. nm.interfaceMonitor = interfaceMonitor
  103. }
  104. return nm, nil
  105. }
  106. func (r *NetworkManager) Start(stage adapter.StartStage) error {
  107. monitor := taskmonitor.New(r.logger, C.StartTimeout)
  108. switch stage {
  109. case adapter.StartStateInitialize:
  110. if r.networkMonitor != nil {
  111. monitor.Start("initialize network monitor")
  112. err := r.networkMonitor.Start()
  113. monitor.Finish()
  114. if err != nil {
  115. return err
  116. }
  117. }
  118. if r.interfaceMonitor != nil {
  119. monitor.Start("initialize interface monitor")
  120. err := r.interfaceMonitor.Start()
  121. monitor.Finish()
  122. if err != nil {
  123. return err
  124. }
  125. }
  126. case adapter.StartStateStart:
  127. if runtime.GOOS == "windows" {
  128. powerListener, err := winpowrprof.NewEventListener(r.notifyWindowsPowerEvent)
  129. if err == nil {
  130. r.powerListener = powerListener
  131. } else {
  132. r.logger.Warn("initialize power listener: ", err)
  133. }
  134. }
  135. if r.powerListener != nil {
  136. monitor.Start("start power listener")
  137. err := r.powerListener.Start()
  138. monitor.Finish()
  139. if err != nil {
  140. return E.Cause(err, "start power listener")
  141. }
  142. }
  143. if C.IsAndroid && r.platformInterface == nil {
  144. monitor.Start("initialize package manager")
  145. packageManager, err := tun.NewPackageManager(tun.PackageManagerOptions{
  146. Callback: r,
  147. Logger: r.logger,
  148. })
  149. monitor.Finish()
  150. if err != nil {
  151. return E.Cause(err, "create package manager")
  152. }
  153. monitor.Start("start package manager")
  154. err = packageManager.Start()
  155. monitor.Finish()
  156. if err != nil {
  157. r.logger.Warn("initialize package manager: ", err)
  158. } else {
  159. r.packageManager = packageManager
  160. }
  161. }
  162. case adapter.StartStatePostStart:
  163. r.started = true
  164. }
  165. return nil
  166. }
  167. func (r *NetworkManager) Close() error {
  168. monitor := taskmonitor.New(r.logger, C.StopTimeout)
  169. var err error
  170. if r.packageManager != nil {
  171. monitor.Start("close package manager")
  172. err = E.Append(err, r.packageManager.Close(), func(err error) error {
  173. return E.Cause(err, "close package manager")
  174. })
  175. monitor.Finish()
  176. }
  177. if r.powerListener != nil {
  178. monitor.Start("close power listener")
  179. err = E.Append(err, r.powerListener.Close(), func(err error) error {
  180. return E.Cause(err, "close power listener")
  181. })
  182. monitor.Finish()
  183. }
  184. if r.interfaceMonitor != nil {
  185. monitor.Start("close interface monitor")
  186. err = E.Append(err, r.interfaceMonitor.Close(), func(err error) error {
  187. return E.Cause(err, "close interface monitor")
  188. })
  189. monitor.Finish()
  190. }
  191. if r.networkMonitor != nil {
  192. monitor.Start("close network monitor")
  193. err = E.Append(err, r.networkMonitor.Close(), func(err error) error {
  194. return E.Cause(err, "close network monitor")
  195. })
  196. monitor.Finish()
  197. }
  198. return err
  199. }
  200. func (r *NetworkManager) InterfaceFinder() control.InterfaceFinder {
  201. return r.interfaceFinder
  202. }
  203. func (r *NetworkManager) UpdateInterfaces() error {
  204. if r.platformInterface == nil {
  205. return r.interfaceFinder.Update()
  206. } else {
  207. interfaces, err := r.platformInterface.Interfaces()
  208. if err != nil {
  209. return err
  210. }
  211. if C.IsDarwin {
  212. err = r.interfaceFinder.Update()
  213. if err != nil {
  214. return err
  215. }
  216. // NEInterface only provides name,index and type
  217. interfaces = common.Map(interfaces, func(it adapter.NetworkInterface) adapter.NetworkInterface {
  218. iif, _ := r.interfaceFinder.ByIndex(it.Index)
  219. if iif != nil {
  220. it.Interface = *iif
  221. }
  222. return it
  223. })
  224. } else {
  225. r.interfaceFinder.UpdateInterfaces(common.Map(interfaces, func(it adapter.NetworkInterface) control.Interface { return it.Interface }))
  226. }
  227. oldInterfaces := r.networkInterfaces.Load()
  228. newInterfaces := common.Filter(interfaces, func(it adapter.NetworkInterface) bool {
  229. return it.Flags&net.FlagUp != 0
  230. })
  231. r.networkInterfaces.Store(newInterfaces)
  232. if len(newInterfaces) > 0 && !slices.EqualFunc(oldInterfaces, newInterfaces, func(oldInterface adapter.NetworkInterface, newInterface adapter.NetworkInterface) bool {
  233. return oldInterface.Interface.Index == newInterface.Interface.Index &&
  234. oldInterface.Interface.Name == newInterface.Interface.Name &&
  235. oldInterface.Interface.Flags == newInterface.Interface.Flags &&
  236. oldInterface.Type == newInterface.Type &&
  237. oldInterface.Expensive == newInterface.Expensive &&
  238. oldInterface.Constrained == newInterface.Constrained
  239. }) {
  240. r.logger.Info("updated available networks: ", strings.Join(common.Map(newInterfaces, func(it adapter.NetworkInterface) string {
  241. var options []string
  242. options = append(options, F.ToString(it.Type))
  243. if it.Expensive {
  244. options = append(options, "expensive")
  245. }
  246. if it.Constrained {
  247. options = append(options, "constrained")
  248. }
  249. return F.ToString(it.Name, " (", strings.Join(options, ", "), ")")
  250. }), ", "))
  251. }
  252. return nil
  253. }
  254. }
  255. func (r *NetworkManager) DefaultNetworkInterface() *adapter.NetworkInterface {
  256. iif := r.interfaceMonitor.DefaultInterface()
  257. if iif == nil {
  258. return nil
  259. }
  260. for _, it := range r.networkInterfaces.Load() {
  261. if it.Interface.Index == iif.Index {
  262. return &it
  263. }
  264. }
  265. return &adapter.NetworkInterface{Interface: *iif}
  266. }
  267. func (r *NetworkManager) NetworkInterfaces() []adapter.NetworkInterface {
  268. return r.networkInterfaces.Load()
  269. }
  270. func (r *NetworkManager) AutoDetectInterface() bool {
  271. return r.autoDetectInterface
  272. }
  273. func (r *NetworkManager) AutoDetectInterfaceFunc() control.Func {
  274. if r.platformInterface != nil && r.platformInterface.UsePlatformAutoDetectInterfaceControl() {
  275. return func(network, address string, conn syscall.RawConn) error {
  276. return control.Raw(conn, func(fd uintptr) error {
  277. return r.platformInterface.AutoDetectInterfaceControl(int(fd))
  278. })
  279. }
  280. } else {
  281. if r.interfaceMonitor == nil {
  282. return nil
  283. }
  284. return control.BindToInterfaceFunc(r.interfaceFinder, func(network string, address string) (interfaceName string, interfaceIndex int, err error) {
  285. remoteAddr := M.ParseSocksaddr(address).Addr
  286. if remoteAddr.IsValid() {
  287. iif, err := r.interfaceFinder.ByAddr(remoteAddr)
  288. if err == nil {
  289. return iif.Name, iif.Index, nil
  290. }
  291. }
  292. defaultInterface := r.interfaceMonitor.DefaultInterface()
  293. if defaultInterface == nil {
  294. return "", -1, tun.ErrNoRoute
  295. }
  296. return defaultInterface.Name, defaultInterface.Index, nil
  297. })
  298. }
  299. }
  300. func (r *NetworkManager) ProtectFunc() control.Func {
  301. if r.platformInterface != nil && r.platformInterface.UsePlatformAutoDetectInterfaceControl() {
  302. return func(network, address string, conn syscall.RawConn) error {
  303. return control.Raw(conn, func(fd uintptr) error {
  304. return r.platformInterface.AutoDetectInterfaceControl(int(fd))
  305. })
  306. }
  307. }
  308. return nil
  309. }
  310. func (r *NetworkManager) DefaultOptions() adapter.NetworkOptions {
  311. return r.defaultOptions
  312. }
  313. func (r *NetworkManager) RegisterAutoRedirectOutputMark(mark uint32) error {
  314. if r.autoRedirectOutputMark > 0 {
  315. return E.New("only one auto-redirect can be configured")
  316. }
  317. r.autoRedirectOutputMark = mark
  318. return nil
  319. }
  320. func (r *NetworkManager) AutoRedirectOutputMark() uint32 {
  321. return r.autoRedirectOutputMark
  322. }
  323. func (r *NetworkManager) NetworkMonitor() tun.NetworkUpdateMonitor {
  324. return r.networkMonitor
  325. }
  326. func (r *NetworkManager) InterfaceMonitor() tun.DefaultInterfaceMonitor {
  327. return r.interfaceMonitor
  328. }
  329. func (r *NetworkManager) PackageManager() tun.PackageManager {
  330. return r.packageManager
  331. }
  332. func (r *NetworkManager) WIFIState() adapter.WIFIState {
  333. return r.wifiState
  334. }
  335. func (r *NetworkManager) ResetNetwork() {
  336. r.tracker.Close()
  337. for _, endpoint := range r.endpoint.Endpoints() {
  338. listener, isListener := endpoint.(adapter.InterfaceUpdateListener)
  339. if isListener {
  340. listener.InterfaceUpdated()
  341. }
  342. }
  343. for _, inbound := range r.inbound.Inbounds() {
  344. listener, isListener := inbound.(adapter.InterfaceUpdateListener)
  345. if isListener {
  346. listener.InterfaceUpdated()
  347. }
  348. }
  349. for _, outbound := range r.outbound.Outbounds() {
  350. listener, isListener := outbound.(adapter.InterfaceUpdateListener)
  351. if isListener {
  352. listener.InterfaceUpdated()
  353. }
  354. }
  355. }
  356. func (r *NetworkManager) notifyInterfaceUpdate(defaultInterface *control.Interface, flags int) {
  357. if defaultInterface == nil {
  358. r.pauseManager.NetworkPause()
  359. r.logger.Error("missing default interface")
  360. return
  361. }
  362. r.pauseManager.NetworkWake()
  363. var options []string
  364. options = append(options, F.ToString("index ", defaultInterface.Index))
  365. if C.IsAndroid && r.platformInterface == nil {
  366. var vpnStatus string
  367. if r.interfaceMonitor.AndroidVPNEnabled() {
  368. vpnStatus = "enabled"
  369. } else {
  370. vpnStatus = "disabled"
  371. }
  372. options = append(options, "vpn "+vpnStatus)
  373. } else if r.platformInterface != nil {
  374. networkInterface := common.Find(r.networkInterfaces.Load(), func(it adapter.NetworkInterface) bool {
  375. return it.Interface.Index == defaultInterface.Index
  376. })
  377. if networkInterface.Name == "" {
  378. // race
  379. return
  380. }
  381. options = append(options, F.ToString("type ", networkInterface.Type))
  382. if networkInterface.Expensive {
  383. options = append(options, "expensive")
  384. }
  385. if networkInterface.Constrained {
  386. options = append(options, "constrained")
  387. }
  388. }
  389. r.logger.Info("updated default interface ", defaultInterface.Name, ", ", strings.Join(options, ", "))
  390. if r.platformInterface != nil {
  391. state := r.platformInterface.ReadWIFIState()
  392. if state != r.wifiState {
  393. r.wifiState = state
  394. if state.SSID != "" {
  395. r.logger.Info("updated WIFI state: SSID=", state.SSID, ", BSSID=", state.BSSID)
  396. }
  397. }
  398. }
  399. if !r.started {
  400. return
  401. }
  402. r.ResetNetwork()
  403. }
  404. func (r *NetworkManager) notifyWindowsPowerEvent(event int) {
  405. switch event {
  406. case winpowrprof.EVENT_SUSPEND:
  407. r.pauseManager.DevicePause()
  408. r.ResetNetwork()
  409. case winpowrprof.EVENT_RESUME:
  410. if !r.pauseManager.IsDevicePaused() {
  411. return
  412. }
  413. fallthrough
  414. case winpowrprof.EVENT_RESUME_AUTOMATIC:
  415. r.pauseManager.DeviceWake()
  416. r.ResetNetwork()
  417. }
  418. }
  419. func (r *NetworkManager) OnPackagesUpdated(packages int, sharedUsers int) {
  420. r.logger.Info("updated packages list: ", packages, " packages, ", sharedUsers, " shared users")
  421. }