router.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package rules
  2. import (
  3. "errors"
  4. "time"
  5. "github.com/v2ray/v2ray-core/app"
  6. "github.com/v2ray/v2ray-core/app/dns"
  7. "github.com/v2ray/v2ray-core/app/router"
  8. "github.com/v2ray/v2ray-core/common/collect"
  9. "github.com/v2ray/v2ray-core/common/log"
  10. v2net "github.com/v2ray/v2ray-core/common/net"
  11. )
  12. var (
  13. ErrorInvalidRule = errors.New("Invalid Rule")
  14. ErrorNoRuleApplicable = errors.New("No rule applicable")
  15. )
  16. type cacheEntry struct {
  17. tag string
  18. err error
  19. validUntil time.Time
  20. }
  21. func newCacheEntry(tag string, err error) *cacheEntry {
  22. this := &cacheEntry{
  23. tag: tag,
  24. err: err,
  25. }
  26. this.Extend()
  27. return this
  28. }
  29. func (this *cacheEntry) IsValid() bool {
  30. return this.validUntil.Before(time.Now())
  31. }
  32. func (this *cacheEntry) Extend() {
  33. this.validUntil = time.Now().Add(time.Hour)
  34. }
  35. type Router struct {
  36. config *RouterRuleConfig
  37. cache *collect.ValidityMap
  38. space app.Space
  39. }
  40. func NewRouter(config *RouterRuleConfig, space app.Space) *Router {
  41. return &Router{
  42. config: config,
  43. cache: collect.NewValidityMap(3600),
  44. space: space,
  45. }
  46. }
  47. // @Private
  48. func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
  49. dnsServer := this.space.GetApp(dns.APP_ID).(dns.Server)
  50. ips := dnsServer.Get(dest.Address().Domain())
  51. if len(ips) == 0 {
  52. return nil
  53. }
  54. dests := make([]v2net.Destination, len(ips))
  55. for idx, ip := range ips {
  56. if dest.IsTCP() {
  57. dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port())
  58. } else {
  59. dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port())
  60. }
  61. }
  62. return dests
  63. }
  64. func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
  65. for _, rule := range this.config.Rules {
  66. if rule.Apply(dest) {
  67. return rule.Tag, nil
  68. }
  69. }
  70. if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().IsDomain() {
  71. log.Info("Router: Looking up IP for ", dest)
  72. ipDests := this.ResolveIP(dest)
  73. if ipDests != nil {
  74. for _, ipDest := range ipDests {
  75. log.Info("Router: Trying IP ", ipDest)
  76. for _, rule := range this.config.Rules {
  77. if rule.Apply(ipDest) {
  78. return rule.Tag, nil
  79. }
  80. }
  81. }
  82. }
  83. }
  84. return "", ErrorNoRuleApplicable
  85. }
  86. func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
  87. rawEntry := this.cache.Get(dest)
  88. if rawEntry == nil {
  89. tag, err := this.takeDetourWithoutCache(dest)
  90. this.cache.Set(dest, newCacheEntry(tag, err))
  91. return tag, err
  92. }
  93. entry := rawEntry.(*cacheEntry)
  94. return entry.tag, entry.err
  95. }
  96. type RouterFactory struct {
  97. }
  98. func (this *RouterFactory) Create(rawConfig interface{}, space app.Space) (router.Router, error) {
  99. return NewRouter(rawConfig.(*RouterRuleConfig), space), nil
  100. }
  101. func init() {
  102. router.RegisterRouter("rules", &RouterFactory{})
  103. }