dns.go 2.62 KB
Newer Older
1 2 3 4 5 6 7
package commands

import (
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"
Jan Winkelmann's avatar
Jan Winkelmann committed
8
	e "github.com/ipfs/go-ipfs/core/commands/e"
9
	ncmd "github.com/ipfs/go-ipfs/core/commands/name"
10
	namesys "github.com/ipfs/go-ipfs/namesys"
Dirk McCormick's avatar
Dirk McCormick committed
11
	nsopts "github.com/ipfs/go-ipfs/namesys/opts"
Jan Winkelmann's avatar
Jan Winkelmann committed
12

13
	"gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
14 15
)

Kejie Zhang's avatar
Kejie Zhang committed
16 17 18 19
const (
	dnsRecursiveOptionName = "recursive"
)

20
var DNSCmd = &cmds.Command{
Jan Winkelmann's avatar
Jan Winkelmann committed
21
	Helptext: cmdkit.HelpText{
22
		Tagline: "Resolve DNS links.",
23 24 25 26 27 28 29 30 31 32 33 34 35 36
		ShortDescription: `
Multihashes are hard to remember, but domain names are usually easy to
remember.  To create memorable aliases for multihashes, DNS TXT
records can point to other DNS links, IPFS objects, IPNS keys, etc.
This command resolves those links to the referenced object.
`,
		LongDescription: `
Multihashes are hard to remember, but domain names are usually easy to
remember.  To create memorable aliases for multihashes, DNS TXT
records can point to other DNS links, IPFS objects, IPNS keys, etc.
This command resolves those links to the referenced object.

For example, with this DNS TXT record:

37
	> dig +short TXT _dnslink.ipfs.io
Lars Gierth's avatar
Lars Gierth committed
38
	dnslink=/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy
39 40 41

The resolver will give:

Lars Gierth's avatar
Lars Gierth committed
42 43
	> ipfs dns ipfs.io
	/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy
44

Lars Gierth's avatar
Lars Gierth committed
45
The resolver can recursively resolve:
46

Lars Gierth's avatar
Lars Gierth committed
47 48 49 50
	> dig +short TXT recursive.ipfs.io
	dnslink=/ipns/ipfs.io
	> ipfs dns -r recursive.ipfs.io
	/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy
51 52 53
`,
	},

Jan Winkelmann's avatar
Jan Winkelmann committed
54 55
	Arguments: []cmdkit.Argument{
		cmdkit.StringArg("domain-name", true, false, "The domain-name name to resolve.").EnableStdin(),
56
	},
Jan Winkelmann's avatar
Jan Winkelmann committed
57
	Options: []cmdkit.Option{
Kejie Zhang's avatar
Kejie Zhang committed
58
		cmdkit.BoolOption(dnsRecursiveOptionName, "r", "Resolve until the result is not a DNS link."),
59 60 61
	},
	Run: func(req cmds.Request, res cmds.Response) {

Kejie Zhang's avatar
Kejie Zhang committed
62
		recursive, _, _ := req.Option(dnsRecursiveOptionName).Bool()
63
		name := req.Arguments()[0]
64
		resolver := namesys.NewDNSResolver()
65

Dirk McCormick's avatar
Dirk McCormick committed
66
		var ropts []nsopts.ResolveOpt
67
		if !recursive {
Dirk McCormick's avatar
Dirk McCormick committed
68
			ropts = append(ropts, nsopts.Depth(1))
69
		}
Dirk McCormick's avatar
Dirk McCormick committed
70 71

		output, err := resolver.Resolve(req.Context(), name, ropts...)
72
		if err == namesys.ErrResolveFailed {
Jan Winkelmann's avatar
Jan Winkelmann committed
73
			res.SetError(err, cmdkit.ErrNotFound)
74 75
			return
		}
76
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
77
			res.SetError(err, cmdkit.ErrNormal)
78 79
			return
		}
80
		res.SetOutput(&ncmd.ResolvedPath{Path: output})
81 82 83
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
Jan Winkelmann's avatar
Jan Winkelmann committed
84 85 86 87 88
			v, err := unwrapOutput(res.Output())
			if err != nil {
				return nil, err
			}

89
			output, ok := v.(*ncmd.ResolvedPath)
90
			if !ok {
Jan Winkelmann's avatar
Jan Winkelmann committed
91
				return nil, e.TypeErr(output, v)
92
			}
93
			return strings.NewReader(output.Path.String() + "\n"), nil
94 95
		},
	},
96
	Type: ncmd.ResolvedPath{},
97
}