| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 | 
							- package dns
 
- import (
 
- 	"net"
 
- 	"sync"
 
- 	"time"
 
- 	"github.com/v2ray/v2ray-core/app"
 
- )
 
- type entry struct {
 
- 	domain     string
 
- 	ip         net.IP
 
- 	validUntil time.Time
 
- }
 
- func newEntry(domain string, ip net.IP) *entry {
 
- 	this := &entry{
 
- 		domain: domain,
 
- 		ip:     ip,
 
- 	}
 
- 	this.Extend()
 
- 	return this
 
- }
 
- func (this *entry) IsValid() bool {
 
- 	return this.validUntil.After(time.Now())
 
- }
 
- func (this *entry) Extend() {
 
- 	this.validUntil = time.Now().Add(time.Hour)
 
- }
 
- type DnsCache struct {
 
- 	sync.RWMutex
 
- 	cache  map[string]*entry
 
- 	config CacheConfig
 
- }
 
- func NewCache(config CacheConfig) *DnsCache {
 
- 	cache := &DnsCache{
 
- 		cache:  make(map[string]*entry),
 
- 		config: config,
 
- 	}
 
- 	go cache.cleanup()
 
- 	return cache
 
- }
 
- func (this *DnsCache) cleanup() {
 
- 	for range time.Tick(60 * time.Second) {
 
- 		entry2Remove := make([]*entry, 0, 128)
 
- 		this.RLock()
 
- 		for _, entry := range this.cache {
 
- 			if !entry.IsValid() {
 
- 				entry2Remove = append(entry2Remove, entry)
 
- 			}
 
- 		}
 
- 		this.RUnlock()
 
- 		for _, entry := range entry2Remove {
 
- 			if !entry.IsValid() {
 
- 				this.Lock()
 
- 				delete(this.cache, entry.domain)
 
- 				this.Unlock()
 
- 			}
 
- 		}
 
- 	}
 
- }
 
- func (this *DnsCache) Add(context app.Context, domain string, ip net.IP) {
 
- 	callerTag := context.CallerTag()
 
- 	if !this.config.IsTrustedSource(callerTag) {
 
- 		return
 
- 	}
 
- 	this.RLock()
 
- 	entry, found := this.cache[domain]
 
- 	this.RUnlock()
 
- 	if found {
 
- 		entry.ip = ip
 
- 		entry.Extend()
 
- 	} else {
 
- 		this.Lock()
 
- 		this.cache[domain] = newEntry(domain, ip)
 
- 		this.Unlock()
 
- 	}
 
- }
 
- func (this *DnsCache) Get(context app.Context, domain string) net.IP {
 
- 	this.RLock()
 
- 	entry, found := this.cache[domain]
 
- 	this.RUnlock()
 
- 	if found {
 
- 		return entry.ip
 
- 	}
 
- 	return nil
 
- }
 
 
  |