1
0

network.go 17 KB

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