router.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package rules
  2. import (
  3. "errors"
  4. "time"
  5. "github.com/v2ray/v2ray-core/app/router"
  6. "github.com/v2ray/v2ray-core/common/collect"
  7. v2net "github.com/v2ray/v2ray-core/common/net"
  8. )
  9. var (
  10. InvalidRule = errors.New("Invalid Rule")
  11. NoRuleApplicable = errors.New("No rule applicable")
  12. )
  13. type cacheEntry struct {
  14. tag string
  15. err error
  16. validUntil time.Time
  17. }
  18. func newCacheEntry(tag string, err error) *cacheEntry {
  19. this := &cacheEntry{
  20. tag: tag,
  21. err: err,
  22. }
  23. this.Extend()
  24. return this
  25. }
  26. func (this *cacheEntry) IsValid() bool {
  27. return this.validUntil.Before(time.Now())
  28. }
  29. func (this *cacheEntry) Extend() {
  30. this.validUntil = time.Now().Add(time.Hour)
  31. }
  32. type Router struct {
  33. rules []*Rule
  34. cache *collect.ValidityMap
  35. }
  36. func NewRouter() *Router {
  37. return &Router{
  38. rules: make([]*Rule, 0, 16),
  39. cache: collect.NewValidityMap(3600),
  40. }
  41. }
  42. func (this *Router) AddRule(rule *Rule) *Router {
  43. this.rules = append(this.rules, rule)
  44. return this
  45. }
  46. func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
  47. for _, rule := range this.rules {
  48. if rule.Apply(dest) {
  49. return rule.Tag, nil
  50. }
  51. }
  52. return "", NoRuleApplicable
  53. }
  54. func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
  55. rawEntry := this.cache.Get(dest)
  56. if rawEntry == nil {
  57. tag, err := this.takeDetourWithoutCache(dest)
  58. this.cache.Set(dest, newCacheEntry(tag, err))
  59. return tag, err
  60. }
  61. entry := rawEntry.(*cacheEntry)
  62. return entry.tag, entry.err
  63. }
  64. type RouterFactory struct {
  65. }
  66. func (this *RouterFactory) Create(rawConfig interface{}) (router.Router, error) {
  67. config := rawConfig.(*RouterRuleConfig)
  68. rules := config.Rules()
  69. router := NewRouter()
  70. for _, rule := range rules {
  71. if rule == nil {
  72. return nil, InvalidRule
  73. }
  74. router.AddRule(rule)
  75. }
  76. return router, nil
  77. }
  78. func init() {
  79. router.RegisterRouter("rules", &RouterFactory{})
  80. }