client.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package localdns
  2. import (
  3. "github.com/v2fly/v2ray-core/v4/common/net"
  4. "github.com/v2fly/v2ray-core/v4/features/dns"
  5. )
  6. // Client is an implementation of dns.Client, which queries localhost for DNS.
  7. type Client struct{}
  8. // Type implements common.HasType.
  9. func (*Client) Type() interface{} {
  10. return dns.ClientType()
  11. }
  12. // Start implements common.Runnable.
  13. func (*Client) Start() error { return nil }
  14. // Close implements common.Closable.
  15. func (*Client) Close() error { return nil }
  16. // LookupIP implements Client.
  17. func (*Client) LookupIP(host string, option dns.IPOption) ([]net.IP, error) {
  18. ips, err := net.LookupIP(host)
  19. if err != nil {
  20. return nil, err
  21. }
  22. parsedIPs := make([]net.IP, 0, len(ips))
  23. ipv4 := make([]net.IP, 0, len(ips))
  24. ipv6 := make([]net.IP, 0, len(ips))
  25. for _, ip := range ips {
  26. parsed := net.IPAddress(ip)
  27. if parsed != nil {
  28. parsedIPs = append(parsedIPs, parsed.IP())
  29. }
  30. if len(ip) == net.IPv4len {
  31. ipv4 = append(ipv4, ip)
  32. }
  33. if len(ip) == net.IPv6len {
  34. ipv6 = append(ipv6, ip)
  35. }
  36. }
  37. switch {
  38. case option.IPv4Enable && option.IPv6Enable:
  39. if len(parsedIPs) > 0 {
  40. return parsedIPs, nil
  41. }
  42. case option.IPv4Enable:
  43. if len(ipv4) > 0 {
  44. return ipv4, nil
  45. }
  46. case option.IPv6Enable:
  47. if len(ipv6) > 0 {
  48. return ipv6, nil
  49. }
  50. }
  51. return nil, dns.ErrEmptyResponse
  52. }
  53. // New create a new dns.Client that queries localhost for DNS.
  54. func New() *Client {
  55. return &Client{}
  56. }