Skip to content

Commit

Permalink
refactor: use path.Path in namesys (some tests are failing bc of trai…
Browse files Browse the repository at this point in the history
…ling slashes)
  • Loading branch information
hacdias committed Sep 11, 2023
1 parent ae304bb commit 5df213c
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 171 deletions.
6 changes: 5 additions & 1 deletion gateway/blocks_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,11 @@ func (bb *BlocksBackend) GetIPNSRecord(ctx context.Context, c cid.Cid) ([]byte,

func (bb *BlocksBackend) GetDNSLinkRecord(ctx context.Context, hostname string) (path.Path, error) {
if bb.namesys != nil {
p, _, err := bb.namesys.Resolve(ctx, "/ipns/"+hostname, namesys.ResolveWithDepth(1))
p, err := path.NewPath("/ipns/" + hostname)
if err != nil {
return nil, err
}
p, _, err = bb.namesys.Resolve(ctx, p, namesys.ResolveWithDepth(1))
if err == namesys.ErrResolveRecursion {
err = nil
}
Expand Down
18 changes: 9 additions & 9 deletions gateway/utilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func newMockNamesysItem(p path.Path, ttl time.Duration) *mockNamesysItem {

type mockNamesys map[string]*mockNamesysItem

func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...namesys.ResolveOption) (value path.Path, ttl time.Duration, err error) {
func (m mockNamesys) Resolve(ctx context.Context, p path.Path, opts ...namesys.ResolveOption) (value path.Path, ttl time.Duration, err error) {
cfg := namesys.DefaultResolveOptions()
for _, o := range opts {
o(&cfg)
Expand All @@ -72,11 +72,7 @@ func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...namesys.R
// max uint
depth = ^uint(0)
}
p, err := path.NewPath(name)
if err != nil {
return nil, 0, err
}
name = path.SegmentsToString(p.Segments()[:2]...)
name := path.SegmentsToString(p.Segments()[:2]...)
for strings.HasPrefix(name, "/ipns/") {
if depth == 0 {
return value, 0, namesys.ErrResolveRecursion
Expand All @@ -96,9 +92,9 @@ func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...namesys.R
return value, ttl, err
}

func (m mockNamesys) ResolveAsync(ctx context.Context, name string, opts ...namesys.ResolveOption) <-chan namesys.ResolveResult {
func (m mockNamesys) ResolveAsync(ctx context.Context, p path.Path, opts ...namesys.ResolveOption) <-chan namesys.ResolveResult {
out := make(chan namesys.ResolveResult, 1)
v, ttl, err := m.Resolve(ctx, name, opts...)
v, ttl, err := m.Resolve(ctx, p, opts...)
out <- namesys.ResolveResult{Path: v, TTL: ttl, Err: err}
close(out)
return out
Expand Down Expand Up @@ -179,7 +175,11 @@ func (mb *mockBackend) GetIPNSRecord(ctx context.Context, c cid.Cid) ([]byte, er

func (mb *mockBackend) GetDNSLinkRecord(ctx context.Context, hostname string) (path.Path, error) {
if mb.namesys != nil {
p, _, err := mb.namesys.Resolve(ctx, "/ipns/"+hostname, namesys.ResolveWithDepth(1))
p, err := path.NewPath("/ipns/" + hostname)
if err != nil {
return nil, err
}
p, _, err = mb.namesys.Resolve(ctx, p, namesys.ResolveWithDepth(1))
if err == namesys.ErrResolveRecursion {
err = nil
}
Expand Down
54 changes: 24 additions & 30 deletions namesys/dns_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"
"time"

"github.com/ipfs/boxo/ipns"
path "github.com/ipfs/boxo/path"
"github.com/ipfs/go-cid"
dns "github.com/miekg/dns"
Expand All @@ -32,41 +31,43 @@ func NewDNSResolver(lookup LookupTXTFunc) *DNSResolver {
return &DNSResolver{lookupTXT: lookup}
}

func (r *DNSResolver) Resolve(ctx context.Context, name string, options ...ResolveOption) (path.Path, time.Duration, error) {
ctx, span := startSpan(ctx, "DNSResolver.Resolve")
func (r *DNSResolver) Resolve(ctx context.Context, p path.Path, options ...ResolveOption) (path.Path, time.Duration, error) {
ctx, span := startSpan(ctx, "DNSResolver.Resolve", trace.WithAttributes(attribute.Stringer("Path", p)))
defer span.End()

return resolve(ctx, r, name, ProcessResolveOptions(options))
return resolve(ctx, r, p, ProcessResolveOptions(options))
}

func (r *DNSResolver) ResolveAsync(ctx context.Context, name string, options ...ResolveOption) <-chan ResolveResult {
ctx, span := startSpan(ctx, "DNSResolver.ResolveAsync")
func (r *DNSResolver) ResolveAsync(ctx context.Context, p path.Path, options ...ResolveOption) <-chan ResolveResult {
ctx, span := startSpan(ctx, "DNSResolver.ResolveAsync", trace.WithAttributes(attribute.Stringer("Path", p)))
defer span.End()

return resolveAsync(ctx, r, name, ProcessResolveOptions(options))
return resolveAsync(ctx, r, p, ProcessResolveOptions(options))
}

func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options ResolveOptions) <-chan ResolveResult {
ctx, span := startSpan(ctx, "DNSResolver.ResolveOnceAsync")
func (r *DNSResolver) resolveOnceAsync(ctx context.Context, p path.Path, options ResolveOptions) <-chan ResolveResult {
ctx, span := startSpan(ctx, "DNSResolver.ResolveOnceAsync", trace.WithAttributes(attribute.Stringer("Path", p)))
defer span.End()

var fqdn string
out := make(chan ResolveResult, 1)
name = strings.TrimPrefix(name, ipns.NamespacePrefix)
segments := strings.SplitN(name, "/", 2)
domain := segments[0]
if p.Namespace() != path.IPNSNamespace {
out <- ResolveResult{Err: fmt.Errorf("unsupported namespace: %s", p.Namespace().String())}
close(out)
return out
}

if _, ok := dns.IsDomainName(domain); !ok {
out <- ResolveResult{Err: fmt.Errorf("not a valid domain name: %q", domain)}
segments := p.Segments()
fqdn := segments[1]
if _, ok := dns.IsDomainName(fqdn); !ok {
out <- ResolveResult{Err: fmt.Errorf("not a valid domain name: %q", fqdn)}
close(out)
return out
}
log.Debugf("DNSResolver resolving %s", domain)

if strings.HasSuffix(domain, ".") {
fqdn = domain
} else {
fqdn = domain + "."
log.Debugf("DNSResolver resolving %s", fqdn)

if !strings.HasSuffix(fqdn, ".") {
fqdn += "."
}

rootChan := make(chan ResolveResult, 1)
Expand All @@ -75,13 +76,6 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
subChan := make(chan ResolveResult, 1)
go workDomain(ctx, r, "_dnslink."+fqdn, subChan)

appendPath := func(p path.Path) (path.Path, error) {
if len(segments) > 1 {
return path.Join(p, segments[1])
}
return p, nil
}

go func() {
defer close(out)
ctx, span := startSpan(ctx, "DNSResolver.ResolveOnceAsync.Worker")
Expand All @@ -96,7 +90,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
break
}
if subRes.Err == nil {
p, err := appendPath(subRes.Path)
p, err := path.Join(subRes.Path, segments[2:]...)
emitOnceResult(ctx, out, ResolveResult{Path: p, Err: err})
// Return without waiting for rootRes, since this result
// (for "_dnslink."+fqdn) takes precedence
Expand All @@ -109,7 +103,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
break
}
if rootRes.Err == nil {
p, err := appendPath(rootRes.Path)
p, err := path.Join(rootRes.Path, segments[2:]...)
emitOnceResult(ctx, out, ResolveResult{Path: p, Err: err})
// Do not return here. Wait for subRes so that it is
// output last if good, thereby giving subRes precedence.
Expand All @@ -126,7 +120,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
// 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: _dnslink subdomain at %q is missing a TXT record (https://docs.ipfs.tech/concepts/dnslink/)", ErrResolveFailed, gopath.Base(name))
err := fmt.Errorf("%w: _dnslink subdomain at %q is missing a TXT record (https://docs.ipfs.tech/concepts/dnslink/)", ErrResolveFailed, gopath.Base(fqdn))
emitOnceResult(ctx, out, ResolveResult{Err: err})
}
return
Expand Down
75 changes: 38 additions & 37 deletions namesys/dns_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,46 +151,47 @@ func TestDNSResolution(t *testing.T) {
expectedPath string
expectedError error
}{
{"multihash.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/multihash.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"ipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"dipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"dns1.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"dns1.example.com", 1, "/ipns/ipfs.example.com", ErrResolveRecursion},
{"dns2.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"dns2.example.com", 1, "/ipns/dns1.example.com", ErrResolveRecursion},
{"dns2.example.com", 2, "/ipns/ipfs.example.com", ErrResolveRecursion},
{"multi.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"multi.example.com", 1, "/ipns/dns1.example.com", ErrResolveRecursion},
{"multi.example.com", 2, "/ipns/ipfs.example.com", ErrResolveRecursion},
{"equals.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/=equals", nil},
{"loop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion},
{"loop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion},
{"loop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion},
{"loop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion},
{"dloop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion},
{"dloop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion},
{"dloop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion},
{"dloop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion},
{"bad.example.com", DefaultDepthLimit, "", ErrResolveFailed},
{"/ipns/ipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/dipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/dns1.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/dns1.example.com", 1, "/ipns/ipfs.example.com", ErrResolveRecursion},
{"/ipns/dns2.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/dns2.example.com", 1, "/ipns/dns1.example.com", ErrResolveRecursion},
{"/ipns/dns2.example.com", 2, "/ipns/ipfs.example.com", ErrResolveRecursion},
{"/ipns/multi.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/multi.example.com", 1, "/ipns/dns1.example.com", ErrResolveRecursion},
{"/ipns/multi.example.com", 2, "/ipns/ipfs.example.com", ErrResolveRecursion},
{"/ipns/equals.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/=equals", nil},
{"/ipns/loop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion},
{"/ipns/loop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion},
{"/ipns/loop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion},
{"/ipns/loop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion},
{"/ipns/dloop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion},
{"/ipns/dloop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion},
{"/ipns/dloop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion},
{"/ipns/dloop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion},
{"/ipns/bad.example.com", DefaultDepthLimit, "", ErrResolveFailed},
{"withsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", nil},
{"withrecsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub", nil},
{"withsegment.example.com/test1", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/test1", nil},
{"withrecsegment.example.com/test2", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test2", nil},
{"withrecsegment.example.com/test3/", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test3/", nil},
{"withtrailingrec.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/", nil},
{"double.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"conflict.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil},
{"fqdn.example.com.", DefaultDepthLimit, "/ipfs/QmYvMB9yrsSf7RKBghkfwmHJkzJhW2ZgVwq3LxBXXPasFr", nil},
{"en.wikipedia-on-ipfs.org", 2, "/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze", nil},
{"custom.non-icann.tldextravaganza.", 2, "/ipfs/bafybeieto6mcuvqlechv4iadoqvnffondeiwxc2bcfcewhvpsd2odvbmvm", nil},
{"singlednslabelshouldbeok", 2, "/ipfs/bafybeih4a6ylafdki6ailjrdvmr7o4fbbeceeeuty4v3qyyouiz5koqlpi", nil},
{"www.wealdtech.eth", 1, "/ipns/ipfs.example.com", ErrResolveRecursion},
{"www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/bad.example.com", DefaultDepthLimit, "", ErrResolveFailed},
{"/ipns/withsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", nil},
{"/ipns/withrecsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub", nil},
{"/ipns/withsegment.example.com/test1", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/test1", nil},
{"/ipns/withrecsegment.example.com/test2", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test2", nil},
{"/ipns/withrecsegment.example.com/test3/", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test3/", nil},
{"/ipns/withtrailingrec.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/", nil},
{"/ipns/double.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/conflict.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil},
{"/ipns/fqdn.example.com.", DefaultDepthLimit, "/ipfs/QmYvMB9yrsSf7RKBghkfwmHJkzJhW2ZgVwq3LxBXXPasFr", nil},
{"/ipns/en.wikipedia-on-ipfs.org", 2, "/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze", nil},
{"/ipns/custom.non-icann.tldextravaganza.", 2, "/ipfs/bafybeieto6mcuvqlechv4iadoqvnffondeiwxc2bcfcewhvpsd2odvbmvm", nil},
{"/ipns/singlednslabelshouldbeok", 2, "/ipfs/bafybeih4a6ylafdki6ailjrdvmr7o4fbbeceeeuty4v3qyyouiz5koqlpi", nil},
{"/ipns/www.wealdtech.eth", 1, "/ipns/ipfs.example.com", ErrResolveRecursion},
{"/ipns/www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"/ipns/www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
{"www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil},
} {
testResolution(t, r, testCase.name, (testCase.depth), testCase.expectedPath, 0, testCase.expectedError)
t.Run(testCase.name, func(t *testing.T) {
testResolution(t, r, testCase.name, (testCase.depth), testCase.expectedPath, 0, testCase.expectedError)
})
}
}
4 changes: 2 additions & 2 deletions namesys/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ type Resolver interface {
//
// There is a default depth-limit to avoid infinite recursion. Most users will be fine with
// this default limit, but if you need to adjust the limit you can specify it as an option.
Resolve(ctx context.Context, name string, options ...ResolveOption) (value path.Path, ttl time.Duration, err error)
Resolve(context.Context, path.Path, ...ResolveOption) (path.Path, time.Duration, error)

// ResolveAsync performs recursive name lookup, like Resolve, but it returns entries as
// they are discovered in the DHT. Each returned result is guaranteed to be "better"
// (which usually means newer) than the previous one.
ResolveAsync(ctx context.Context, name string, options ...ResolveOption) <-chan ResolveResult
ResolveAsync(context.Context, path.Path, ...ResolveOption) <-chan ResolveResult
}

// ResolveOptions specifies options for resolving an IPNS Path.
Expand Down
37 changes: 23 additions & 14 deletions namesys/ipns_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package namesys

import (
"context"
"fmt"
"time"

"github.com/ipfs/boxo/ipns"
Expand Down Expand Up @@ -36,36 +37,40 @@ func NewIPNSResolver(route routing.ValueStore) *IPNSResolver {
}
}

func (r *IPNSResolver) Resolve(ctx context.Context, name string, options ...ResolveOption) (path.Path, time.Duration, error) {
ctx, span := startSpan(ctx, "IPNSResolver.Resolve", trace.WithAttributes(attribute.String("Name", name)))
func (r *IPNSResolver) Resolve(ctx context.Context, p path.Path, options ...ResolveOption) (path.Path, time.Duration, error) {
ctx, span := startSpan(ctx, "IPNSResolver.Resolve", trace.WithAttributes(attribute.Stringer("Path", p)))
defer span.End()

return resolve(ctx, r, name, ProcessResolveOptions(options))
return resolve(ctx, r, p, ProcessResolveOptions(options))
}

func (r *IPNSResolver) ResolveAsync(ctx context.Context, name string, options ...ResolveOption) <-chan ResolveResult {
ctx, span := startSpan(ctx, "IPNSResolver.ResolveAsync", trace.WithAttributes(attribute.String("Name", name)))
func (r *IPNSResolver) ResolveAsync(ctx context.Context, p path.Path, options ...ResolveOption) <-chan ResolveResult {
ctx, span := startSpan(ctx, "IPNSResolver.ResolveAsync", trace.WithAttributes(attribute.Stringer("Path", p)))
defer span.End()

return resolveAsync(ctx, r, name, ProcessResolveOptions(options))
return resolveAsync(ctx, r, p, ProcessResolveOptions(options))
}

func (r *IPNSResolver) resolveOnceAsync(ctx context.Context, nameStr string, options ResolveOptions) <-chan ResolveResult {
ctx, span := startSpan(ctx, "IPNSResolver.ResolveOnceAsync", trace.WithAttributes(attribute.String("Name", nameStr)))
func (r *IPNSResolver) resolveOnceAsync(ctx context.Context, p path.Path, options ResolveOptions) <-chan ResolveResult {
ctx, span := startSpan(ctx, "IPNSResolver.ResolveOnceAsync", trace.WithAttributes(attribute.Stringer("Path", p)))
defer span.End()

out := make(chan ResolveResult, 1)
log.Debugf("RoutingResolver resolving %s", nameStr)
cancel := func() {}
if p.Namespace() != path.IPNSNamespace {
out <- ResolveResult{Err: fmt.Errorf("unsupported namespace: %s", p.Namespace().String())}
close(out)
return out
}

cancel := func() {}
if options.DhtTimeout != 0 {
// Resolution must complete within the timeout
ctx, cancel = context.WithTimeout(ctx, options.DhtTimeout)
}

name, err := ipns.NameFromString(nameStr)
segments := p.Segments()
name, err := ipns.NameFromString(segments[1])
if err != nil {
log.Debugf("RoutingResolver: could not convert key %q to IPNS name: %s\n", nameStr, err)
out <- ResolveResult{Err: err}
close(out)
cancel()
Expand All @@ -74,7 +79,6 @@ func (r *IPNSResolver) resolveOnceAsync(ctx context.Context, nameStr string, opt

vals, err := r.routing.SearchValue(ctx, string(name.RoutingKey()), dht.Quorum(int(options.DhtRecordCount)))
if err != nil {
log.Debugf("RoutingResolver: dht get for name %s failed: %s", nameStr, err)
out <- ResolveResult{Err: err}
close(out)
cancel()
Expand All @@ -96,7 +100,6 @@ func (r *IPNSResolver) resolveOnceAsync(ctx context.Context, nameStr string, opt

rec, err := ipns.UnmarshalRecord(val)
if err != nil {
log.Debugf("RoutingResolver: could not unmarshal value for name %s: %s", nameStr, err)
emitOnceResult(ctx, out, ResolveResult{Err: err})
return
}
Expand All @@ -107,6 +110,12 @@ func (r *IPNSResolver) resolveOnceAsync(ctx context.Context, nameStr string, opt
return
}

p, err = path.Join(p, segments[2:]...)
if err != nil {
emitOnceResult(ctx, out, ResolveResult{Err: err})
return
}

ttl, err := calculateBestTTL(rec)
if err != nil {
emitOnceResult(ctx, out, ResolveResult{Err: err})
Expand Down
Loading

0 comments on commit 5df213c

Please sign in to comment.