Skip to content

Commit

Permalink
Make dns resolve paths under _dnslink.
Browse files Browse the repository at this point in the history
Thus allowing to CNAME main site entry to gateway and stil specify
dnslink.

License: MIT
Signed-off-by: Jakub Sztandera <[email protected]>
  • Loading branch information
Kubuxu committed Jan 15, 2016
1 parent 04914ac commit c3d9180
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 10 deletions.
53 changes: 43 additions & 10 deletions namesys/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,66 @@ func (r *DNSResolver) ResolveN(ctx context.Context, name string, depth int) (pat
return resolve(ctx, r, name, depth, "/ipns/")
}

type lookupRes struct {
path path.Path
error error
}

// resolveOnce implements resolver.
// TXT records for a given domain name should contain a b58
// encoded multihash.
func (r *DNSResolver) resolveOnce(ctx context.Context, name string) (path.Path, error) {
segments := strings.SplitN(name, "/", 2)
domain := segments[0]

if !isd.IsDomain(segments[0]) {
if !isd.IsDomain(domain) {
return "", errors.New("not a valid domain name")
}
log.Infof("DNSResolver resolving %s", domain)

rootChan := make(chan lookupRes)
go workDomain(r, domain, rootChan)

subChan := make(chan lookupRes)
go workDomain(r, "_dnslink." + domain, subChan)

subRes := <- subChan

var p path.Path
if subRes.error == nil {
p = subRes.path
} else {
rootRes := <- rootChan
if rootRes.error == nil {
p = rootRes.path
} else {
return "", ErrResolveFailed
}
}
if len(segments) > 1 {
return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[1])
} else {
return p, nil
}
}

func workDomain(r *DNSResolver, name string, res chan lookupRes) {
txt, err := r.lookupTXT(name)

log.Infof("DNSResolver resolving %s", segments[0])
txt, err := r.lookupTXT(segments[0])
if err != nil {
return "", err
// Error is != nil
res <- lookupRes{"", err}
return
}

for _, t := range txt {
p, err := parseEntry(t)
if err == nil {
if len(segments) > 1 {
return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[1])
}
return p, nil
res <- lookupRes{p, nil}
return
}
}

return "", ErrResolveFailed
res <- lookupRes{"", ErrResolveFailed}
}

func parseEntry(txt string) (path.Path, error) {
Expand Down
28 changes: 28 additions & 0 deletions namesys/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ func newMockDNS() *mockDNS {
"ipfs.example.com": []string{
"dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
},
"_dnslink.dipfs.example.com": []string{
"dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
},
"dns1.example.com": []string{
"dnslink=/ipns/ipfs.example.com",
},
Expand All @@ -85,6 +88,12 @@ func newMockDNS() *mockDNS {
"loop2.example.com": []string{
"dnslink=/ipns/loop1.example.com",
},
"_dnslink.dloop1.example.com": []string{
"dnslink=/ipns/loop2.example.com",
},
"_dnslink.dloop2.example.com": []string{
"dnslink=/ipns/loop1.example.com",
},
"bad.example.com": []string{
"dnslink=",
},
Expand All @@ -100,6 +109,18 @@ func newMockDNS() *mockDNS {
"withtrailingrec.example.com": []string{
"dnslink=/ipns/withtrailing.example.com/segment/",
},
"double.example.com": []string{
"dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
},
"_dnslink.double.example.com": []string{
"dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
},
"double.conflict.com": []string{
"dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
},
"_dnslink.conflict.example.com": []string{
"dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE",
},
},
}
}
Expand All @@ -109,6 +130,7 @@ func TestDNSResolution(t *testing.T) {
r := &DNSResolver{lookupTXT: mock.lookupTXT}
testResolution(t, r, "multihash.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
testResolution(t, r, "ipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
testResolution(t, r, "dipfs.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
testResolution(t, r, "dns1.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
testResolution(t, r, "dns1.example.com", 1, "/ipns/ipfs.example.com", ErrResolveRecursion)
testResolution(t, r, "dns2.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
Expand All @@ -122,11 +144,17 @@ func TestDNSResolution(t *testing.T) {
testResolution(t, r, "loop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion)
testResolution(t, r, "loop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion)
testResolution(t, r, "loop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
testResolution(t, r, "dloop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion)
testResolution(t, r, "dloop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion)
testResolution(t, r, "dloop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion)
testResolution(t, r, "dloop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
testResolution(t, r, "bad.example.com", DefaultDepthLimit, "", ErrResolveFailed)
testResolution(t, r, "withsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", nil)
testResolution(t, r, "withrecsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub", nil)
testResolution(t, r, "withsegment.example.com/test1", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/test1", nil)
testResolution(t, r, "withrecsegment.example.com/test2", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test2", nil)
testResolution(t, r, "withrecsegment.example.com/test3/", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test3/", nil)
testResolution(t, r, "withtrailingrec.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/", nil)
testResolution(t, r, "double.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
testResolution(t, r, "conflict.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil)
}

0 comments on commit c3d9180

Please sign in to comment.