dns

package
v0.0.10 Latest Latest
Warning

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

Go to latest
Published: Mar 9, 2024 License: MIT Imports: 14 Imported by: 2

Documentation

Overview

Package dns helps parse internationalized domain names (IDNA), canonicalize names and provides a strict and metrics-keeping logging DNS resolver.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrRelativeDNSName = errors.New("dns: host to lookup must be absolute, ending with a dot")
View Source
var Pedantic bool

Pedantic enables stricter parsing.

Functions

func IsNotFound

func IsNotFound(err error) bool

IsNotFound returns whether an error is an adns.DNSError with IsNotFound set. IsNotFound means the requested type does not exist for the given domain (a nodata or nxdomain response). It doesn't not necessarily mean no other types for that name exist.

A DNS server can respond to a lookup with an error "nxdomain" to indicate a name does not exist (at all), or with a success status with an empty list. The adns resolver (just like the Go resolver) returns an IsNotFound error for both cases, there is no need to explicitly check for zero entries.

Types

type Domain

type Domain struct {
	// A non-unicode domain, e.g. with A-labels (xn--...) or NR-LDH (non-reserved
	// letters/digits/hyphens) labels. Always in lower case. No trailing dot.
	ASCII string

	// Name as U-labels, in Unicode NFC. Empty if this is an ASCII-only domain. No
	// trailing dot.
	Unicode string
}

Domain is a domain name, with one or more labels, with at least an ASCII representation, and for IDNA non-ASCII domains a unicode representation. The ASCII string must be used for DNS lookups. The strings do not have a trailing dot. When using with StrictResolver, add the trailing dot.

func ParseDomain

func ParseDomain(s string) (Domain, error)

ParseDomain parses a domain name that can consist of ASCII-only labels or U labels (unicode). Names are IDN-canonicalized and lower-cased. Characters in unicode can be replaced by equivalents. E.g. "Ⓡ" to "r". This means you should only compare parsed domain names, never unparsed strings directly.

Example
package main

import (
	"fmt"
	"log"

	"github.com/mjl-/mox/dns"
)

func main() {
	// ASCII-only domain.
	basic, err := dns.ParseDomain("example.com")
	if err != nil {
		log.Fatalf("parse domain: %v", err)
	}
	fmt.Printf("%s\n", basic)

	// IDNA domain xn--74h.example.
	smile, err := dns.ParseDomain("☺.example")
	if err != nil {
		log.Fatalf("parse domain: %v", err)
	}
	fmt.Printf("%s\n", smile)

	// ASCII only domain curl.se in surprisingly allowed spelling.
	surprising, err := dns.ParseDomain("ℂᵤⓇℒ。𝐒🄴")
	if err != nil {
		log.Fatalf("parse domain: %v", err)
	}
	fmt.Printf("%s\n", surprising)

}
Output:

example.com
☺.example/xn--74h.example
curl.se

func ParseDomainLax added in v0.0.8

func ParseDomainLax(s string) (Domain, error)

ParseDomainLax parses a domain like ParseDomain, but allows labels with underscores if the entire domain name is ASCII-only non-IDNA and Pedantic mode is not enabled. Used for interoperability, e.g. domains may specify MX targets with underscores.

func (Domain) ASCIIExtra

func (d Domain) ASCIIExtra(smtputf8 bool) string

ASCIIExtra returns the ASCII version of the domain name if smtputf8 is true and this is a unicode domain name. Otherwise it returns an empty string.

This function is used to add the punycode name in a comment to SMTP message headers, e.g. Received and Authentication-Results.

func (Domain) IsZero

func (d Domain) IsZero() bool

IsZero returns if this is an empty Domain.

func (Domain) LogString added in v0.0.3

func (d Domain) LogString() string

LogString returns a domain for logging. For IDNA names, the string is the slash-separated Unicode and ASCII name. For ASCII-only domain names, just the ASCII string is returned.

func (Domain) Name

func (d Domain) Name() string

Name returns the unicode name if set, otherwise the ASCII name.

func (Domain) String

func (d Domain) String() string

Strings returns a human-readable string. For IDNA names, the string contains both the unicode and ASCII name.

func (Domain) XName

func (d Domain) XName(utf8 bool) string

XName is like Name, but only returns a unicode name when utf8 is true.

type IPDomain

type IPDomain struct {
	IP     net.IP
	Domain Domain
}

IPDomain is an ip address, a domain, or empty.

func (IPDomain) IsDomain

func (d IPDomain) IsDomain() bool

func (IPDomain) IsIP

func (d IPDomain) IsIP() bool

func (IPDomain) IsZero

func (d IPDomain) IsZero() bool

IsZero returns if both IP and Domain are zero.

func (IPDomain) LogString added in v0.0.3

func (d IPDomain) LogString() string

LogString returns a string with both ASCII-only and optional UTF-8 representation.

func (IPDomain) String

func (d IPDomain) String() string

String returns a string representation of either the IP or domain (with UTF-8).

func (IPDomain) XString

func (d IPDomain) XString(utf8 bool) string

XString is like String, but only returns UTF-8 domains if utf8 is true.

type MockResolver

type MockResolver struct {
	PTR          map[string][]string
	A            map[string][]string
	AAAA         map[string][]string
	TXT          map[string][]string
	MX           map[string][]*net.MX
	TLSA         map[string][]adns.TLSA // Keys are e.g. _25._tcp.<host>.
	CNAME        map[string]string
	Fail         []string // Records of the form "type name", e.g. "cname localhost." that will return a servfail.
	AllAuthentic bool     // Default value for authentic in responses. Overridden with Authentic and Inauthentic
	Authentic    []string // Like Fail, but records that cause the response to be authentic.
	Inauthentic  []string // Like Authentic, but making response inauthentic.
}

MockResolver is a Resolver used for testing. Set DNS records in the fields, which map FQDNs (with trailing dot) to values.

func (MockResolver) LookupAddr

func (r MockResolver) LookupAddr(ctx context.Context, ip string) ([]string, adns.Result, error)

func (MockResolver) LookupCNAME

func (r MockResolver) LookupCNAME(ctx context.Context, name string) (string, adns.Result, error)

func (MockResolver) LookupHost

func (r MockResolver) LookupHost(ctx context.Context, host string) ([]string, adns.Result, error)

func (MockResolver) LookupIP

func (r MockResolver) LookupIP(ctx context.Context, network, host string) ([]net.IP, adns.Result, error)

func (MockResolver) LookupIPAddr

func (r MockResolver) LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, adns.Result, error)

func (MockResolver) LookupMX

func (r MockResolver) LookupMX(ctx context.Context, name string) ([]*net.MX, adns.Result, error)

func (MockResolver) LookupNS

func (r MockResolver) LookupNS(ctx context.Context, name string) ([]*net.NS, adns.Result, error)

func (MockResolver) LookupPort

func (r MockResolver) LookupPort(ctx context.Context, network, service string) (port int, err error)

func (MockResolver) LookupSRV

func (r MockResolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*net.SRV, adns.Result, error)

func (MockResolver) LookupTLSA added in v0.0.8

func (r MockResolver) LookupTLSA(ctx context.Context, port int, protocol string, host string) ([]adns.TLSA, adns.Result, error)

func (MockResolver) LookupTXT

func (r MockResolver) LookupTXT(ctx context.Context, name string) ([]string, adns.Result, error)

type Resolver

type Resolver interface {
	LookupPort(ctx context.Context, network, service string) (port int, err error)
	LookupAddr(ctx context.Context, addr string) ([]string, adns.Result, error) // Always returns absolute names, with trailing dot.
	LookupCNAME(ctx context.Context, host string) (string, adns.Result, error)  // NOTE: returns an error if no CNAME record is present.
	LookupHost(ctx context.Context, host string) ([]string, adns.Result, error)
	LookupIP(ctx context.Context, network, host string) ([]net.IP, adns.Result, error)
	LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, adns.Result, error)
	LookupMX(ctx context.Context, name string) ([]*net.MX, adns.Result, error)
	LookupNS(ctx context.Context, name string) ([]*net.NS, adns.Result, error)
	LookupSRV(ctx context.Context, service, proto, name string) (string, []*net.SRV, adns.Result, error)
	LookupTXT(ctx context.Context, name string) ([]string, adns.Result, error)
	LookupTLSA(ctx context.Context, port int, protocol, host string) ([]adns.TLSA, adns.Result, error)
}

Resolver is the interface strict resolver implements.

func WithPackage

func WithPackage(resolver Resolver, name string) Resolver

WithPackage sets Pkg on resolver if it is a StrictResolve and does not have a package set yet.

type StrictResolver

type StrictResolver struct {
	Pkg      string         // Name of subsystem that is making DNS requests, for metrics.
	Resolver *adns.Resolver // Where the actual lookups are done. If nil, adns.DefaultResolver is used for lookups.
	Log      *slog.Logger
}

StrictResolver is a net.Resolver that enforces that DNS names end with a dot, preventing "search"-relative lookups.

func (StrictResolver) LookupAddr

func (r StrictResolver) LookupAddr(ctx context.Context, addr string) (resp []string, result adns.Result, err error)

func (StrictResolver) LookupCNAME

func (r StrictResolver) LookupCNAME(ctx context.Context, host string) (resp string, result adns.Result, err error)

LookupCNAME looks up a CNAME. Unlike "net" LookupCNAME, it returns a "not found" error if there is no CNAME record.

func (StrictResolver) LookupHost

func (r StrictResolver) LookupHost(ctx context.Context, host string) (resp []string, result adns.Result, err error)

func (StrictResolver) LookupIP

func (r StrictResolver) LookupIP(ctx context.Context, network, host string) (resp []net.IP, result adns.Result, err error)

func (StrictResolver) LookupIPAddr

func (r StrictResolver) LookupIPAddr(ctx context.Context, host string) (resp []net.IPAddr, result adns.Result, err error)

func (StrictResolver) LookupMX

func (r StrictResolver) LookupMX(ctx context.Context, name string) (resp []*net.MX, result adns.Result, err error)

func (StrictResolver) LookupNS

func (r StrictResolver) LookupNS(ctx context.Context, name string) (resp []*net.NS, result adns.Result, err error)

func (StrictResolver) LookupPort

func (r StrictResolver) LookupPort(ctx context.Context, network, service string) (resp int, err error)

func (StrictResolver) LookupSRV

func (r StrictResolver) LookupSRV(ctx context.Context, service, proto, name string) (resp0 string, resp1 []*net.SRV, result adns.Result, err error)

func (StrictResolver) LookupTLSA added in v0.0.8

func (r StrictResolver) LookupTLSA(ctx context.Context, port int, protocol, host string) (resp []adns.TLSA, result adns.Result, err error)

func (StrictResolver) LookupTXT

func (r StrictResolver) LookupTXT(ctx context.Context, name string) (resp []string, result adns.Result, err error)

func (StrictResolver) WithPackage

func (r StrictResolver) WithPackage(name string) Resolver

Jump to

Keyboard shortcuts

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