network.go 15 KB

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