resolver: error from ResolveIPAddresses when no nameserver answered (closes #190)
check / check (push) Failing after 2m25s
check / check (push) Failing after 2m25s
ResolveIPAddresses now returns an error wrapping ErrNoNameserverAnswered when every nameserver of the name's zone timed out or failed, instead of no addresses and no error. It reads each nameserver's status as the lookup already sets it; one answer, even NXDOMAIN, is enough for an empty result without an error. The only caller, the nameserver address lookup, already keeps the previous addresses on an error; its comment no longer says the resolver hides this case. Model: opus-5-5
This commit is contained in:
@@ -734,7 +734,9 @@ func (r *Resolver) LookupAllRecords(
|
||||
}
|
||||
|
||||
// ResolveIPAddresses resolves a hostname to all IPv4 and IPv6
|
||||
// addresses, following CNAME chains up to MaxCNAMEDepth.
|
||||
// addresses, following CNAME chains up to MaxCNAMEDepth. When no
|
||||
// nameserver of the name's zone answered, it returns an error wrapping
|
||||
// ErrNoNameserverAnswered rather than no addresses.
|
||||
func (r *Resolver) ResolveIPAddresses(
|
||||
ctx context.Context,
|
||||
hostname string,
|
||||
@@ -760,7 +762,10 @@ func (r *Resolver) resolveIPWithCNAME(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ips, cnameTarget := collectIPs(results)
|
||||
ips, cnameTarget, err := collectIPs(results)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolving %s: %w", hostname, err)
|
||||
}
|
||||
|
||||
if len(ips) == 0 && cnameTarget != "" {
|
||||
return r.resolveIPWithCNAME(ctx, cnameTarget, depth+1)
|
||||
@@ -771,16 +776,28 @@ func (r *Resolver) resolveIPWithCNAME(
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
// collectIPs returns the addresses in the nameservers' answers and the
|
||||
// first CNAME target among them. It returns ErrNoNameserverAnswered when
|
||||
// every nameserver timed out or failed: that is not a name with no
|
||||
// addresses.
|
||||
func collectIPs(
|
||||
results map[string]*NameserverResponse,
|
||||
) ([]string, string) {
|
||||
) ([]string, string, error) {
|
||||
seen := make(map[string]bool)
|
||||
|
||||
var ips []string
|
||||
|
||||
var cnameTarget string
|
||||
|
||||
answered := false
|
||||
|
||||
for _, resp := range results {
|
||||
if resp.Status == StatusTimeout || resp.Status == StatusError {
|
||||
continue
|
||||
}
|
||||
|
||||
answered = true
|
||||
|
||||
if resp.Status == StatusNXDomain {
|
||||
continue
|
||||
}
|
||||
@@ -804,5 +821,9 @@ func collectIPs(
|
||||
}
|
||||
}
|
||||
|
||||
return ips, cnameTarget
|
||||
if !answered {
|
||||
return nil, "", ErrNoNameserverAnswered
|
||||
}
|
||||
|
||||
return ips, cnameTarget, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user