1
0

network.go 17 KB

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