Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (r *Resolver) LookupHost(ctx context.Context, host string) (addrs []string,
}
ip, err := netdev.GetHostByName(host)
if err != nil {
return nil, &DNSError{Err: err.Error(), Name: host}
return nil, newLookupError(host, err)
}
return []string{ip.String()}, nil
}
Expand Down Expand Up @@ -88,7 +88,7 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err
}
ip, err := netdev.GetHostByName(host)
if err != nil {
return nil, &DNSError{Err: err.Error(), Name: host}
return nil, newLookupError(host, err)
}
return []IPAddr{{IP: ip.AsSlice(), Zone: ip.Zone()}}, nil
}
Expand All @@ -104,7 +104,7 @@ func (r *Resolver) LookupNetIP(ctx context.Context, network, host string) ([]net
}
ip, err := netdev.GetHostByName(host)
if err != nil {
return nil, &DNSError{Err: err.Error(), Name: host}
return nil, newLookupError(host, err)
}
return []netip.Addr{ip}, nil
}
Expand Down Expand Up @@ -149,3 +149,23 @@ func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error)

// errNoSuchHost is returned when the host lookup finds no matching records.
var errNoSuchHost = errors.New("no such host")

// newLookupError wraps a netdev resolver error in a DNSError for host.
//
// TINYGO: the netdev can report a DNSError of its own, and callers read
// IsNotFound and IsTimeout on the outer error, so carry those flags out.
func newLookupError(host string, err error) *DNSError {
dnsErr := &DNSError{Err: err.Error(), Name: host, UnwrapErr: err}
if inner, ok := err.(*DNSError); ok {
// Take the inner description and not its Error(), which repeats the
// "lookup <host>" prefix that this error adds.
dnsErr.Err = inner.Err
dnsErr.IsNotFound = inner.IsNotFound
dnsErr.IsTimeout = inner.IsTimeout
dnsErr.IsTemporary = inner.IsTemporary
if inner.Server != "" {
dnsErr.Server = inner.Server
}
}
return dnsErr
}
18 changes: 15 additions & 3 deletions netdev_native.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,25 @@ const (
// dnsLookup resolves name by querying the system nameservers over UDP,
// preferring an IPv4 (A) answer and falling back to IPv6 (AAAA).
func dnsLookup(name string) (netip.Addr, error) {
if addr, err := dnsLookupType(name, dnsTypeA); err == nil {
addr, errA := dnsLookupType(name, dnsTypeA)
if errA == nil {
return addr, nil
}
if addr, err := dnsLookupType(name, dnsTypeAAAA); err == nil {
addr, errAAAA := dnsLookupType(name, dnsTypeAAAA)
if errAAAA == nil {
return addr, nil
}
return netip.Addr{}, &DNSError{Err: "no address found", Name: name}
// A name that the servers answered NXDOMAIN for is a different condition
// from a name that they did not answer at all.
notFound := isNotFoundErr(errA) && isNotFoundErr(errAAAA)
return netip.Addr{}, &DNSError{Err: "no address found", Name: name, IsNotFound: notFound}
}

// isNotFoundErr reports whether err is a DNSError for a name or a record type
// that does not exist.
func isNotFoundErr(err error) bool {
dnsErr, ok := err.(*DNSError)
return ok && dnsErr.IsNotFound
}

// dnsLookupType resolves name for a single DNS record type (A or AAAA).
Expand Down