router.go 24 KB

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