network.go 15 KB

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