github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/features/dns/localdns/client.go (about)

     1  package localdns
     2  
     3  import (
     4  	"github.com/v2fly/v2ray-core/v5/common/net"
     5  	"github.com/v2fly/v2ray-core/v5/features/dns"
     6  )
     7  
     8  // Client is an implementation of dns.Client, which queries localhost for DNS.
     9  type Client struct{}
    10  
    11  // Type implements common.HasType.
    12  func (*Client) Type() interface{} {
    13  	return dns.ClientType()
    14  }
    15  
    16  // Start implements common.Runnable.
    17  func (*Client) Start() error { return nil }
    18  
    19  // Close implements common.Closable.
    20  func (*Client) Close() error { return nil }
    21  
    22  // LookupIP implements Client.
    23  func (*Client) LookupIP(host string) ([]net.IP, error) {
    24  	ips, err := net.LookupIP(host)
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	parsedIPs := make([]net.IP, 0, len(ips))
    29  	for _, ip := range ips {
    30  		parsed := net.IPAddress(ip)
    31  		if parsed != nil {
    32  			parsedIPs = append(parsedIPs, parsed.IP())
    33  		}
    34  	}
    35  	if len(parsedIPs) == 0 {
    36  		return nil, dns.ErrEmptyResponse
    37  	}
    38  	return parsedIPs, nil
    39  }
    40  
    41  // LookupIPv4 implements IPv4Lookup.
    42  func (c *Client) LookupIPv4(host string) ([]net.IP, error) {
    43  	ips, err := c.LookupIP(host)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	ipv4 := make([]net.IP, 0, len(ips))
    48  	for _, ip := range ips {
    49  		if len(ip) == net.IPv4len {
    50  			ipv4 = append(ipv4, ip)
    51  		}
    52  	}
    53  	if len(ipv4) == 0 {
    54  		return nil, dns.ErrEmptyResponse
    55  	}
    56  	return ipv4, nil
    57  }
    58  
    59  // LookupIPv6 implements IPv6Lookup.
    60  func (c *Client) LookupIPv6(host string) ([]net.IP, error) {
    61  	ips, err := c.LookupIP(host)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	ipv6 := make([]net.IP, 0, len(ips))
    66  	for _, ip := range ips {
    67  		if len(ip) == net.IPv6len {
    68  			ipv6 = append(ipv6, ip)
    69  		}
    70  	}
    71  	if len(ipv6) == 0 {
    72  		return nil, dns.ErrEmptyResponse
    73  	}
    74  	return ipv6, nil
    75  }
    76  
    77  // New create a new dns.Client that queries localhost for DNS.
    78  func New() *Client {
    79  	return &Client{}
    80  }