dnslink

package module
v0.0.0-...-97903f3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2026 License: MIT Imports: 5 Imported by: 4

README

  • 👉 this project is no longer maintained, greenfield projects should use dnslink-std/go
  • we will convert this repo to a thin arapper around dnslink-std/go at some point – see #15

dnslink resolution in go-ipfs

Table of Contents

Background

Package dnslink implements a DNS link resolver. dnslink is a basic standard for placing traversable links in DNS itself. See dnslink.info

A dnslink is a path link in a DNS TXT record, like this:

dnslink=/ipfs/QmR7tiySn6vFHcEjBeZNtYGAFh735PJHfEMdVEycj9jAPy

For example:

> dig TXT ipfs.io
ipfs.io.  120   IN  TXT  dnslink=/ipfs/QmR7tiySn6vFHcEjBeZNtYGAFh735PJHfEMdVEycj9jAPy

This package eases resolving and working with thse DNS links. For example:

import (
  dnslink "github.com/ipfs/go-dnslink"
)

link, err := dnslink.Resolve("ipfs.io")
// link = "/ipfs/QmR7tiySn6vFHcEjBeZNtYGAFh735PJHfEMdVEycj9jAPy"

It even supports recursive resolution. Suppose you have three domains with dnslink records like these:

> dig TXT foo.com
foo.com.  120   IN  TXT  dnslink=/ipns/bar.com/f/o/o
> dig TXT bar.com
bar.com.  120   IN  TXT  dnslink=/ipns/long.test.baz.it/b/a/r
> dig TXT long.test.baz.it
long.test.baz.it.  120   IN  TXT  dnslink=/b/a/z

Expect these resolutions:

dnslink.ResolveN("long.test.baz.it", 0) // "/ipns/long.test.baz.it"
dnslink.Resolve("long.test.baz.it")     // "/b/a/z"

dnslink.ResolveN("bar.com", 1)          // "/ipns/long.test.baz.it/b/a/r"
dnslink.Resolve("bar.com")              // "/b/a/z/b/a/r"

dnslink.ResolveN("foo.com", 1)          // "/ipns/bar.com/f/o/o/"
dnslink.ResolveN("foo.com", 2)          // "/ipns/long.test.baz.it/b/a/r/f/o/o/"
dnslink.Resolve("foo.com")              // "/b/a/z/b/a/r/f/o/o"

Install

go get github.com/ipfs/go-dnslink

Usage

As a library
import (
  log
  fmt

  dnslink "github.com/ipfs/go-dnslink"
)

func main() {
  link, err := dnslink.Resolve("ipfs.io")
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println(link) // string path
}
As a commandline tool

Check out the commandline tool, which works like this:

> dnslink ipfs.io
/ipfs/QmR7tiySn6vFHcEjBeZNtYGAFh735PJHfEMdVEycj9jAPy

Contribute

Feel free to join in. All welcome. Open an issue!

This repository falls under the IPFS Code of Conduct.

Want to hack on IPFS?

License

MIT © Juan Benet-Batiz

Documentation

Overview

Package dnslink implements a dns link resolver. dnslink is a basic standard for placing traversable links in dns itself. See dnslink.info

A dnslink is a path link in a dns TXT record, like this:

dnslink=/ipfs/QmR7tiySn6vFHcEjBeZNtYGAFh735PJHfEMdVEycj9jAPy

For example:

> dig TXT ipfs.io
ipfs.io.  120   IN  TXT  dnslink=/ipfs/QmR7tiySn6vFHcEjBeZNtYGAFh735PJHfEMdVEycj9jAPy

This package eases resolving and working with thse dns links. For example:

import (
  dnslink "github.com/ipfs/go-dnslink"
)

link, err := dnslink.Resolve("ipfs.io")
// link = "/ipfs/QmR7tiySn6vFHcEjBeZNtYGAFh735PJHfEMdVEycj9jAPy"

It even supports recursive resolution. Suppose you have three domains with dnslink records like these:

> dig TXT foo.com
foo.com.  120   IN  TXT  dnslink=/dns/bar.com/f/o/o
> dig TXT bar.com
bar.com.  120   IN  TXT  dnslink=/dns/long.test.baz.it/b/a/r
> dig TXT long.test.baz.it
long.test.baz.it.  120   IN  TXT  dnslink=/b/a/z

Expect these resolutions:

dnslink.ResolveN("long.test.baz.it", 0) // "/dns/long.test.baz.it"
dnslink.Resolve("long.test.baz.it")     // "/b/a/z"

dnslink.ResolveN("bar.com", 1)          // "/dns/long.test.baz.it/b/a/r"
dnslink.Resolve("bar.com")              // "/b/a/z/b/a/r"

dnslink.ResolveN("foo.com", 1)          // "/dns/bar.com/f/o/o/"
dnslink.ResolveN("foo.com", 2)          // "/dns/long.test.baz.it/b/a/r/f/o/o/"
dnslink.Resolve("foo.com")              // "/b/a/z/b/a/r/f/o/o"

Index

Constants

View Source
const DefaultDepthLimit = 16

DefaultDepthLimit controls how many dns links to resolve through before returning. Users can override this default.

View Source
const MaximumDepthLimit = 256

MaximumDepthLimit governs the max number of recursive resolutions.

Variables

View Source
var (
	// ErrInvalidDomain is returned when a string representing a domain name
	// is not actually a valid domain.
	ErrInvalidDomain = errors.New("not a valid domain name")

	// ErrInvalidDnslink is returned when the dnslink entry in a TXT record
	// does not follow the proper dnslink format ("dnslink=<path>")
	ErrInvalidDnslink = errors.New("not a valid dnslink entry")

	// ErrResolveFailed is returned when a resolution failed, most likely
	// due to a network error.
	ErrResolveFailed = errors.New("link resolution failed")

	// ErrResolveLimit is returned when a recursive resolution goes over
	// the limit.
	ErrResolveLimit = errors.New("resolve depth exceeded")
)

Functions

func ParseLinkDomain

func ParseLinkDomain(txt string) (string, string, error)

ParseLinkDomain parses a domain from a dnslink path. The link path must follow the dnslink format:

/dns/<domain>/<path>
/dns/ipfs.io
/dns/ipfs.io/blog/0-hello-worlds

ParseLinkDomain will return ErrInvalidDnslink if parsing fails, and ErrInvalidDomain if the domain is not valid.

func ParseTXT

func ParseTXT(txt string) (string, error)

ParseTXT parses a TXT record value for a dnslink value. The TXT record must follow the dnslink format:

TXT dnslink=<path>
TXT dnslink=/foo/bar/baz

ParseTXT will return ErrInvalidDnslink if parsing fails.

func Resolve

func Resolve(domain string) (string, error)

Resolve is the simplest way to use this package. It simply resolves the dnslink at a particular domain. It will recursively keep resolving until reaching the DefaultDepthLimit. If the depth is reached, Resolve will return the last value retrieved, and ErrResolveLimit. If TXT records are found but are not valid dnslink records, Resolve will return ErrInvalidDnslink. Resolve will check every TXT record returned. If resolution fails otherwise, Resolve will return ErrResolveFailed

func ResolveN

func ResolveN(domain string, depth int) (string, error)

ResolveN is just like Resolve, with the option to specify a maximum resolution depth.

Types

type LookupTXTFunc

type LookupTXTFunc func(name string) (txt []string, err error)

LookupTXTFunc is a function that looks up a TXT record in some dns resovler. This is useful for testing or passing your own dns resolution process, which could take into account non-standard TLDs like .bit, .onion, .ipfs, etc.

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver implements a dnslink Resolver on DNS domains. This struct is here for composing dnslink resolution with other types of resolvers.

func NewResolver

func NewResolver(defaultDepth int) *Resolver

NewResolver constructs a new dnslink resolver. The given defaultDepth will be the maximum depth used by the Resolve function.

func (*Resolver) Resolve

func (r *Resolver) Resolve(domain string) (string, error)

Resolve resolves the dnslink at a particular domain. It will recursively keep resolving until reaching the defaultDepth of Resolver. If the depth is reached, Resolve will return the last value retrieved, and ErrResolveLimit. If TXT records are found but are not valid dnslink records, Resolve will return ErrInvalidDnslink. Resolve will check every TXT record returned. If resolution fails otherwise, Resolve will return ErrResolveFailed

func (*Resolver) ResolveN

func (r *Resolver) ResolveN(domain string, depth int) (link string, err error)

ResolveN is just like Resolve, with the option to specify a maximum resolution depth.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL