network.go 15 KB

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