router.go 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166
  1. package route
  2. import (
  3. "context"
  4. "io"
  5. "net"
  6. "net/http"
  7. "net/netip"
  8. "net/url"
  9. "os"
  10. "os/user"
  11. "path/filepath"
  12. "strings"
  13. "time"
  14. "github.com/sagernet/sing-box/adapter"
  15. "github.com/sagernet/sing-box/common/dialer"
  16. "github.com/sagernet/sing-box/common/dialer/conntrack"
  17. "github.com/sagernet/sing-box/common/geoip"
  18. "github.com/sagernet/sing-box/common/geosite"
  19. "github.com/sagernet/sing-box/common/mux"
  20. "github.com/sagernet/sing-box/common/process"
  21. "github.com/sagernet/sing-box/common/sniff"
  22. "github.com/sagernet/sing-box/common/warning"
  23. C "github.com/sagernet/sing-box/constant"
  24. "github.com/sagernet/sing-box/experimental/libbox/platform"
  25. "github.com/sagernet/sing-box/log"
  26. "github.com/sagernet/sing-box/ntp"
  27. "github.com/sagernet/sing-box/option"
  28. "github.com/sagernet/sing-box/outbound"
  29. "github.com/sagernet/sing-dns"
  30. "github.com/sagernet/sing-tun"
  31. "github.com/sagernet/sing-vmess"
  32. "github.com/sagernet/sing/common"
  33. "github.com/sagernet/sing/common/buf"
  34. "github.com/sagernet/sing/common/bufio"
  35. "github.com/sagernet/sing/common/control"
  36. E "github.com/sagernet/sing/common/exceptions"
  37. F "github.com/sagernet/sing/common/format"
  38. M "github.com/sagernet/sing/common/metadata"
  39. N "github.com/sagernet/sing/common/network"
  40. "github.com/sagernet/sing/common/rw"
  41. "github.com/sagernet/sing/common/uot"
  42. )
  43. var warnDefaultInterfaceOnUnsupportedPlatform = warning.New(
  44. func() bool {
  45. return !(C.IsLinux || C.IsWindows || C.IsDarwin)
  46. },
  47. "route option `default_mark` is only supported on Linux and Windows",
  48. )
  49. var warnDefaultMarkOnNonLinux = warning.New(
  50. func() bool {
  51. return !C.IsLinux
  52. },
  53. "route option `default_mark` is only supported on Linux",
  54. )
  55. var warnFindProcessOnUnsupportedPlatform = warning.New(
  56. func() bool {
  57. return !(C.IsLinux || C.IsWindows || C.IsDarwin)
  58. },
  59. "route option `find_process` is only supported on Linux, Windows, and macOS",
  60. )
  61. var _ adapter.Router = (*Router)(nil)
  62. type Router struct {
  63. ctx context.Context
  64. logger log.ContextLogger
  65. dnsLogger log.ContextLogger
  66. inboundByTag map[string]adapter.Inbound
  67. outbounds []adapter.Outbound
  68. outboundByTag map[string]adapter.Outbound
  69. rules []adapter.Rule
  70. defaultDetour string
  71. defaultOutboundForConnection adapter.Outbound
  72. defaultOutboundForPacketConnection adapter.Outbound
  73. needGeoIPDatabase bool
  74. needGeositeDatabase bool
  75. geoIPOptions option.GeoIPOptions
  76. geositeOptions option.GeositeOptions
  77. geoIPReader *geoip.Reader
  78. geositeReader *geosite.Reader
  79. geositeCache map[string]adapter.Rule
  80. dnsClient *dns.Client
  81. defaultDomainStrategy dns.DomainStrategy
  82. dnsRules []adapter.DNSRule
  83. defaultTransport dns.Transport
  84. transports []dns.Transport
  85. transportMap map[string]dns.Transport
  86. transportDomainStrategy map[dns.Transport]dns.DomainStrategy
  87. interfaceFinder myInterfaceFinder
  88. autoDetectInterface bool
  89. defaultInterface string
  90. defaultMark int
  91. networkMonitor tun.NetworkUpdateMonitor
  92. interfaceMonitor tun.DefaultInterfaceMonitor
  93. packageManager tun.PackageManager
  94. processSearcher process.Searcher
  95. timeService adapter.TimeService
  96. clashServer adapter.ClashServer
  97. v2rayServer adapter.V2RayServer
  98. platformInterface platform.Interface
  99. }
  100. func NewRouter(
  101. ctx context.Context,
  102. logFactory log.Factory,
  103. options option.RouteOptions,
  104. dnsOptions option.DNSOptions,
  105. ntpOptions option.NTPOptions,
  106. inbounds []option.Inbound,
  107. platformInterface platform.Interface,
  108. ) (*Router, error) {
  109. if options.DefaultInterface != "" {
  110. warnDefaultInterfaceOnUnsupportedPlatform.Check()
  111. }
  112. if options.DefaultMark != 0 {
  113. warnDefaultMarkOnNonLinux.Check()
  114. }
  115. if options.FindProcess {
  116. warnFindProcessOnUnsupportedPlatform.Check()
  117. }
  118. router := &Router{
  119. ctx: ctx,
  120. logger: logFactory.NewLogger("router"),
  121. dnsLogger: logFactory.NewLogger("dns"),
  122. outboundByTag: make(map[string]adapter.Outbound),
  123. rules: make([]adapter.Rule, 0, len(options.Rules)),
  124. dnsRules: make([]adapter.DNSRule, 0, len(dnsOptions.Rules)),
  125. needGeoIPDatabase: hasRule(options.Rules, isGeoIPRule) || hasDNSRule(dnsOptions.Rules, isGeoIPDNSRule),
  126. needGeositeDatabase: hasRule(options.Rules, isGeositeRule) || hasDNSRule(dnsOptions.Rules, isGeositeDNSRule),
  127. geoIPOptions: common.PtrValueOrDefault(options.GeoIP),
  128. geositeOptions: common.PtrValueOrDefault(options.Geosite),
  129. geositeCache: make(map[string]adapter.Rule),
  130. defaultDetour: options.Final,
  131. defaultDomainStrategy: dns.DomainStrategy(dnsOptions.Strategy),
  132. autoDetectInterface: options.AutoDetectInterface,
  133. defaultInterface: options.DefaultInterface,
  134. defaultMark: options.DefaultMark,
  135. platformInterface: platformInterface,
  136. }
  137. router.dnsClient = dns.NewClient(dnsOptions.DNSClientOptions.DisableCache, dnsOptions.DNSClientOptions.DisableExpire, router.dnsLogger)
  138. for i, ruleOptions := range options.Rules {
  139. routeRule, err := NewRule(router, router.logger, ruleOptions)
  140. if err != nil {
  141. return nil, E.Cause(err, "parse rule[", i, "]")
  142. }
  143. router.rules = append(router.rules, routeRule)
  144. }
  145. for i, dnsRuleOptions := range dnsOptions.Rules {
  146. dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions)
  147. if err != nil {
  148. return nil, E.Cause(err, "parse dns rule[", i, "]")
  149. }
  150. router.dnsRules = append(router.dnsRules, dnsRule)
  151. }
  152. transports := make([]dns.Transport, len(dnsOptions.Servers))
  153. dummyTransportMap := make(map[string]dns.Transport)
  154. transportMap := make(map[string]dns.Transport)
  155. transportTags := make([]string, len(dnsOptions.Servers))
  156. transportTagMap := make(map[string]bool)
  157. transportDomainStrategy := make(map[dns.Transport]dns.DomainStrategy)
  158. for i, server := range dnsOptions.Servers {
  159. var tag string
  160. if server.Tag != "" {
  161. tag = server.Tag
  162. } else {
  163. tag = F.ToString(i)
  164. }
  165. if transportTagMap[tag] {
  166. return nil, E.New("duplicate dns server tag: ", tag)
  167. }
  168. transportTags[i] = tag
  169. transportTagMap[tag] = true
  170. }
  171. ctx = adapter.ContextWithRouter(ctx, router)
  172. for {
  173. lastLen := len(dummyTransportMap)
  174. for i, server := range dnsOptions.Servers {
  175. tag := transportTags[i]
  176. if _, exists := dummyTransportMap[tag]; exists {
  177. continue
  178. }
  179. var detour N.Dialer
  180. if server.Detour == "" {
  181. detour = dialer.NewRouter(router)
  182. } else {
  183. detour = dialer.NewDetour(router, server.Detour)
  184. }
  185. switch server.Address {
  186. case "local":
  187. default:
  188. serverURL, _ := url.Parse(server.Address)
  189. var serverAddress string
  190. if serverURL != nil {
  191. serverAddress = serverURL.Hostname()
  192. }
  193. if serverAddress == "" {
  194. serverAddress = server.Address
  195. }
  196. _, notIpAddress := netip.ParseAddr(serverAddress)
  197. if server.AddressResolver != "" {
  198. if !transportTagMap[server.AddressResolver] {
  199. return nil, E.New("parse dns server[", tag, "]: address resolver not found: ", server.AddressResolver)
  200. }
  201. if upstream, exists := dummyTransportMap[server.AddressResolver]; exists {
  202. detour = dns.NewDialerWrapper(detour, router.dnsClient, upstream, dns.DomainStrategy(server.AddressStrategy), time.Duration(server.AddressFallbackDelay))
  203. } else {
  204. continue
  205. }
  206. } else if notIpAddress != nil {
  207. switch serverURL.Scheme {
  208. case "rcode", "dhcp":
  209. default:
  210. return nil, E.New("parse dns server[", tag, "]: missing address_resolver")
  211. }
  212. }
  213. }
  214. transport, err := dns.CreateTransport(tag, ctx, logFactory.NewLogger(F.ToString("dns/transport[", tag, "]")), detour, server.Address)
  215. if err != nil {
  216. return nil, E.Cause(err, "parse dns server[", tag, "]")
  217. }
  218. transports[i] = transport
  219. dummyTransportMap[tag] = transport
  220. if server.Tag != "" {
  221. transportMap[server.Tag] = transport
  222. }
  223. strategy := dns.DomainStrategy(server.Strategy)
  224. if strategy != dns.DomainStrategyAsIS {
  225. transportDomainStrategy[transport] = strategy
  226. }
  227. }
  228. if len(transports) == len(dummyTransportMap) {
  229. break
  230. }
  231. if lastLen != len(dummyTransportMap) {
  232. continue
  233. }
  234. unresolvedTags := common.MapIndexed(common.FilterIndexed(dnsOptions.Servers, func(index int, server option.DNSServerOptions) bool {
  235. _, exists := dummyTransportMap[transportTags[index]]
  236. return !exists
  237. }), func(index int, server option.DNSServerOptions) string {
  238. return transportTags[index]
  239. })
  240. if len(unresolvedTags) == 0 {
  241. panic(F.ToString("unexpected unresolved dns servers: ", len(transports), " ", len(dummyTransportMap), " ", len(transportMap)))
  242. }
  243. return nil, E.New("found circular reference in dns servers: ", strings.Join(unresolvedTags, " "))
  244. }
  245. var defaultTransport dns.Transport
  246. if dnsOptions.Final != "" {
  247. defaultTransport = dummyTransportMap[dnsOptions.Final]
  248. if defaultTransport == nil {
  249. return nil, E.New("default dns server not found: ", dnsOptions.Final)
  250. }
  251. }
  252. if defaultTransport == nil {
  253. if len(transports) == 0 {
  254. transports = append(transports, dns.NewLocalTransport("local", N.SystemDialer))
  255. }
  256. defaultTransport = transports[0]
  257. }
  258. router.defaultTransport = defaultTransport
  259. router.transports = transports
  260. router.transportMap = transportMap
  261. router.transportDomainStrategy = transportDomainStrategy
  262. needInterfaceMonitor := options.AutoDetectInterface || common.Any(inbounds, func(inbound option.Inbound) bool {
  263. return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy || inbound.TunOptions.AutoRoute
  264. })
  265. if needInterfaceMonitor {
  266. networkMonitor, err := tun.NewNetworkUpdateMonitor(router)
  267. if err == nil {
  268. router.networkMonitor = networkMonitor
  269. networkMonitor.RegisterCallback(router.interfaceFinder.update)
  270. }
  271. }
  272. if router.networkMonitor != nil && needInterfaceMonitor {
  273. interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor, tun.DefaultInterfaceMonitorOptions{
  274. OverrideAndroidVPN: options.OverrideAndroidVPN,
  275. })
  276. if err != nil {
  277. return nil, E.New("auto_detect_interface unsupported on current platform")
  278. }
  279. interfaceMonitor.RegisterCallback(router.notifyNetworkUpdate)
  280. router.interfaceMonitor = interfaceMonitor
  281. }
  282. needFindProcess := hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess
  283. needPackageManager := C.IsAndroid && platformInterface == nil && (needFindProcess || common.Any(inbounds, func(inbound option.Inbound) bool {
  284. return len(inbound.TunOptions.IncludePackage) > 0 || len(inbound.TunOptions.ExcludePackage) > 0
  285. }))
  286. if needPackageManager {
  287. packageManager, err := tun.NewPackageManager(router)
  288. if err != nil {
  289. return nil, E.Cause(err, "create package manager")
  290. }
  291. router.packageManager = packageManager
  292. }
  293. if needFindProcess {
  294. if platformInterface != nil {
  295. router.processSearcher = platformInterface
  296. } else {
  297. searcher, err := process.NewSearcher(process.Config{
  298. Logger: logFactory.NewLogger("router/process"),
  299. PackageManager: router.packageManager,
  300. })
  301. if err != nil {
  302. if err != os.ErrInvalid {
  303. router.logger.Warn(E.Cause(err, "create process searcher"))
  304. }
  305. } else {
  306. router.processSearcher = searcher
  307. }
  308. }
  309. }
  310. if ntpOptions.Enabled {
  311. router.timeService = ntp.NewService(ctx, router, logFactory.NewLogger("ntp"), ntpOptions)
  312. }
  313. return router, nil
  314. }
  315. func (r *Router) Initialize(inbounds []adapter.Inbound, outbounds []adapter.Outbound, defaultOutbound func() adapter.Outbound) error {
  316. inboundByTag := make(map[string]adapter.Inbound)
  317. for _, inbound := range inbounds {
  318. inboundByTag[inbound.Tag()] = inbound
  319. }
  320. outboundByTag := make(map[string]adapter.Outbound)
  321. for _, detour := range outbounds {
  322. outboundByTag[detour.Tag()] = detour
  323. }
  324. var defaultOutboundForConnection adapter.Outbound
  325. var defaultOutboundForPacketConnection adapter.Outbound
  326. if r.defaultDetour != "" {
  327. detour, loaded := outboundByTag[r.defaultDetour]
  328. if !loaded {
  329. return E.New("default detour not found: ", r.defaultDetour)
  330. }
  331. if common.Contains(detour.Network(), N.NetworkTCP) {
  332. defaultOutboundForConnection = detour
  333. }
  334. if common.Contains(detour.Network(), N.NetworkUDP) {
  335. defaultOutboundForPacketConnection = detour
  336. }
  337. }
  338. var index, packetIndex int
  339. if defaultOutboundForConnection == nil {
  340. for i, detour := range outbounds {
  341. if common.Contains(detour.Network(), N.NetworkTCP) {
  342. index = i
  343. defaultOutboundForConnection = detour
  344. break
  345. }
  346. }
  347. }
  348. if defaultOutboundForPacketConnection == nil {
  349. for i, detour := range outbounds {
  350. if common.Contains(detour.Network(), N.NetworkUDP) {
  351. packetIndex = i
  352. defaultOutboundForPacketConnection = detour
  353. break
  354. }
  355. }
  356. }
  357. if defaultOutboundForConnection == nil || defaultOutboundForPacketConnection == nil {
  358. detour := defaultOutbound()
  359. if defaultOutboundForConnection == nil {
  360. defaultOutboundForConnection = detour
  361. }
  362. if defaultOutboundForPacketConnection == nil {
  363. defaultOutboundForPacketConnection = detour
  364. }
  365. outbounds = append(outbounds, detour)
  366. outboundByTag[detour.Tag()] = detour
  367. }
  368. if defaultOutboundForConnection != defaultOutboundForPacketConnection {
  369. var description string
  370. if defaultOutboundForConnection.Tag() != "" {
  371. description = defaultOutboundForConnection.Tag()
  372. } else {
  373. description = F.ToString(index)
  374. }
  375. var packetDescription string
  376. if defaultOutboundForPacketConnection.Tag() != "" {
  377. packetDescription = defaultOutboundForPacketConnection.Tag()
  378. } else {
  379. packetDescription = F.ToString(packetIndex)
  380. }
  381. r.logger.Info("using ", defaultOutboundForConnection.Type(), "[", description, "] as default outbound for connection")
  382. r.logger.Info("using ", defaultOutboundForPacketConnection.Type(), "[", packetDescription, "] as default outbound for packet connection")
  383. }
  384. r.inboundByTag = inboundByTag
  385. r.outbounds = outbounds
  386. r.defaultOutboundForConnection = defaultOutboundForConnection
  387. r.defaultOutboundForPacketConnection = defaultOutboundForPacketConnection
  388. r.outboundByTag = outboundByTag
  389. for i, rule := range r.rules {
  390. if _, loaded := outboundByTag[rule.Outbound()]; !loaded {
  391. return E.New("outbound not found for rule[", i, "]: ", rule.Outbound())
  392. }
  393. }
  394. return nil
  395. }
  396. func (r *Router) Outbounds() []adapter.Outbound {
  397. return r.outbounds
  398. }
  399. func (r *Router) Start() error {
  400. if r.needGeoIPDatabase {
  401. err := r.prepareGeoIPDatabase()
  402. if err != nil {
  403. return err
  404. }
  405. }
  406. if r.needGeositeDatabase {
  407. err := r.prepareGeositeDatabase()
  408. if err != nil {
  409. return err
  410. }
  411. }
  412. if r.interfaceMonitor != nil {
  413. err := r.interfaceMonitor.Start()
  414. if err != nil {
  415. return err
  416. }
  417. }
  418. if r.networkMonitor != nil {
  419. err := r.networkMonitor.Start()
  420. if err != nil {
  421. return err
  422. }
  423. }
  424. if r.packageManager != nil {
  425. err := r.packageManager.Start()
  426. if err != nil {
  427. return err
  428. }
  429. }
  430. if r.needGeositeDatabase {
  431. for _, rule := range r.rules {
  432. err := rule.UpdateGeosite()
  433. if err != nil {
  434. r.logger.Error("failed to initialize geosite: ", err)
  435. }
  436. }
  437. for _, rule := range r.dnsRules {
  438. err := rule.UpdateGeosite()
  439. if err != nil {
  440. r.logger.Error("failed to initialize geosite: ", err)
  441. }
  442. }
  443. err := common.Close(r.geositeReader)
  444. if err != nil {
  445. return err
  446. }
  447. r.geositeCache = nil
  448. r.geositeReader = nil
  449. }
  450. for i, rule := range r.rules {
  451. err := rule.Start()
  452. if err != nil {
  453. return E.Cause(err, "initialize rule[", i, "]")
  454. }
  455. }
  456. for i, rule := range r.dnsRules {
  457. err := rule.Start()
  458. if err != nil {
  459. return E.Cause(err, "initialize DNS rule[", i, "]")
  460. }
  461. }
  462. for i, transport := range r.transports {
  463. err := transport.Start()
  464. if err != nil {
  465. return E.Cause(err, "initialize DNS server[", i, "]")
  466. }
  467. }
  468. if r.timeService != nil {
  469. err := r.timeService.Start()
  470. if err != nil {
  471. return E.Cause(err, "initialize time service")
  472. }
  473. }
  474. return nil
  475. }
  476. func (r *Router) Close() error {
  477. var err error
  478. for i, rule := range r.rules {
  479. r.logger.Trace("closing rule[", i, "]")
  480. err = E.Append(err, rule.Close(), func(err error) error {
  481. return E.Cause(err, "close rule[", i, "]")
  482. })
  483. }
  484. for i, rule := range r.dnsRules {
  485. r.logger.Trace("closing dns rule[", i, "]")
  486. err = E.Append(err, rule.Close(), func(err error) error {
  487. return E.Cause(err, "close dns rule[", i, "]")
  488. })
  489. }
  490. for i, transport := range r.transports {
  491. r.logger.Trace("closing transport[", i, "] ")
  492. err = E.Append(err, transport.Close(), func(err error) error {
  493. return E.Cause(err, "close dns transport[", i, "]")
  494. })
  495. }
  496. if r.geositeReader != nil {
  497. r.logger.Trace("closing geoip reader")
  498. err = E.Append(err, common.Close(r.geoIPReader), func(err error) error {
  499. return E.Cause(err, "close geoip reader")
  500. })
  501. }
  502. if r.interfaceMonitor != nil {
  503. r.logger.Trace("closing interface monitor")
  504. err = E.Append(err, r.interfaceMonitor.Close(), func(err error) error {
  505. return E.Cause(err, "close interface monitor")
  506. })
  507. }
  508. if r.networkMonitor != nil {
  509. r.logger.Trace("closing network monitor")
  510. err = E.Append(err, r.networkMonitor.Close(), func(err error) error {
  511. return E.Cause(err, "close network monitor")
  512. })
  513. }
  514. if r.packageManager != nil {
  515. r.logger.Trace("closing package manager")
  516. err = E.Append(err, r.packageManager.Close(), func(err error) error {
  517. return E.Cause(err, "close package manager")
  518. })
  519. }
  520. if r.timeService != nil {
  521. r.logger.Trace("closing time service")
  522. err = E.Append(err, r.timeService.Close(), func(err error) error {
  523. return E.Cause(err, "close time service")
  524. })
  525. }
  526. return err
  527. }
  528. func (r *Router) GeoIPReader() *geoip.Reader {
  529. return r.geoIPReader
  530. }
  531. func (r *Router) LoadGeosite(code string) (adapter.Rule, error) {
  532. rule, cached := r.geositeCache[code]
  533. if cached {
  534. return rule, nil
  535. }
  536. items, err := r.geositeReader.Read(code)
  537. if err != nil {
  538. return nil, err
  539. }
  540. rule, err = NewDefaultRule(r, nil, geosite.Compile(items))
  541. if err != nil {
  542. return nil, err
  543. }
  544. r.geositeCache[code] = rule
  545. return rule, nil
  546. }
  547. func (r *Router) Outbound(tag string) (adapter.Outbound, bool) {
  548. outbound, loaded := r.outboundByTag[tag]
  549. return outbound, loaded
  550. }
  551. func (r *Router) DefaultOutbound(network string) adapter.Outbound {
  552. if network == N.NetworkTCP {
  553. return r.defaultOutboundForConnection
  554. } else {
  555. return r.defaultOutboundForPacketConnection
  556. }
  557. }
  558. func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  559. if metadata.InboundDetour != "" {
  560. if metadata.LastInbound == metadata.InboundDetour {
  561. return E.New("routing loop on detour: ", metadata.InboundDetour)
  562. }
  563. detour := r.inboundByTag[metadata.InboundDetour]
  564. if detour == nil {
  565. return E.New("inbound detour not found: ", metadata.InboundDetour)
  566. }
  567. injectable, isInjectable := detour.(adapter.InjectableInbound)
  568. if !isInjectable {
  569. return E.New("inbound detour is not injectable: ", metadata.InboundDetour)
  570. }
  571. if !common.Contains(injectable.Network(), N.NetworkTCP) {
  572. return E.New("inject: TCP unsupported")
  573. }
  574. metadata.LastInbound = metadata.Inbound
  575. metadata.Inbound = metadata.InboundDetour
  576. metadata.InboundDetour = ""
  577. err := injectable.NewConnection(ctx, conn, metadata)
  578. if err != nil {
  579. return E.Cause(err, "inject ", detour.Tag())
  580. }
  581. return nil
  582. }
  583. metadata.Network = N.NetworkTCP
  584. switch metadata.Destination.Fqdn {
  585. case mux.Destination.Fqdn:
  586. r.logger.InfoContext(ctx, "inbound multiplex connection")
  587. return mux.NewConnection(ctx, r, r, r.logger, conn, metadata)
  588. case vmess.MuxDestination.Fqdn:
  589. r.logger.InfoContext(ctx, "inbound legacy multiplex connection")
  590. return vmess.HandleMuxConnection(ctx, conn, adapter.NewUpstreamHandler(metadata, r.RouteConnection, r.RoutePacketConnection, r))
  591. case uot.MagicAddress:
  592. request, err := uot.ReadRequest(conn)
  593. if err != nil {
  594. return E.Cause(err, "read UoT request")
  595. }
  596. if request.IsConnect {
  597. r.logger.InfoContext(ctx, "inbound UoT connect connection to ", request.Destination)
  598. } else {
  599. r.logger.InfoContext(ctx, "inbound UoT connection to ", request.Destination)
  600. }
  601. metadata.Domain = metadata.Destination.Fqdn
  602. metadata.Destination = request.Destination
  603. return r.RoutePacketConnection(ctx, uot.NewConn(conn, *request), metadata)
  604. case uot.LegacyMagicAddress:
  605. r.logger.InfoContext(ctx, "inbound legacy UoT connection")
  606. metadata.Domain = metadata.Destination.Fqdn
  607. metadata.Destination = M.Socksaddr{Addr: netip.IPv4Unspecified()}
  608. return r.RoutePacketConnection(ctx, uot.NewConn(conn, uot.Request{}), metadata)
  609. }
  610. if metadata.InboundOptions.SniffEnabled {
  611. buffer := buf.NewPacket()
  612. buffer.FullReset()
  613. sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
  614. if sniffMetadata != nil {
  615. metadata.Protocol = sniffMetadata.Protocol
  616. metadata.Domain = sniffMetadata.Domain
  617. if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) {
  618. metadata.Destination = M.Socksaddr{
  619. Fqdn: metadata.Domain,
  620. Port: metadata.Destination.Port,
  621. }
  622. }
  623. if metadata.Domain != "" {
  624. r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol, ", domain: ", metadata.Domain)
  625. } else {
  626. r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol)
  627. }
  628. } else if err != nil {
  629. r.logger.TraceContext(ctx, "sniffed no protocol: ", err)
  630. }
  631. if !buffer.IsEmpty() {
  632. conn = bufio.NewCachedConn(conn, buffer)
  633. } else {
  634. buffer.Release()
  635. }
  636. }
  637. if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS {
  638. addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy))
  639. if err != nil {
  640. return err
  641. }
  642. metadata.DestinationAddresses = addresses
  643. r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
  644. }
  645. ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForConnection)
  646. if err != nil {
  647. return err
  648. }
  649. if !common.Contains(detour.Network(), N.NetworkTCP) {
  650. return E.New("missing supported outbound, closing connection")
  651. }
  652. if r.clashServer != nil {
  653. trackerConn, tracker := r.clashServer.RoutedConnection(ctx, conn, metadata, matchedRule)
  654. defer tracker.Leave()
  655. conn = trackerConn
  656. }
  657. if r.v2rayServer != nil {
  658. if statsService := r.v2rayServer.StatsService(); statsService != nil {
  659. conn = statsService.RoutedConnection(metadata.Inbound, detour.Tag(), metadata.User, conn)
  660. }
  661. }
  662. return detour.NewConnection(ctx, conn, metadata)
  663. }
  664. func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  665. if metadata.InboundDetour != "" {
  666. if metadata.LastInbound == metadata.InboundDetour {
  667. return E.New("routing loop on detour: ", metadata.InboundDetour)
  668. }
  669. detour := r.inboundByTag[metadata.InboundDetour]
  670. if detour == nil {
  671. return E.New("inbound detour not found: ", metadata.InboundDetour)
  672. }
  673. injectable, isInjectable := detour.(adapter.InjectableInbound)
  674. if !isInjectable {
  675. return E.New("inbound detour is not injectable: ", metadata.InboundDetour)
  676. }
  677. if !common.Contains(injectable.Network(), N.NetworkUDP) {
  678. return E.New("inject: UDP unsupported")
  679. }
  680. metadata.LastInbound = metadata.Inbound
  681. metadata.Inbound = metadata.InboundDetour
  682. metadata.InboundDetour = ""
  683. err := injectable.NewPacketConnection(ctx, conn, metadata)
  684. if err != nil {
  685. return E.Cause(err, "inject ", detour.Tag())
  686. }
  687. return nil
  688. }
  689. metadata.Network = N.NetworkUDP
  690. if metadata.InboundOptions.SniffEnabled {
  691. buffer := buf.NewPacket()
  692. buffer.FullReset()
  693. destination, err := conn.ReadPacket(buffer)
  694. if err != nil {
  695. buffer.Release()
  696. return err
  697. }
  698. sniffMetadata, _ := sniff.PeekPacket(ctx, buffer.Bytes(), sniff.DomainNameQuery, sniff.QUICClientHello, sniff.STUNMessage)
  699. if sniffMetadata != nil {
  700. metadata.Protocol = sniffMetadata.Protocol
  701. metadata.Domain = sniffMetadata.Domain
  702. if metadata.InboundOptions.SniffOverrideDestination && M.IsDomainName(metadata.Domain) {
  703. metadata.Destination = M.Socksaddr{
  704. Fqdn: metadata.Domain,
  705. Port: metadata.Destination.Port,
  706. }
  707. }
  708. if metadata.Domain != "" {
  709. r.logger.DebugContext(ctx, "sniffed packet protocol: ", metadata.Protocol, ", domain: ", metadata.Domain)
  710. } else {
  711. r.logger.DebugContext(ctx, "sniffed packet protocol: ", metadata.Protocol)
  712. }
  713. }
  714. conn = bufio.NewCachedPacketConn(conn, buffer, destination)
  715. }
  716. if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS {
  717. addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy))
  718. if err != nil {
  719. return err
  720. }
  721. metadata.DestinationAddresses = addresses
  722. r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
  723. }
  724. ctx, matchedRule, detour, err := r.match(ctx, &metadata, r.defaultOutboundForPacketConnection)
  725. if err != nil {
  726. return err
  727. }
  728. if !common.Contains(detour.Network(), N.NetworkUDP) {
  729. return E.New("missing supported outbound, closing packet connection")
  730. }
  731. if r.clashServer != nil {
  732. trackerConn, tracker := r.clashServer.RoutedPacketConnection(ctx, conn, metadata, matchedRule)
  733. defer tracker.Leave()
  734. conn = trackerConn
  735. }
  736. if r.v2rayServer != nil {
  737. if statsService := r.v2rayServer.StatsService(); statsService != nil {
  738. conn = statsService.RoutedPacketConnection(metadata.Inbound, detour.Tag(), metadata.User, conn)
  739. }
  740. }
  741. return detour.NewPacketConnection(ctx, conn, metadata)
  742. }
  743. func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, defaultOutbound adapter.Outbound) (context.Context, adapter.Rule, adapter.Outbound, error) {
  744. matchRule, matchOutbound := r.match0(ctx, metadata, defaultOutbound)
  745. if contextOutbound, loaded := outbound.TagFromContext(ctx); loaded {
  746. if contextOutbound == matchOutbound.Tag() {
  747. return nil, nil, nil, E.New("connection loopback in outbound/", matchOutbound.Type(), "[", matchOutbound.Tag(), "]")
  748. }
  749. }
  750. ctx = outbound.ContextWithTag(ctx, matchOutbound.Tag())
  751. return ctx, matchRule, matchOutbound, nil
  752. }
  753. func (r *Router) match0(ctx context.Context, metadata *adapter.InboundContext, defaultOutbound adapter.Outbound) (adapter.Rule, adapter.Outbound) {
  754. if r.processSearcher != nil {
  755. var originDestination netip.AddrPort
  756. if metadata.OriginDestination.IsValid() {
  757. originDestination = metadata.OriginDestination.AddrPort()
  758. } else if metadata.Destination.IsIP() {
  759. originDestination = metadata.Destination.AddrPort()
  760. }
  761. processInfo, err := process.FindProcessInfo(r.processSearcher, ctx, metadata.Network, metadata.Source.AddrPort(), originDestination)
  762. if err != nil {
  763. r.logger.InfoContext(ctx, "failed to search process: ", err)
  764. } else {
  765. if processInfo.ProcessPath != "" {
  766. r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath)
  767. } else if processInfo.PackageName != "" {
  768. r.logger.InfoContext(ctx, "found package name: ", processInfo.PackageName)
  769. } else if processInfo.UserId != -1 {
  770. if /*needUserName &&*/ true {
  771. osUser, _ := user.LookupId(F.ToString(processInfo.UserId))
  772. if osUser != nil {
  773. processInfo.User = osUser.Username
  774. }
  775. }
  776. if processInfo.User != "" {
  777. r.logger.InfoContext(ctx, "found user: ", processInfo.User)
  778. } else {
  779. r.logger.InfoContext(ctx, "found user id: ", processInfo.UserId)
  780. }
  781. }
  782. metadata.ProcessInfo = processInfo
  783. }
  784. }
  785. for i, rule := range r.rules {
  786. if rule.Match(metadata) {
  787. detour := rule.Outbound()
  788. r.logger.DebugContext(ctx, "match[", i, "] ", rule.String(), " => ", detour)
  789. if outbound, loaded := r.Outbound(detour); loaded {
  790. return rule, outbound
  791. }
  792. r.logger.ErrorContext(ctx, "outbound not found: ", detour)
  793. }
  794. }
  795. return nil, defaultOutbound
  796. }
  797. func (r *Router) InterfaceFinder() control.InterfaceFinder {
  798. return &r.interfaceFinder
  799. }
  800. func (r *Router) AutoDetectInterface() bool {
  801. return r.autoDetectInterface
  802. }
  803. func (r *Router) AutoDetectInterfaceFunc() control.Func {
  804. if r.platformInterface != nil {
  805. return r.platformInterface.AutoDetectInterfaceControl()
  806. } else {
  807. return control.BindToInterfaceFunc(r.InterfaceFinder(), func(network string, address string) (interfaceName string, interfaceIndex int) {
  808. remoteAddr := M.ParseSocksaddr(address).Addr
  809. if C.IsLinux {
  810. return r.InterfaceMonitor().DefaultInterfaceName(remoteAddr), -1
  811. } else {
  812. return "", r.InterfaceMonitor().DefaultInterfaceIndex(remoteAddr)
  813. }
  814. })
  815. }
  816. }
  817. func (r *Router) DefaultInterface() string {
  818. return r.defaultInterface
  819. }
  820. func (r *Router) DefaultMark() int {
  821. return r.defaultMark
  822. }
  823. func (r *Router) Rules() []adapter.Rule {
  824. return r.rules
  825. }
  826. func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor {
  827. return r.networkMonitor
  828. }
  829. func (r *Router) InterfaceMonitor() tun.DefaultInterfaceMonitor {
  830. return r.interfaceMonitor
  831. }
  832. func (r *Router) PackageManager() tun.PackageManager {
  833. return r.packageManager
  834. }
  835. func (r *Router) TimeFunc() func() time.Time {
  836. if r.timeService == nil {
  837. return nil
  838. }
  839. return r.timeService.TimeFunc()
  840. }
  841. func (r *Router) ClashServer() adapter.ClashServer {
  842. return r.clashServer
  843. }
  844. func (r *Router) SetClashServer(server adapter.ClashServer) {
  845. r.clashServer = server
  846. }
  847. func (r *Router) V2RayServer() adapter.V2RayServer {
  848. return r.v2rayServer
  849. }
  850. func (r *Router) SetV2RayServer(server adapter.V2RayServer) {
  851. r.v2rayServer = server
  852. }
  853. func hasRule(rules []option.Rule, cond func(rule option.DefaultRule) bool) bool {
  854. for _, rule := range rules {
  855. switch rule.Type {
  856. case C.RuleTypeDefault:
  857. if cond(rule.DefaultOptions) {
  858. return true
  859. }
  860. case C.RuleTypeLogical:
  861. for _, subRule := range rule.LogicalOptions.Rules {
  862. if cond(subRule) {
  863. return true
  864. }
  865. }
  866. }
  867. }
  868. return false
  869. }
  870. func hasDNSRule(rules []option.DNSRule, cond func(rule option.DefaultDNSRule) bool) bool {
  871. for _, rule := range rules {
  872. switch rule.Type {
  873. case C.RuleTypeDefault:
  874. if cond(rule.DefaultOptions) {
  875. return true
  876. }
  877. case C.RuleTypeLogical:
  878. for _, subRule := range rule.LogicalOptions.Rules {
  879. if cond(subRule) {
  880. return true
  881. }
  882. }
  883. }
  884. }
  885. return false
  886. }
  887. func isGeoIPRule(rule option.DefaultRule) bool {
  888. return len(rule.SourceGeoIP) > 0 && common.Any(rule.SourceGeoIP, notPrivateNode) || len(rule.GeoIP) > 0 && common.Any(rule.GeoIP, notPrivateNode)
  889. }
  890. func isGeoIPDNSRule(rule option.DefaultDNSRule) bool {
  891. return len(rule.SourceGeoIP) > 0 && common.Any(rule.SourceGeoIP, notPrivateNode)
  892. }
  893. func isGeositeRule(rule option.DefaultRule) bool {
  894. return len(rule.Geosite) > 0
  895. }
  896. func isGeositeDNSRule(rule option.DefaultDNSRule) bool {
  897. return len(rule.Geosite) > 0
  898. }
  899. func isProcessRule(rule option.DefaultRule) bool {
  900. return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
  901. }
  902. func isProcessDNSRule(rule option.DefaultDNSRule) bool {
  903. return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
  904. }
  905. func notPrivateNode(code string) bool {
  906. return code != "private"
  907. }
  908. func (r *Router) prepareGeoIPDatabase() error {
  909. var geoPath string
  910. if r.geoIPOptions.Path != "" {
  911. geoPath = r.geoIPOptions.Path
  912. } else {
  913. geoPath = "geoip.db"
  914. if foundPath, loaded := C.FindPath(geoPath); loaded {
  915. geoPath = foundPath
  916. }
  917. }
  918. geoPath = C.BasePath(geoPath)
  919. if !rw.FileExists(geoPath) {
  920. r.logger.Warn("geoip database not exists: ", geoPath)
  921. var err error
  922. for attempts := 0; attempts < 3; attempts++ {
  923. err = r.downloadGeoIPDatabase(geoPath)
  924. if err == nil {
  925. break
  926. }
  927. r.logger.Error("download geoip database: ", err)
  928. os.Remove(geoPath)
  929. // time.Sleep(10 * time.Second)
  930. }
  931. if err != nil {
  932. return err
  933. }
  934. }
  935. geoReader, codes, err := geoip.Open(geoPath)
  936. if err != nil {
  937. return E.Cause(err, "open geoip database")
  938. }
  939. r.logger.Info("loaded geoip database: ", len(codes), " codes")
  940. r.geoIPReader = geoReader
  941. return nil
  942. }
  943. func (r *Router) prepareGeositeDatabase() error {
  944. var geoPath string
  945. if r.geositeOptions.Path != "" {
  946. geoPath = r.geositeOptions.Path
  947. } else {
  948. geoPath = "geosite.db"
  949. if foundPath, loaded := C.FindPath(geoPath); loaded {
  950. geoPath = foundPath
  951. }
  952. }
  953. geoPath = C.BasePath(geoPath)
  954. if !rw.FileExists(geoPath) {
  955. r.logger.Warn("geosite database not exists: ", geoPath)
  956. var err error
  957. for attempts := 0; attempts < 3; attempts++ {
  958. err = r.downloadGeositeDatabase(geoPath)
  959. if err == nil {
  960. break
  961. }
  962. r.logger.Error("download geosite database: ", err)
  963. os.Remove(geoPath)
  964. // time.Sleep(10 * time.Second)
  965. }
  966. if err != nil {
  967. return err
  968. }
  969. }
  970. geoReader, codes, err := geosite.Open(geoPath)
  971. if err == nil {
  972. r.logger.Info("loaded geosite database: ", len(codes), " codes")
  973. r.geositeReader = geoReader
  974. } else {
  975. return E.Cause(err, "open geosite database")
  976. }
  977. return nil
  978. }
  979. func (r *Router) downloadGeoIPDatabase(savePath string) error {
  980. var downloadURL string
  981. if r.geoIPOptions.DownloadURL != "" {
  982. downloadURL = r.geoIPOptions.DownloadURL
  983. } else {
  984. downloadURL = "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db"
  985. }
  986. r.logger.Info("downloading geoip database")
  987. var detour adapter.Outbound
  988. if r.geoIPOptions.DownloadDetour != "" {
  989. outbound, loaded := r.Outbound(r.geoIPOptions.DownloadDetour)
  990. if !loaded {
  991. return E.New("detour outbound not found: ", r.geoIPOptions.DownloadDetour)
  992. }
  993. detour = outbound
  994. } else {
  995. detour = r.defaultOutboundForConnection
  996. }
  997. if parentDir := filepath.Dir(savePath); parentDir != "" {
  998. os.MkdirAll(parentDir, 0o755)
  999. }
  1000. saveFile, err := os.OpenFile(savePath, os.O_CREATE|os.O_WRONLY, 0o644)
  1001. if err != nil {
  1002. return E.Cause(err, "open output file: ", downloadURL)
  1003. }
  1004. defer saveFile.Close()
  1005. httpClient := &http.Client{
  1006. Transport: &http.Transport{
  1007. ForceAttemptHTTP2: true,
  1008. TLSHandshakeTimeout: 5 * time.Second,
  1009. DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
  1010. return detour.DialContext(ctx, network, M.ParseSocksaddr(addr))
  1011. },
  1012. },
  1013. }
  1014. defer httpClient.CloseIdleConnections()
  1015. response, err := httpClient.Get(downloadURL)
  1016. if err != nil {
  1017. return err
  1018. }
  1019. defer response.Body.Close()
  1020. _, err = io.Copy(saveFile, response.Body)
  1021. return err
  1022. }
  1023. func (r *Router) downloadGeositeDatabase(savePath string) error {
  1024. var downloadURL string
  1025. if r.geositeOptions.DownloadURL != "" {
  1026. downloadURL = r.geositeOptions.DownloadURL
  1027. } else {
  1028. downloadURL = "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db"
  1029. }
  1030. r.logger.Info("downloading geosite database")
  1031. var detour adapter.Outbound
  1032. if r.geositeOptions.DownloadDetour != "" {
  1033. outbound, loaded := r.Outbound(r.geositeOptions.DownloadDetour)
  1034. if !loaded {
  1035. return E.New("detour outbound not found: ", r.geositeOptions.DownloadDetour)
  1036. }
  1037. detour = outbound
  1038. } else {
  1039. detour = r.defaultOutboundForConnection
  1040. }
  1041. if parentDir := filepath.Dir(savePath); parentDir != "" {
  1042. os.MkdirAll(parentDir, 0o755)
  1043. }
  1044. saveFile, err := os.OpenFile(savePath, os.O_CREATE|os.O_WRONLY, 0o644)
  1045. if err != nil {
  1046. return E.Cause(err, "open output file: ", downloadURL)
  1047. }
  1048. defer saveFile.Close()
  1049. httpClient := &http.Client{
  1050. Transport: &http.Transport{
  1051. ForceAttemptHTTP2: true,
  1052. TLSHandshakeTimeout: 5 * time.Second,
  1053. DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
  1054. return detour.DialContext(ctx, network, M.ParseSocksaddr(addr))
  1055. },
  1056. },
  1057. }
  1058. defer httpClient.CloseIdleConnections()
  1059. response, err := httpClient.Get(downloadURL)
  1060. if err != nil {
  1061. return err
  1062. }
  1063. defer response.Body.Close()
  1064. _, err = io.Copy(saveFile, response.Body)
  1065. return err
  1066. }
  1067. func (r *Router) OnPackagesUpdated(packages int, sharedUsers int) {
  1068. r.logger.Info("updated packages list: ", packages, " packages, ", sharedUsers, " shared users")
  1069. }
  1070. func (r *Router) NewError(ctx context.Context, err error) {
  1071. common.Close(err)
  1072. if E.IsClosedOrCanceled(err) {
  1073. r.logger.DebugContext(ctx, "connection closed: ", err)
  1074. return
  1075. }
  1076. r.logger.ErrorContext(ctx, err)
  1077. }
  1078. func (r *Router) notifyNetworkUpdate(int) error {
  1079. if C.IsAndroid {
  1080. var vpnStatus string
  1081. if r.interfaceMonitor.AndroidVPNEnabled() {
  1082. vpnStatus = "enabled"
  1083. } else {
  1084. vpnStatus = "disabled"
  1085. }
  1086. r.logger.Info("updated default interface ", r.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", r.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()), ", vpn ", vpnStatus)
  1087. } else {
  1088. r.logger.Info("updated default interface ", r.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", r.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()))
  1089. }
  1090. for _, outbound := range r.outbounds {
  1091. listener, isListener := outbound.(adapter.InterfaceUpdateListener)
  1092. if isListener {
  1093. err := listener.InterfaceUpdated()
  1094. if err != nil {
  1095. return err
  1096. }
  1097. }
  1098. }
  1099. if conntrack.Enabled {
  1100. conntrack.Close()
  1101. }
  1102. return nil
  1103. }