router.go 27 KB

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