router.go 31 KB

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