router.go 21 KB

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