server.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package dns
  2. import (
  3. "net"
  4. "sync"
  5. "time"
  6. "github.com/v2ray/v2ray-core/app"
  7. "github.com/v2ray/v2ray-core/app/dispatcher"
  8. "github.com/miekg/dns"
  9. )
  10. const (
  11. QueryTimeout = time.Second * 2
  12. )
  13. type DomainRecord struct {
  14. A *ARecord
  15. }
  16. type CacheServer struct {
  17. sync.RWMutex
  18. records map[string]*DomainRecord
  19. servers []NameServer
  20. }
  21. func NewCacheServer(space app.Space, config *Config) *CacheServer {
  22. server := &CacheServer{
  23. records: make(map[string]*DomainRecord),
  24. servers: make([]NameServer, len(config.NameServers)),
  25. }
  26. dispatcher := space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
  27. for idx, ns := range config.NameServers {
  28. server.servers[idx] = NewUDPNameServer(ns, dispatcher)
  29. }
  30. return server
  31. }
  32. //@Private
  33. func (this *CacheServer) GetCached(domain string) []net.IP {
  34. this.RLock()
  35. defer this.RUnlock()
  36. if record, found := this.records[domain]; found && record.A.Expire.After(time.Now()) {
  37. return record.A.IPs
  38. }
  39. return nil
  40. }
  41. func (this *CacheServer) Get(context app.Context, domain string) []net.IP {
  42. domain = dns.Fqdn(domain)
  43. ips := this.GetCached(domain)
  44. if ips != nil {
  45. return ips
  46. }
  47. for _, server := range this.servers {
  48. response := server.QueryA(domain)
  49. select {
  50. case a := <-response:
  51. this.Lock()
  52. this.records[domain] = &DomainRecord{
  53. A: a,
  54. }
  55. this.Unlock()
  56. return a.IPs
  57. case <-time.Tick(QueryTimeout):
  58. }
  59. }
  60. return nil
  61. }