router.go 2.6 KB

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