|  | @@ -11,6 +11,7 @@ import (
 | 
											
												
													
														|  |  	"v2ray.com/core"
 |  |  	"v2ray.com/core"
 | 
											
												
													
														|  |  	"v2ray.com/core/common"
 |  |  	"v2ray.com/core/common"
 | 
											
												
													
														|  |  	"v2ray.com/core/common/net"
 |  |  	"v2ray.com/core/common/net"
 | 
											
												
													
														|  | 
 |  | +	"v2ray.com/core/common/signal"
 | 
											
												
													
														|  |  )
 |  |  )
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  const (
 |  |  const (
 | 
											
										
											
												
													
														|  | @@ -37,6 +38,7 @@ type Server struct {
 | 
											
												
													
														|  |  	hosts   map[string]net.IP
 |  |  	hosts   map[string]net.IP
 | 
											
												
													
														|  |  	records map[string]*DomainRecord
 |  |  	records map[string]*DomainRecord
 | 
											
												
													
														|  |  	servers []NameServer
 |  |  	servers []NameServer
 | 
											
												
													
														|  | 
 |  | +	task    *signal.PeriodicTask
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func New(ctx context.Context, config *Config) (*Server, error) {
 |  |  func New(ctx context.Context, config *Config) (*Server, error) {
 | 
											
										
											
												
													
														|  | @@ -45,6 +47,13 @@ func New(ctx context.Context, config *Config) (*Server, error) {
 | 
											
												
													
														|  |  		servers: make([]NameServer, len(config.NameServers)),
 |  |  		servers: make([]NameServer, len(config.NameServers)),
 | 
											
												
													
														|  |  		hosts:   config.GetInternalHosts(),
 |  |  		hosts:   config.GetInternalHosts(),
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +	server.task = &signal.PeriodicTask{
 | 
											
												
													
														|  | 
 |  | +		Interval: time.Minute * 10,
 | 
											
												
													
														|  | 
 |  | +		Execute: func() error {
 | 
											
												
													
														|  | 
 |  | +			server.cleanup()
 | 
											
												
													
														|  | 
 |  | +			return nil
 | 
											
												
													
														|  | 
 |  | +		},
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  |  	v := core.FromContext(ctx)
 |  |  	v := core.FromContext(ctx)
 | 
											
												
													
														|  |  	if v == nil {
 |  |  	if v == nil {
 | 
											
												
													
														|  |  		return nil, newError("V is not in context.")
 |  |  		return nil, newError("V is not in context.")
 | 
											
										
											
												
													
														|  | @@ -75,16 +84,14 @@ func New(ctx context.Context, config *Config) (*Server, error) {
 | 
											
												
													
														|  |  	return server, nil
 |  |  	return server, nil
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (*Server) Interface() interface{} {
 |  | 
 | 
											
												
													
														|  | -	return (*Server)(nil)
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | 
 |  | +// Start implements common.Runnable.
 | 
											
												
													
														|  |  func (s *Server) Start() error {
 |  |  func (s *Server) Start() error {
 | 
											
												
													
														|  | -	return nil
 |  | 
 | 
											
												
													
														|  | 
 |  | +	return s.task.Start()
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (*Server) Close() error {
 |  | 
 | 
											
												
													
														|  | -	return nil
 |  | 
 | 
											
												
													
														|  | 
 |  | +// Close implements common.Runnable.
 | 
											
												
													
														|  | 
 |  | +func (s *Server) Close() error {
 | 
											
												
													
														|  | 
 |  | +	return s.task.Close()
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func (s *Server) GetCached(domain string) []net.IP {
 |  |  func (s *Server) GetCached(domain string) []net.IP {
 | 
											
										
											
												
													
														|  | @@ -98,18 +105,12 @@ func (s *Server) GetCached(domain string) []net.IP {
 | 
											
												
													
														|  |  	return nil
 |  |  	return nil
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (s *Server) tryCleanup() {
 |  | 
 | 
											
												
													
														|  | 
 |  | +func (s *Server) cleanup() {
 | 
											
												
													
														|  |  	s.Lock()
 |  |  	s.Lock()
 | 
											
												
													
														|  |  	defer s.Unlock()
 |  |  	defer s.Unlock()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	if len(s.records) > 256 {
 |  | 
 | 
											
												
													
														|  | -		domains := make([]string, 0, 256)
 |  | 
 | 
											
												
													
														|  | -		for d, r := range s.records {
 |  | 
 | 
											
												
													
														|  | -			if r.Expired() {
 |  | 
 | 
											
												
													
														|  | -				domains = append(domains, d)
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | -		}
 |  | 
 | 
											
												
													
														|  | -		for _, d := range domains {
 |  | 
 | 
											
												
													
														|  | 
 |  | +	for d, r := range s.records {
 | 
											
												
													
														|  | 
 |  | +		if r.Expired() {
 | 
											
												
													
														|  |  			delete(s.records, d)
 |  |  			delete(s.records, d)
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
										
											
												
													
														|  | @@ -126,8 +127,6 @@ func (s *Server) LookupIP(domain string) ([]net.IP, error) {
 | 
											
												
													
														|  |  		return ips, nil
 |  |  		return ips, nil
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	s.tryCleanup()
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  	for _, server := range s.servers {
 |  |  	for _, server := range s.servers {
 | 
											
												
													
														|  |  		response := server.QueryA(domain)
 |  |  		response := server.QueryA(domain)
 | 
											
												
													
														|  |  		select {
 |  |  		select {
 |