Unverified Commit 22432d19 authored by Andrew Gillis's avatar Andrew Gillis Committed by GitHub

Properly report DNSLink errors (#12)

* Properly report DNSLink errors

Only report that there is no DNSLink for a name when there are no DNSLink TXT records available for that name.  For all other errors, such as being offline, report the more general "cannot resolve name" error.

* Document that we give precedence to good results from looking up DNSLinks in TXT records from `"_dnslink."+fqdn` over results from `fqdn`.
parent 3d907820
......@@ -2,7 +2,6 @@ package namesys
import (
"context"
"fmt"
"strings"
"time"
......@@ -37,14 +36,6 @@ func resolve(ctx context.Context, r resolver, name string, options opts.ResolveO
}
}
if err == ErrResolveFailed {
i := len(name) - 1
for i >= 0 && name[i] != '/' {
i--
}
// Wrap error so that it can be tested if it is a ErrResolveFailed
err = fmt.Errorf("%w: %q is missing a DNSLink record (https://docs.ipfs.io/concepts/dnslink/)", ErrResolveFailed, name[i+1:])
}
return p, err
}
......
......@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
gpath "path"
"strings"
path "github.com/ipfs/go-path"
......@@ -88,6 +89,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
go func() {
defer close(out)
var rootResErr, subResErr error
for {
select {
case subRes, ok := <-subChan:
......@@ -98,8 +100,11 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
if subRes.error == nil {
p, err := appendPath(subRes.path)
emitOnceResult(ctx, out, onceResult{value: p, err: err})
// Return without waiting for rootRes, since this result
// (for "_dnslink."+fqdn) takes precedence
return
}
subResErr = subRes.error
case rootRes, ok := <-rootChan:
if !ok {
rootChan = nil
......@@ -108,11 +113,24 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
if rootRes.error == nil {
p, err := appendPath(rootRes.path)
emitOnceResult(ctx, out, onceResult{value: p, err: err})
// Do not return here. Wait for subRes so that it is
// output last if good, thereby giving subRes precedence.
} else {
rootResErr = rootRes.error
}
case <-ctx.Done():
return
}
if subChan == nil && rootChan == nil {
// If here, then both lookups are done
//
// If both lookups failed due to no TXT records with a
// dnslink, then output a more specific error message
if rootResErr == ErrResolveFailed && subResErr == ErrResolveFailed {
// Wrap error so that it can be tested if it is a ErrResolveFailed
err := fmt.Errorf("%w: %q is missing a DNSLink record (https://docs.ipfs.io/concepts/dnslink/)", ErrResolveFailed, gpath.Base(name))
emitOnceResult(ctx, out, onceResult{err: err})
}
return
}
}
......@@ -126,7 +144,14 @@ func workDomain(r *DNSResolver, name string, res chan lookupRes) {
txt, err := r.lookupTXT(name)
if err != nil {
// Error is != nil
if dnsErr, ok := err.(*net.DNSError); ok {
// If no TXT records found, return same error as when no text
// records contain dnslink. Otherwise, return the actual error.
if dnsErr.IsNotFound {
err = ErrResolveFailed
}
}
// Could not look up any text records for name
res <- lookupRes{"", err}
return
}
......@@ -138,6 +163,8 @@ func workDomain(r *DNSResolver, name string, res chan lookupRes) {
return
}
}
// There were no TXT records with a dnslink
res <- lookupRes{"", ErrResolveFailed}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment