|  | @@ -2,12 +2,10 @@ package rules
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  import (
 |  |  import (
 | 
											
												
													
														|  |  	"errors"
 |  |  	"errors"
 | 
											
												
													
														|  | -	"time"
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	"github.com/v2ray/v2ray-core/app"
 |  |  	"github.com/v2ray/v2ray-core/app"
 | 
											
												
													
														|  |  	"github.com/v2ray/v2ray-core/app/dns"
 |  |  	"github.com/v2ray/v2ray-core/app/dns"
 | 
											
												
													
														|  |  	"github.com/v2ray/v2ray-core/app/router"
 |  |  	"github.com/v2ray/v2ray-core/app/router"
 | 
											
												
													
														|  | -	"github.com/v2ray/v2ray-core/common/collect"
 |  | 
 | 
											
												
													
														|  |  	"github.com/v2ray/v2ray-core/common/log"
 |  |  	"github.com/v2ray/v2ray-core/common/log"
 | 
											
												
													
														|  |  	v2net "github.com/v2ray/v2ray-core/common/net"
 |  |  	v2net "github.com/v2ray/v2ray-core/common/net"
 | 
											
												
													
														|  |  )
 |  |  )
 | 
											
										
											
												
													
														|  | @@ -17,43 +15,16 @@ var (
 | 
											
												
													
														|  |  	ErrorNoRuleApplicable = errors.New("No rule applicable")
 |  |  	ErrorNoRuleApplicable = errors.New("No rule applicable")
 | 
											
												
													
														|  |  )
 |  |  )
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -type cacheEntry struct {
 |  | 
 | 
											
												
													
														|  | -	tag        string
 |  | 
 | 
											
												
													
														|  | -	err        error
 |  | 
 | 
											
												
													
														|  | -	validUntil time.Time
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -func newCacheEntry(tag string, err error) *cacheEntry {
 |  | 
 | 
											
												
													
														|  | -	this := &cacheEntry{
 |  | 
 | 
											
												
													
														|  | -		tag: tag,
 |  | 
 | 
											
												
													
														|  | -		err: err,
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -	this.Extend()
 |  | 
 | 
											
												
													
														|  | -	return this
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -func (this *cacheEntry) IsValid() bool {
 |  | 
 | 
											
												
													
														|  | -	return this.validUntil.Before(time.Now())
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -func (this *cacheEntry) Extend() {
 |  | 
 | 
											
												
													
														|  | -	this.validUntil = time.Now().Add(time.Hour)
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -func (this *cacheEntry) Release() {
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  type Router struct {
 |  |  type Router struct {
 | 
											
												
													
														|  |  	config    *RouterRuleConfig
 |  |  	config    *RouterRuleConfig
 | 
											
												
													
														|  | -	cache     *collect.ValidityMap
 |  | 
 | 
											
												
													
														|  | 
 |  | +	cache     *RoutingTable
 | 
											
												
													
														|  |  	dnsServer dns.Server
 |  |  	dnsServer dns.Server
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func NewRouter(config *RouterRuleConfig, space app.Space) *Router {
 |  |  func NewRouter(config *RouterRuleConfig, space app.Space) *Router {
 | 
											
												
													
														|  |  	r := &Router{
 |  |  	r := &Router{
 | 
											
												
													
														|  |  		config: config,
 |  |  		config: config,
 | 
											
												
													
														|  | -		cache:  collect.NewValidityMap(3600),
 |  | 
 | 
											
												
													
														|  | 
 |  | +		cache:  NewRoutingTable(),
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  	space.InitializeApplication(func() error {
 |  |  	space.InitializeApplication(func() error {
 | 
											
												
													
														|  |  		if !space.HasApp(dns.APP_ID) {
 |  |  		if !space.HasApp(dns.APP_ID) {
 | 
											
										
											
												
													
														|  | @@ -113,14 +84,13 @@ func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, erro
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
 |  |  func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
 | 
											
												
													
														|  |  	destStr := dest.String()
 |  |  	destStr := dest.String()
 | 
											
												
													
														|  | -	rawEntry := this.cache.Get(destStr)
 |  | 
 | 
											
												
													
														|  | -	if rawEntry == nil {
 |  | 
 | 
											
												
													
														|  | 
 |  | +	found, tag, err := this.cache.Get(destStr)
 | 
											
												
													
														|  | 
 |  | +	if !found {
 | 
											
												
													
														|  |  		tag, err := this.takeDetourWithoutCache(dest)
 |  |  		tag, err := this.takeDetourWithoutCache(dest)
 | 
											
												
													
														|  | -		this.cache.Set(destStr, newCacheEntry(tag, err))
 |  | 
 | 
											
												
													
														|  | 
 |  | +		this.cache.Set(destStr, tag, err)
 | 
											
												
													
														|  |  		return tag, err
 |  |  		return tag, err
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | -	entry := rawEntry.(*cacheEntry)
 |  | 
 | 
											
												
													
														|  | -	return entry.tag, entry.err
 |  | 
 | 
											
												
													
														|  | 
 |  | +	return tag, err
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  type RouterFactory struct {
 |  |  type RouterFactory struct {
 |