network.go 17 KB

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