network.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  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. RewriteTTL: defaultDomainResolver.RewriteTTL,
  77. ClientSubnet: defaultDomainResolver.ClientSubnet.Build(netip.Prefix{}),
  78. },
  79. NetworkStrategy: (*C.NetworkStrategy)(options.DefaultNetworkStrategy),
  80. NetworkType: common.Map(options.DefaultNetworkType, option.InterfaceType.Build),
  81. FallbackNetworkType: common.Map(options.DefaultFallbackNetworkType, option.InterfaceType.Build),
  82. FallbackDelay: time.Duration(options.DefaultFallbackDelay),
  83. },
  84. pauseManager: service.FromContext[pause.Manager](ctx),
  85. platformInterface: service.FromContext[adapter.PlatformInterface](ctx),
  86. connectionManager: service.FromContext[adapter.ConnectionManager](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(options.Rules, isWIFIRule) || hasDNSRule(dnsOptions.Rules, isWIFIDNSRule),
  91. }
  92. if options.DefaultNetworkStrategy != nil {
  93. if options.DefaultInterface != "" {
  94. return nil, E.New("`default_network_strategy` is conflict with `default_interface`")
  95. }
  96. if !options.AutoDetectInterface {
  97. return nil, E.New("`auto_detect_interface` is required by `default_network_strategy`")
  98. }
  99. }
  100. usePlatformDefaultInterfaceMonitor := nm.platformInterface != nil
  101. enforceInterfaceMonitor := options.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: options.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 || !r.platformInterface.UsePlatformNetworkInterfaces() {
  256. return r.interfaceFinder.Update()
  257. } else {
  258. interfaces, err := r.platformInterface.NetworkInterfaces()
  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.wifiState = state
  403. r.wifiStateMutex.Unlock()
  404. if state.SSID != "" {
  405. r.logger.Info("WIFI state changed: SSID=", state.SSID, ", BSSID=", state.BSSID)
  406. } else {
  407. r.logger.Info("WIFI disconnected")
  408. }
  409. } else {
  410. r.wifiStateMutex.Unlock()
  411. }
  412. }
  413. func (r *NetworkManager) UpdateWIFIState() {
  414. var state adapter.WIFIState
  415. if r.wifiMonitor != nil {
  416. state = r.wifiMonitor.ReadWIFIState()
  417. } else if r.platformInterface != nil && r.platformInterface.UsePlatformWIFIMonitor() {
  418. state = r.platformInterface.ReadWIFIState()
  419. } else {
  420. return
  421. }
  422. r.onWIFIStateChanged(state)
  423. }
  424. func (r *NetworkManager) ResetNetwork() {
  425. if r.connectionManager != nil {
  426. r.connectionManager.CloseAll()
  427. }
  428. for _, endpoint := range r.endpoint.Endpoints() {
  429. listener, isListener := endpoint.(adapter.InterfaceUpdateListener)
  430. if isListener {
  431. listener.InterfaceUpdated()
  432. }
  433. }
  434. for _, inbound := range r.inbound.Inbounds() {
  435. listener, isListener := inbound.(adapter.InterfaceUpdateListener)
  436. if isListener {
  437. listener.InterfaceUpdated()
  438. }
  439. }
  440. for _, outbound := range r.outbound.Outbounds() {
  441. listener, isListener := outbound.(adapter.InterfaceUpdateListener)
  442. if isListener {
  443. listener.InterfaceUpdated()
  444. }
  445. }
  446. }
  447. func (r *NetworkManager) notifyInterfaceUpdate(defaultInterface *control.Interface, flags int) {
  448. if defaultInterface == nil {
  449. r.pauseManager.NetworkPause()
  450. r.logger.Error("missing default interface")
  451. return
  452. }
  453. r.pauseManager.NetworkWake()
  454. var options []string
  455. options = append(options, F.ToString("index ", defaultInterface.Index))
  456. if C.IsAndroid && r.platformInterface == nil {
  457. var vpnStatus string
  458. if r.interfaceMonitor.AndroidVPNEnabled() {
  459. vpnStatus = "enabled"
  460. } else {
  461. vpnStatus = "disabled"
  462. }
  463. options = append(options, "vpn "+vpnStatus)
  464. } else if r.platformInterface != nil {
  465. networkInterface := common.Find(r.networkInterfaces.Load(), func(it adapter.NetworkInterface) bool {
  466. return it.Interface.Index == defaultInterface.Index
  467. })
  468. if networkInterface.Name == "" {
  469. // race
  470. return
  471. }
  472. options = append(options, F.ToString("type ", networkInterface.Type))
  473. if networkInterface.Expensive {
  474. options = append(options, "expensive")
  475. }
  476. if networkInterface.Constrained {
  477. options = append(options, "constrained")
  478. }
  479. }
  480. r.logger.Info("updated default interface ", defaultInterface.Name, ", ", strings.Join(options, ", "))
  481. r.UpdateWIFIState()
  482. if !r.started {
  483. return
  484. }
  485. r.ResetNetwork()
  486. }
  487. func (r *NetworkManager) notifyWindowsPowerEvent(event int) {
  488. switch event {
  489. case winpowrprof.EVENT_SUSPEND:
  490. r.pauseManager.DevicePause()
  491. r.ResetNetwork()
  492. case winpowrprof.EVENT_RESUME:
  493. if !r.pauseManager.IsDevicePaused() {
  494. return
  495. }
  496. fallthrough
  497. case winpowrprof.EVENT_RESUME_AUTOMATIC:
  498. r.pauseManager.DeviceWake()
  499. r.ResetNetwork()
  500. }
  501. }
  502. func (r *NetworkManager) OnPackagesUpdated(packages int, sharedUsers int) {
  503. r.logger.Info("updated packages list: ", packages, " packages, ", sharedUsers, " shared users")
  504. }