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

feat: support non-ICANN DNSLink names #13

Merged
merged 3 commits into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

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.

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).
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).

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.
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/).

The package provides implementations for all three resolvers.

Expand Down
4 changes: 2 additions & 2 deletions dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

path "github.com/ipfs/go-path"
opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
isd "github.com/jbenet/go-is-domain"
dns "github.com/miekg/dns"
)

// LookupTXTFunc is a generic type for a function that lookups TXT record values.
Expand Down Expand Up @@ -50,7 +50,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
segments := strings.SplitN(name, "/", 2)
domain := segments[0]

if !isd.IsDomain(domain) {
if _, ok := dns.IsDomainName(domain); !ok {
out <- onceResult{err: fmt.Errorf("not a valid domain name: %s", domain)}
close(out)
return out
Expand Down
12 changes: 12 additions & 0 deletions dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ func newMockDNS() *mockDNS {
"fqdn.example.com.": {
"dnslink=/ipfs/QmYvMB9yrsSf7RKBghkfwmHJkzJhW2ZgVwq3LxBXXPasFr",
},
"en.wikipedia-on-ipfs.org.": {
"dnslink=/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze",
},
"custom.non-icann.tldextravaganza.": {
"dnslink=/ipfs/bafybeieto6mcuvqlechv4iadoqvnffondeiwxc2bcfcewhvpsd2odvbmvm",
},
"singlednslabelshouldbeok.": {
"dnslink=/ipfs/bafybeih4a6ylafdki6ailjrdvmr7o4fbbeceeeuty4v3qyyouiz5koqlpi",
},
"www.wealdtech.eth.": {
"dnslink=/ipns/ipfs.example.com",
},
Expand Down Expand Up @@ -167,6 +176,9 @@ func TestDNSResolution(t *testing.T) {
testResolution(t, r, "double.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
testResolution(t, r, "conflict.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil)
testResolution(t, r, "fqdn.example.com.", opts.DefaultDepthLimit, "/ipfs/QmYvMB9yrsSf7RKBghkfwmHJkzJhW2ZgVwq3LxBXXPasFr", nil)
testResolution(t, r, "en.wikipedia-on-ipfs.org", 2, "/ipfs/bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze", nil)
testResolution(t, r, "custom.non-icann.tldextravaganza.", 2, "/ipfs/bafybeieto6mcuvqlechv4iadoqvnffondeiwxc2bcfcewhvpsd2odvbmvm", nil)
testResolution(t, r, "singlednslabelshouldbeok", 2, "/ipfs/bafybeih4a6ylafdki6ailjrdvmr7o4fbbeceeeuty4v3qyyouiz5koqlpi", nil)
testResolution(t, r, "www.wealdtech.eth", 1, "/ipns/ipfs.example.com", ErrResolveRecursion)
testResolution(t, r, "www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
testResolution(t, r, "www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module github.com/ipfs/go-namesys

require (
github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d
github.com/gogo/protobuf v1.3.2
github.com/hashicorp/golang-lru v0.5.4
github.com/ipfs/go-cid v0.0.7
Expand All @@ -13,14 +12,14 @@ require (
github.com/ipfs/go-log v1.0.4
github.com/ipfs/go-path v0.0.9
github.com/ipfs/interface-go-ipfs-core v0.4.0
github.com/jbenet/go-is-domain v1.0.5
github.com/jbenet/goprocess v0.1.4
github.com/libp2p/go-libp2p v0.13.0
github.com/libp2p/go-libp2p-core v0.8.0
github.com/libp2p/go-libp2p-kad-dht v0.11.1
github.com/libp2p/go-libp2p-peerstore v0.2.6
github.com/libp2p/go-libp2p-record v0.1.3
github.com/libp2p/go-libp2p-testing v0.4.0
github.com/miekg/dns v1.1.41
github.com/multiformats/go-multiaddr v0.3.1
github.com/multiformats/go-multiaddr-dns v0.3.1
github.com/multiformats/go-multihash v0.0.14
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d h1:QgeLLoPD3kRVmeu/1al9iIpIANMi9O1zXFm8BnYGCJg=
github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d/go.mod h1:Jbj8eKecMNwf0KFI75skSUZqMB4UCRcndUScVBTWyUI=
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
Expand Down Expand Up @@ -214,8 +212,6 @@ github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc=
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
github.com/jbenet/go-is-domain v1.0.5 h1:r92uiHbMEJo9Fkey5pMBtZAzjPQWic0ieo7Jw1jEuQQ=
github.com/jbenet/go-is-domain v1.0.5/go.mod h1:xbRLRb0S7FgzDBTJlguhDVwLYM/5yNtvktxj2Ttfy7Q=
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
Expand Down
18 changes: 8 additions & 10 deletions namesys.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
// DHT).
//
// 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.
// use DNSLink (/ipns/<dnslink_name>, https://docs.ipfs.io/concepts/dnslink/)
//
// The package provides implementations for all three resolvers.
package namesys
Expand All @@ -26,10 +25,10 @@ import (
dssync "github.com/ipfs/go-datastore/sync"
path "github.com/ipfs/go-path"
opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
isd "github.com/jbenet/go-is-domain"
ci "github.com/libp2p/go-libp2p-core/crypto"
peer "github.com/libp2p/go-libp2p-core/peer"
routing "github.com/libp2p/go-libp2p-core/routing"
dns "github.com/miekg/dns"
madns "github.com/multiformats/go-multiaddr-dns"
)

Expand All @@ -38,15 +37,14 @@ import (
// Uses several Resolvers:
// (a) IPFS routing naming: SFS-like PKI names.
// (b) dns domains: resolves using links in DNS TXT records
// (c) proquints: interprets string as the raw byte data.
//
// It can only publish to: (a) IPFS routing naming.
//
type mpns struct {
ds ds.Datastore

dnsResolver, proquintResolver, ipnsResolver resolver
ipnsPublisher Publisher
dnsResolver, ipnsResolver resolver
ipnsPublisher Publisher

staticMap map[string]path.Path
cache *lru.Cache
Expand Down Expand Up @@ -125,7 +123,6 @@ func NewNameSystem(r routing.ValueStore, opts ...Option) (NameSystem, error) {
ns.dnsResolver = NewDNSResolver(madns.DefaultResolver.LookupTXT)
}

ns.proquintResolver = new(ProquintResolver)
ns.ipnsResolver = NewIpnsResolver(r)
ns.ipnsPublisher = NewIpnsPublisher(r, ns.ds)

Expand Down Expand Up @@ -188,7 +185,6 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.
// Resolver selection:
// 1. if it is a PeerID/CID/multihash resolve through "ipns".
// 2. if it is a domain name, resolve through "dns"
// 3. otherwise resolve through the "proquint" resolver

var res resolver
ipnsKey, err := peer.Decode(key)
Expand Down Expand Up @@ -225,10 +221,12 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.

if err == nil {
res = ns.ipnsResolver
} else if isd.IsDomain(key) {
} else if _, ok := dns.IsDomainName(key); ok {
res = ns.dnsResolver
} else {
res = ns.proquintResolver
out <- onceResult{err: fmt.Errorf("invalid IPNS root: %q", key)}
Copy link
Member Author

@lidel lidel Apr 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I felt it is better to not default to "DNSLink not found" when input is not even a domain (eg. something like ..), so added a fallback error here.

close(out)
return out
}

resCh := res.resolveOnceAsync(ctx, key, options)
Expand Down
34 changes: 0 additions & 34 deletions proquint.go

This file was deleted.