network.go 14 KB

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