Skip to content

Commit

Permalink
DNS: Implement queryStrategy for localhost DNS
Browse files Browse the repository at this point in the history
  • Loading branch information
Fangliding authored Jan 18, 2025
1 parent 14a6636 commit 7b92e1c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
2 changes: 1 addition & 1 deletion app/dns/nameserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func NewServer(ctx context.Context, dest net.Destination, dispatcher routing.Dis
}
switch {
case strings.EqualFold(u.String(), "localhost"):
return NewLocalNameServer(), nil
return NewLocalNameServer(queryStrategy), nil
case strings.EqualFold(u.Scheme, "https"): // DOH Remote mode
return NewDoHNameServer(u, dispatcher, queryStrategy)
case strings.EqualFold(u.Scheme, "https+local"): // DOH Local mode
Expand Down
32 changes: 28 additions & 4 deletions app/dns/nameserver_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,43 @@ import (

// LocalNameServer is an wrapper over local DNS feature.
type LocalNameServer struct {
client *localdns.Client
client *localdns.Client
queryStrategy QueryStrategy
}

const errEmptyResponse = "No address associated with hostname"

// QueryIP implements Server.
func (s *LocalNameServer) QueryIP(ctx context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) (ips []net.IP, err error) {
option = ResolveIpOptionOverride(s.queryStrategy, option)
if !option.IPv4Enable && !option.IPv6Enable {
return nil, dns.ErrEmptyResponse
}

start := time.Now()
ips, err = s.client.LookupIP(domain, option)

if err != nil && strings.HasSuffix(err.Error(), errEmptyResponse) {
err = dns.ErrEmptyResponse
}

// If ipv4 or ipv6 is disabled, filter out the unwanted IPs
if err != nil && (!option.IPv4Enable || !option.IPv6Enable) {
var FilteredIPs []net.IP
for _, ip := range ips {
if option.IPv4Enable && len(ip) == net.IPv4len {
FilteredIPs = append(FilteredIPs, ip)
}
if option.IPv6Enable && len(ip) == net.IPv6len {
FilteredIPs = append(FilteredIPs, ip)
}
}
if len(FilteredIPs) == 0 {
err = dns.ErrEmptyResponse
}
ips = FilteredIPs
}

if len(ips) > 0 {
errors.LogInfo(ctx, "Localhost got answer: ", domain, " -> ", ips)
log.Record(&log.DNSLog{Server: s.Name(), Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err})
Expand All @@ -42,14 +65,15 @@ func (s *LocalNameServer) Name() string {
}

// NewLocalNameServer creates localdns server object for directly lookup in system DNS.
func NewLocalNameServer() *LocalNameServer {
func NewLocalNameServer(queryStrategy QueryStrategy) *LocalNameServer {
errors.LogInfo(context.Background(), "DNS: created localhost client")
return &LocalNameServer{
client: localdns.New(),
queryStrategy: queryStrategy,
client: localdns.New(),
}
}

// NewLocalDNSClient creates localdns client object for directly lookup in system DNS.
func NewLocalDNSClient() *Client {
return &Client{server: NewLocalNameServer()}
return &Client{server: NewLocalNameServer(QueryStrategy_USE_IP)}
}
2 changes: 1 addition & 1 deletion app/dns/nameserver_local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

func TestLocalNameServer(t *testing.T) {
s := NewLocalNameServer()
s := NewLocalNameServer(QueryStrategy_USE_IP)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
ips, err := s.QueryIP(ctx, "google.com", net.IP{}, dns.IPOption{
IPv4Enable: true,
Expand Down

0 comments on commit 7b92e1c

Please sign in to comment.