router.go 22 KB

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