router.go 28 KB

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