network.go 14 KB

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