Skip to content
This repository was archived by the owner on Jun 20, 2023. It is now read-only.

Commit 2454122

Browse files
authored
Merge pull request #10 from ipfs/feat/custom-resolver
make DNS resolver pluggable
2 parents 22432d1 + df97fc2 commit 2454122

File tree

9 files changed

+132
-151
lines changed

9 files changed

+132
-151
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
1111
Package namesys defines `Resolver` and `Publisher` interfaces for IPNS paths, that is, paths in the form of `/ipns/<name_to_be_resolved>`. A "resolved" IPNS path becomes an `/ipfs/<cid>` path.
1212

13-
Traditionally, these paths would be in the form of `/ipns/peer_id`, which references an IPNS record in a distributed `ValueStore` (usually the IPFS DHT).
13+
Traditionally, these paths would be in the form of `/ipns/{libp2p-key}`, which references an IPNS record in a distributed `ValueStore` (usually the IPFS DHT).
1414

15-
Additionally, the /ipns/ namespace can also be used with domain names that use DNSLink (/ipns/my.domain.example, see https://dnslink.io) and proquint strings.
15+
Additionally, the `/ipns/` namespace can also be used with domain names that use DNSLink (`/ipns/en.wikipedia-on-ipfs.org`, see https://docs.ipfs.io/concepts/dnslink/).
1616

1717
The package provides implementations for all three resolvers.
1818

dns.go

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@ import (
1010

1111
path "github.com/ipfs/go-path"
1212
opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
13-
isd "github.com/jbenet/go-is-domain"
13+
dns "github.com/miekg/dns"
1414
)
1515

16-
const ethTLD = "eth"
17-
const linkTLD = "domains"
18-
19-
// LookupTXTFunc is a generic type for a function that lookups TXT record values.
20-
type LookupTXTFunc func(name string) (txt []string, err error)
16+
// LookupTXTFunc is a function that lookups TXT record values.
17+
type LookupTXTFunc func(ctx context.Context, name string) (txt []string, err error)
2118

2219
// DNSResolver implements a Resolver on DNS domains
2320
type DNSResolver struct {
@@ -27,8 +24,8 @@ type DNSResolver struct {
2724
}
2825

2926
// NewDNSResolver constructs a name resolver using DNS TXT records.
30-
func NewDNSResolver() *DNSResolver {
31-
return &DNSResolver{lookupTXT: net.LookupTXT}
27+
func NewDNSResolver(lookup LookupTXTFunc) *DNSResolver {
28+
return &DNSResolver{lookupTXT: lookup}
3229
}
3330

3431
// Resolve implements Resolver.
@@ -55,7 +52,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
5552
segments := strings.SplitN(name, "/", 2)
5653
domain := segments[0]
5754

58-
if !isd.IsDomain(domain) {
55+
if _, ok := dns.IsDomainName(domain); !ok {
5956
out <- onceResult{err: fmt.Errorf("not a valid domain name: %s", domain)}
6057
close(out)
6158
return out
@@ -68,17 +65,11 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
6865
fqdn = domain + "."
6966
}
7067

71-
if strings.HasSuffix(fqdn, "."+ethTLD+".") {
72-
// This is an ENS name. As we're resolving via an arbitrary DNS server
73-
// that may not know about .eth we need to add our link domain suffix.
74-
fqdn += linkTLD + "."
75-
}
76-
7768
rootChan := make(chan lookupRes, 1)
78-
go workDomain(r, fqdn, rootChan)
69+
go workDomain(ctx, r, fqdn, rootChan)
7970

8071
subChan := make(chan lookupRes, 1)
81-
go workDomain(r, "_dnslink."+fqdn, subChan)
72+
go workDomain(ctx, r, "_dnslink."+fqdn, subChan)
8273

8374
appendPath := func(p path.Path) (path.Path, error) {
8475
if len(segments) > 1 {
@@ -139,10 +130,10 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
139130
return out
140131
}
141132

142-
func workDomain(r *DNSResolver, name string, res chan lookupRes) {
133+
func workDomain(ctx context.Context, r *DNSResolver, name string, res chan lookupRes) {
143134
defer close(res)
144135

145-
txt, err := r.lookupTXT(name)
136+
txt, err := r.lookupTXT(ctx, name)
146137
if err != nil {
147138
if dnsErr, ok := err.(*net.DNSError); ok {
148139
// If no TXT records found, return same error as when no text

dns_test.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package namesys
22

33
import (
4+
"context"
45
"fmt"
56
"testing"
67

@@ -11,7 +12,7 @@ type mockDNS struct {
1112
entries map[string][]string
1213
}
1314

14-
func (m *mockDNS) lookupTXT(name string) (txt []string, err error) {
15+
func (m *mockDNS) lookupTXT(ctx context.Context, name string) (txt []string, err error) {
1516
txt, ok := m.entries[name]
1617
if !ok {
1718
return nil, fmt.Errorf("no TXT entry for %s", name)
@@ -126,7 +127,16 @@ func newMockDNS() *mockDNS {
126127
"fqdn.example.com.": {
127128
"dnslink=/ipfs/QmYvMB9yrsSf7RKBghkfwmHJkzJhW2ZgVwq3LxBXXPasFr",
128129
},
129-
"www.wealdtech.eth.domains.": {
130+
"en.wikipedia-on-ipfs.org.": {
131+
"dnslink=/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze",
132+
},
133+
"custom.non-icann.tldextravaganza.": {
134+
"dnslink=/ipfs/bafybeieto6mcuvqlechv4iadoqvnffondeiwxc2bcfcewhvpsd2odvbmvm",
135+
},
136+
"singlednslabelshouldbeok.": {
137+
"dnslink=/ipfs/bafybeih4a6ylafdki6ailjrdvmr7o4fbbeceeeuty4v3qyyouiz5koqlpi",
138+
},
139+
"www.wealdtech.eth.": {
130140
"dnslink=/ipns/ipfs.example.com",
131141
},
132142
},
@@ -166,7 +176,10 @@ func TestDNSResolution(t *testing.T) {
166176
testResolution(t, r, "double.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
167177
testResolution(t, r, "conflict.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil)
168178
testResolution(t, r, "fqdn.example.com.", opts.DefaultDepthLimit, "/ipfs/QmYvMB9yrsSf7RKBghkfwmHJkzJhW2ZgVwq3LxBXXPasFr", nil)
179+
testResolution(t, r, "en.wikipedia-on-ipfs.org", 2, "/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze", nil)
180+
testResolution(t, r, "custom.non-icann.tldextravaganza.", 2, "/ipfs/bafybeieto6mcuvqlechv4iadoqvnffondeiwxc2bcfcewhvpsd2odvbmvm", nil)
181+
testResolution(t, r, "singlednslabelshouldbeok", 2, "/ipfs/bafybeih4a6ylafdki6ailjrdvmr7o4fbbeceeeuty4v3qyyouiz5koqlpi", nil)
169182
testResolution(t, r, "www.wealdtech.eth", 1, "/ipns/ipfs.example.com", ErrResolveRecursion)
170183
testResolution(t, r, "www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
171-
testResolution(t, r, "www.wealdtech.eth.domains", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
184+
testResolution(t, r, "www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
172185
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
module github.com/ipfs/go-namesys
22

33
require (
4-
github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d
54
github.com/gogo/protobuf v1.3.2
65
github.com/hashicorp/golang-lru v0.5.4
76
github.com/ipfs/go-cid v0.0.7
@@ -13,15 +12,16 @@ require (
1312
github.com/ipfs/go-log v1.0.4
1413
github.com/ipfs/go-path v0.0.9
1514
github.com/ipfs/interface-go-ipfs-core v0.4.0
16-
github.com/jbenet/go-is-domain v1.0.5
1715
github.com/jbenet/goprocess v0.1.4
1816
github.com/libp2p/go-libp2p v0.13.0
1917
github.com/libp2p/go-libp2p-core v0.8.0
2018
github.com/libp2p/go-libp2p-kad-dht v0.11.1
2119
github.com/libp2p/go-libp2p-peerstore v0.2.6
2220
github.com/libp2p/go-libp2p-record v0.1.3
2321
github.com/libp2p/go-libp2p-testing v0.4.0
22+
github.com/miekg/dns v1.1.41
2423
github.com/multiformats/go-multiaddr v0.3.1
24+
github.com/multiformats/go-multiaddr-dns v0.3.1
2525
github.com/multiformats/go-multihash v0.0.14
2626
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc
2727
)

0 commit comments

Comments
 (0)