network.go 17 KB

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