router.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. ErrorInvalidRule = errors.New("Invalid Rule")
  11. ErrorNoRuleApplicable = 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. config *RouterRuleConfig
  34. cache *collect.ValidityMap
  35. }
  36. func NewRouter(config *RouterRuleConfig) *Router {
  37. return &Router{
  38. config: config,
  39. cache: collect.NewValidityMap(3600),
  40. }
  41. }
  42. func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
  43. for _, rule := range this.config.Rules {
  44. if rule.Apply(dest) {
  45. return rule.Tag, nil
  46. }
  47. }
  48. return "", ErrorNoRuleApplicable
  49. }
  50. func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
  51. rawEntry := this.cache.Get(dest)
  52. if rawEntry == nil {
  53. tag, err := this.takeDetourWithoutCache(dest)
  54. this.cache.Set(dest, newCacheEntry(tag, err))
  55. return tag, err
  56. }
  57. entry := rawEntry.(*cacheEntry)
  58. return entry.tag, entry.err
  59. }
  60. type RouterFactory struct {
  61. }
  62. func (this *RouterFactory) Create(rawConfig interface{}) (router.Router, error) {
  63. return NewRouter(rawConfig.(*RouterRuleConfig)), nil
  64. }
  65. func init() {
  66. router.RegisterRouter("rules", &RouterFactory{})
  67. }