network.go 13 KB

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