router.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package rules
  2. import (
  3. "errors"
  4. "v2ray.com/core/app"
  5. "v2ray.com/core/app/dns"
  6. "v2ray.com/core/app/router"
  7. "v2ray.com/core/common/log"
  8. v2net "v2ray.com/core/common/net"
  9. )
  10. var (
  11. ErrInvalidRule = errors.New("Invalid Rule")
  12. ErrNoRuleApplicable = errors.New("No rule applicable")
  13. )
  14. type Router struct {
  15. domainStrategy Config_DomainStrategy
  16. rules []Rule
  17. cache *RoutingTable
  18. dnsServer dns.Server
  19. }
  20. func NewRouter(config *Config, space app.Space) *Router {
  21. r := &Router{
  22. domainStrategy: config.DomainStrategy,
  23. cache: NewRoutingTable(),
  24. rules: make([]Rule, len(config.Rule)),
  25. }
  26. space.InitializeApplication(func() error {
  27. for idx, rule := range config.Rule {
  28. r.rules[idx].Tag = rule.Tag
  29. cond, err := rule.BuildCondition()
  30. if err != nil {
  31. return err
  32. }
  33. r.rules[idx].Condition = cond
  34. }
  35. if !space.HasApp(dns.APP_ID) {
  36. log.Error("DNS: Router is not found in the space.")
  37. return app.ErrMissingApplication
  38. }
  39. r.dnsServer = space.GetApp(dns.APP_ID).(dns.Server)
  40. return nil
  41. })
  42. return r
  43. }
  44. func (this *Router) Release() {
  45. }
  46. // Private: Visible for testing.
  47. func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
  48. ips := this.dnsServer.Get(dest.Address.Domain())
  49. if len(ips) == 0 {
  50. return nil
  51. }
  52. dests := make([]v2net.Destination, len(ips))
  53. for idx, ip := range ips {
  54. if dest.Network == v2net.Network_TCP {
  55. dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port)
  56. } else {
  57. dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port)
  58. }
  59. }
  60. return dests
  61. }
  62. func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
  63. for _, rule := range this.rules {
  64. if rule.Apply(dest) {
  65. return rule.Tag, nil
  66. }
  67. }
  68. if this.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
  69. log.Info("Router: Looking up IP for ", dest)
  70. ipDests := this.ResolveIP(dest)
  71. if ipDests != nil {
  72. for _, ipDest := range ipDests {
  73. log.Info("Router: Trying IP ", ipDest)
  74. for _, rule := range this.rules {
  75. if rule.Apply(ipDest) {
  76. return rule.Tag, nil
  77. }
  78. }
  79. }
  80. }
  81. }
  82. return "", ErrNoRuleApplicable
  83. }
  84. func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
  85. destStr := dest.String()
  86. found, tag, err := this.cache.Get(destStr)
  87. if !found {
  88. tag, err := this.takeDetourWithoutCache(dest)
  89. this.cache.Set(destStr, tag, err)
  90. return tag, err
  91. }
  92. return tag, err
  93. }
  94. type RouterFactory struct {
  95. }
  96. func (this *RouterFactory) Create(rawConfig interface{}, space app.Space) (router.Router, error) {
  97. return NewRouter(rawConfig.(*Config), space), nil
  98. }
  99. func init() {
  100. router.RegisterRouter("rules", &RouterFactory{})
  101. }