dns

package module
v0.0.0-...-dd32194 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2019 License: MIT Imports: 19 Imported by: 0

README

dns GoDoc Build Status Go Report Card

DNS client and server package. See godoc for details & examples.

Documentation

Overview

Package dns provides DNS client and server implementations.

A client can handle queries for a net.Dialer:

dialer := &net.Dialer{
	Resolver: &net.Resolver{
		PreferGo: true,

		Dial: new(dns.Client).Dial,
	},
}

conn, err := dialer.DialContext(ctx, "tcp", "example.com:80")

It can also query a remote DNS server directly:

client := new(dns.Client)
query := &dns.Query{
	RemoteAddr: &net.TCPAddr{IP: net.IPv4(8, 8, 8, 8), Port: 53},

	Message: &dns.Message{
		Questions: []dns.Question{
			{
				Name:  "example.com.",
				Type:  dns.TypeA,
				Class: dns.ClassIN,
			},
			{
				Name:  "example.com.",
				Type:  dns.TypeAAAA,
				Class: dns.ClassIN,
			},
		},
	},
}

msg, err := client.Do(ctx, query)

A handler answers queries for a server or a local resolver for a client:

zone := &dns.Zone{
	Origin: "localhost.",
	TTL:    5 * time.Minute,
	RRs: dns.RRSet{
		"alpha": []dns.Record{
			&dns.A{net.IPv4(127, 0, 0, 42).To4()},
			&dns.AAAA{net.ParseIP("::42")},
		},
	},
}

srv := &dns.Server{
	Addr:    ":53",
	Handler: zone,
}

go srv.ListenAndServe(ctx)

mux := new(dns.ResolveMux)
mux.Handle(dns.TypeANY, zone.Origin, zone)

client := &dns.Client{
	Resolver: mux,
}

net.DefaultResolver = &net.Resolver{
	PreferGo: true,
	Dial:     client.Dial,
}

addrs, err := net.LookupHost("alpha.localhost")

Index

Examples

Constants

View Source
const (
	// Resource Record (RR) TYPEs
	TypeA     Type = 1   // [RFC1035] a host address
	TypeNS    Type = 2   // [RFC1035] an authoritative name server
	TypeCNAME Type = 5   // [RFC1035] the canonical name for an alias
	TypeSOA   Type = 6   // [RFC1035] marks the start of a zone of authority
	TypeWKS   Type = 11  // [RFC1035] a well known service description
	TypePTR   Type = 12  // [RFC1035] a domain name pointer
	TypeHINFO Type = 13  // [RFC1035] host information
	TypeMINFO Type = 14  // [RFC1035] mailbox or mail list information
	TypeMX    Type = 15  // [RFC1035] mail exchange
	TypeTXT   Type = 16  // [RFC1035] text strings
	TypeAAAA  Type = 28  // [RFC3596] IP6 Address
	TypeSRV   Type = 33  // [RFC2782] Server Selection
	TypeDNAME Type = 39  // [RFC6672] DNAME
	TypeOPT   Type = 41  // [RFC6891][RFC3225] OPT
	TypeAXFR  Type = 252 // [RFC1035][RFC5936] transfer of an entire zone
	TypeALL   Type = 255 // [RFC1035][RFC6895] A request for all records the server/cache has available
	TypeCAA   Type = 257 // [RFC6844] Certification Authority Restriction

	TypeANY Type = 0

	// DNS CLASSes
	ClassIN  Class = 1   // [RFC1035] Internet (IN)
	ClassCH  Class = 3   // [] Chaos (CH)
	ClassHS  Class = 4   // [] Hesiod (HS)
	ClassANY Class = 255 // [RFC1035] QCLASS * (ANY)

	// DNS RCODEs
	NoError  RCode = 0 // [RFC1035] No Error
	FormErr  RCode = 1 // [RFC1035] Format Error
	ServFail RCode = 2 // [RFC1035] Server Failure
	NXDomain RCode = 3 // [RFC1035] Non-Existent Domain
	NotImp   RCode = 4 // [RFC1035] Not Implemented
	Refused  RCode = 5 // [RFC1035] Query Refused

)

Domain Name System (DNS) Parameters.

Taken from https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml

Variables

View Source
var (
	// ErrConflictingID is a pipelining error due to the same message ID being
	// used for more than one inflight query.
	ErrConflictingID = errors.New("conflicting message id")

	// ErrOversizedMessage is an error returned when attempting to send a
	// message that is longer than the maximum allowed number of bytes.
	ErrOversizedMessage = errors.New("oversized message")

	// ErrTruncatedMessage indicates the response message has been truncated.
	ErrTruncatedMessage = errors.New("truncated message")

	// ErrUnsupportedNetwork is returned when DialAddr is called with an
	// unknown network.
	ErrUnsupportedNetwork = errors.New("unsupported network")

	// ErrUnsupportedOp indicates the operation is not supported by callee.
	ErrUnsupportedOp = errors.New("unsupported operation")
)
View Source
var (
	// ErrNotStarted indicates that the prerequisite information isn't
	// available yet because the previous records haven't been appropriately
	// parsed or skipped.
	ErrNotStarted = errors.New("parsing of this type isn't available yet")

	// ErrSectionDone indicated that all records in the section have been
	// parsed.
	ErrSectionDone = errors.New("parsing of this section has completed")
)
View Source
var Events = [...]string{
	"",
	"clear",
	"set",
	"setKey",
	"deleteKey",
	"deleteKeyInRecord",
	"appendKeyInRecord",
}
View Source
var NewRecordByType = map[Type]func() Record{
	TypeA:     func() Record { return new(A) },
	TypeNS:    func() Record { return new(NS) },
	TypeCNAME: func() Record { return new(CNAME) },
	TypeSOA:   func() Record { return new(SOA) },
	TypePTR:   func() Record { return new(PTR) },
	TypeMX:    func() Record { return new(MX) },
	TypeTXT:   func() Record { return new(TXT) },
	TypeAAAA:  func() Record { return new(AAAA) },
	TypeSRV:   func() Record { return new(SRV) },
	TypeDNAME: func() Record { return new(DNAME) },
	TypeOPT:   func() Record { return new(OPT) },
	TypeCAA:   func() Record { return new(CAA) },
}

NewRecordByType returns a new instance of a Record for a Type.

Functions

func Recursor

func Recursor(ctx context.Context, w MessageWriter, r *Query)

Recursor forwards a query and copies the response.

func Refuse

func Refuse(ctx context.Context, w MessageWriter, r *Query)

Refuse responds to all queries with a "Query Refused" message.

Types

type A

type A struct {
	A net.IP
	// contains filtered or unexported fields
}

A A is a DNS A record.

func (*A) FromJSon

func (a *A) FromJSon(v string) error

func (*A) Get

func (a *A) Get() interface{}

func (A) Length

func (A) Length(Compressor) (int, error)

Length returns the encoded RDATA size.

func (A) Pack

func (a A) Pack(b []byte, _ Compressor) ([]byte, error)

Pack encodes a as RDATA.

func (*A) String

func (a *A) String() string

func (A) Type

func (A) Type() Type

Type returns the RR type identifier.

func (*A) Unpack

func (a *A) Unpack(b []byte, _ Decompressor) ([]byte, error)

Unpack decodes a from RDATA in b.

type AAAA

type AAAA struct {
	AAAA net.IP
	// contains filtered or unexported fields
}

AAAA is a DNS AAAA record.

func (*AAAA) FromJSon

func (a *AAAA) FromJSon(v string) error

func (*AAAA) Get

func (a *AAAA) Get() interface{}

func (AAAA) Length

func (AAAA) Length(Compressor) (int, error)

Length returns the encoded RDATA size.

func (AAAA) Pack

func (a AAAA) Pack(b []byte, _ Compressor) ([]byte, error)

Pack encodes a as RDATA.

func (*AAAA) String

func (a *AAAA) String() string

func (AAAA) Type

func (AAAA) Type() Type

Type returns the RR type identifier.

func (*AAAA) Unpack

func (a *AAAA) Unpack(b []byte, _ Decompressor) ([]byte, error)

Unpack decodes a from RDATA in b.

type AddrDialer

type AddrDialer interface {
	DialAddr(context.Context, net.Addr) (Conn, error)
}

AddrDialer dials a net Addr.

type CAA

type CAA struct {
	IssuerCritical bool

	Tag   string
	Value string
	// contains filtered or unexported fields
}

type CAA is a DNS CAA record.

func (*CAA) FromJSon

func (c *CAA) FromJSon(v string) error

func (*CAA) Get

func (c *CAA) Get() interface{}

func (CAA) Length

func (c CAA) Length(_ Compressor) (int, error)

Length returns the encoded RDATA size.

func (CAA) Pack

func (c CAA) Pack(b []byte, _ Compressor) ([]byte, error)

Pack encodes c as RDATA.

func (*CAA) String

func (c *CAA) String() string

func (CAA) Type

func (CAA) Type() Type

Type returns the RR type identifier.

func (*CAA) Unpack

func (c *CAA) Unpack(b []byte, _ Decompressor) ([]byte, error)

Unpack decodes c from RDATA in b.

type CNAME

type CNAME struct {
	CNAME string
	// contains filtered or unexported fields
}

CNAME is a DNS CNAME record.

func (*CNAME) FromJSon

func (c *CNAME) FromJSon(v string) error

func (*CNAME) Get

func (c *CNAME) Get() interface{}

func (CNAME) Length

func (c CNAME) Length(com Compressor) (int, error)

Length returns the encoded RDATA size.

func (CNAME) Pack

func (c CNAME) Pack(b []byte, com Compressor) ([]byte, error)

Pack encodes c as RDATA.

func (*CNAME) String

func (c *CNAME) String() string

func (CNAME) Type

func (CNAME) Type() Type

Type returns the RR type identifier.

func (*CNAME) Unpack

func (c *CNAME) Unpack(b []byte, dec Decompressor) ([]byte, error)

Unpack decodes c from RDATA in b.

type Cache

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

Cache is a DNS query cache handler.

func (*Cache) ServeDNS

func (c *Cache) ServeDNS(ctx context.Context, w MessageWriter, r *Query)

ServeDNS answers query questions from a local cache, and forwards unanswered questions upstream, then caches the answers from the response.

type Class

type Class uint16

A Class is a type of network.

type Client

type Client struct {
	// Transport manages connections to DNS servers.
	Transport AddrDialer

	// Resolver is a handler that may answer all or portions of a query.
	// Any questions answered by the handler are not sent to the upstream
	// server.
	Resolver Handler
	// contains filtered or unexported fields
}

Client is a DNS client.

Example (DnsOverTLS)
package main

import (
	"crypto/rand"
	"crypto/tls"
	"net"

	"github.com/benburkert/dns"
)

func main() {
	dnsLocal := dns.OverTLSAddr{
		Addr: &net.TCPAddr{
			IP:   net.IPv4(192, 168, 8, 8),
			Port: 853,
		},
	}

	client := &dns.Client{
		Transport: &dns.Transport{
			Proxy: dns.NameServers{dnsLocal}.Random(rand.Reader),

			TLSConfig: &tls.Config{
				ServerName: "dns.local",
			},
		},
	}

	net.DefaultResolver = &net.Resolver{
		PreferGo: true,
		Dial:     client.Dial,
	}
}
Output:

Example (OverrideNameServers)
package main

import (
	"fmt"
	"net"

	"github.com/benburkert/dns"
)

func main() {
	net.DefaultResolver = &net.Resolver{
		PreferGo: true,

		Dial: (&dns.Client{
			Transport: &dns.Transport{
				Proxy: dns.NameServers{
					&net.UDPAddr{IP: net.IPv4(8, 8, 8, 8), Port: 53},
					&net.UDPAddr{IP: net.IPv4(8, 8, 4, 4), Port: 53},
				}.RoundRobin(),
			},
		}).Dial,
	}

	addrs, err := net.LookupHost("127.0.0.1.xip.io")
	if err != nil {
		panic(err)
	}

	for _, addr := range addrs {
		fmt.Println(addr)
	}
}
Output:

127.0.0.1

func (*Client) Dial

func (c *Client) Dial(ctx context.Context, network, address string) (net.Conn, error)

Dial dials a DNS server and returns a net Conn that reads and writes DNS messages.

func (*Client) Do

func (c *Client) Do(ctx context.Context, query *Query) (*Message, error)

Do sends a DNS query to a server and returns the response message.

type Compressor

type Compressor interface {
	Length(...string) (int, error)
	Pack([]byte, string) ([]byte, error)
}

Compressor encodes domain names.

type Conn

type Conn interface {
	net.Conn

	// Recv reads a DNS message from the connection.
	Recv(msg *Message) error

	// Send writes a DNS message to the connection.
	Send(msg *Message) error
}

Conn is a network connection to a DNS resolver.

type DNAME

type DNAME struct {
	DNAME string
	// contains filtered or unexported fields
}

DNAME is a DNS DNAME record.

func (*DNAME) FromJSon

func (d *DNAME) FromJSon(v string) error

func (*DNAME) Get

func (d *DNAME) Get() interface{}

func (DNAME) Length

func (d DNAME) Length(com Compressor) (int, error)

Length returns the encoded RDATA size.

func (DNAME) Pack

func (d DNAME) Pack(b []byte, com Compressor) ([]byte, error)

Pack encodes c as RDATA.

func (*DNAME) String

func (d *DNAME) String() string

func (DNAME) Type

func (DNAME) Type() Type

Type returns the RR type identifier.

func (*DNAME) Unpack

func (d *DNAME) Unpack(b []byte, dec Decompressor) ([]byte, error)

Unpack decodes c from RDATA in b.

type Decompressor

type Decompressor interface {
	Unpack([]byte) (string, []byte, error)
}

Decompressor decodes domain names.

type Event

type Event int
const (
	KEventClear Event = iota + 1
	KEventSet
	KEventSetKey
	KEventDeleteKey
	KEventDeleteKeyInRecord
	KEventAppendKeyInRecord
)

func (Event) String

func (el Event) String() string

type Handler

type Handler interface {
	ServeDNS(context.Context, MessageWriter, *Query)
	Clear()
	Set(map[string]map[Type][]Record)
	SetKey(string, map[Type][]Record)
	Len() int
	GetKey(string) (map[Type][]Record, bool)
	DeleteKey(string)
	DeleteRecordInKey(string, Record)
	AppendRecordInKey(string, Record)
	GetAll() map[string]map[Type][]Record
	SetBeforeOnClear(func(map[string]map[Type][]Record))
	SetBeforeOnChange(func(Event, string, interface{}, interface{}))
	SetBeforeOnSetKey(func(string, map[Type][]Record, map[Type][]Record))
	SetBeforeDeleteKey(func(string, map[Type][]Record))
	SetBeforeOnDeleteKeyInRecord(func(string, map[Type][]Record, map[Type][]Record))
	SetBeforeOnAppendKeyInRecord(func(string, map[Type][]Record, map[Type][]Record))
	SetOnClear(func(map[string]map[Type][]Record))
	SetOnChange(func(Event, string, interface{}, interface{}))
	SetOnSetKey(func(string, map[Type][]Record, map[Type][]Record))
	SetOnDeleteKey(func(string, map[Type][]Record))
	SetOnDeleteKeyInRecord(func(string, map[Type][]Record, map[Type][]Record))
	SetOnAppendKeyInRecord(func(string, map[Type][]Record, map[Type][]Record))
}

Handler responds to a DNS query.

ServeDNS should build the reply message using the MessageWriter, and may optionally call the Reply method. Returning signals that the request is finished and the response is ready to send.

A recursive handler may call the Recur method of the MessageWriter to send an query upstream. Only unanswered questions are included in the upstream query.

type HandlerFunc

type HandlerFunc func(context.Context, MessageWriter, *Query)

The HandlerFunc type is an adapter to allow the use of ordinary functions as DNS handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a Handler that calls f.

func (HandlerFunc) AppendRecordInKey

func (f HandlerFunc) AppendRecordInKey(k string, r Record)

func (HandlerFunc) Clear

func (f HandlerFunc) Clear()

func (HandlerFunc) DeleteKey

func (f HandlerFunc) DeleteKey(k string)

func (HandlerFunc) DeleteRecordInKey

func (f HandlerFunc) DeleteRecordInKey(k string, r Record)

func (HandlerFunc) GetAll

func (f HandlerFunc) GetAll() map[string]map[Type][]Record

func (HandlerFunc) GetKey

func (f HandlerFunc) GetKey(k string) (map[Type][]Record, bool)

func (HandlerFunc) Len

func (f HandlerFunc) Len() int

func (HandlerFunc) ServeDNS

func (f HandlerFunc) ServeDNS(ctx context.Context, w MessageWriter, r *Query)

ServeDNS calls f(w, r).

func (HandlerFunc) Set

func (f HandlerFunc) Set(v map[string]map[Type][]Record)

func (HandlerFunc) SetBeforeDeleteKey

func (f HandlerFunc) SetBeforeDeleteKey(v func(string, map[Type][]Record))

func (HandlerFunc) SetBeforeOnAppendKeyInRecord

func (f HandlerFunc) SetBeforeOnAppendKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (HandlerFunc) SetBeforeOnChange

func (f HandlerFunc) SetBeforeOnChange(v func(Event, string, interface{}, interface{}))

func (HandlerFunc) SetBeforeOnClear

func (f HandlerFunc) SetBeforeOnClear(v func(map[string]map[Type][]Record))

func (HandlerFunc) SetBeforeOnDeleteKeyInRecord

func (f HandlerFunc) SetBeforeOnDeleteKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (HandlerFunc) SetBeforeOnSetKey

func (f HandlerFunc) SetBeforeOnSetKey(v func(string, map[Type][]Record, map[Type][]Record))

func (HandlerFunc) SetKey

func (f HandlerFunc) SetKey(k string, v map[Type][]Record)

func (HandlerFunc) SetOnAppendKeyInRecord

func (f HandlerFunc) SetOnAppendKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (HandlerFunc) SetOnChange

func (f HandlerFunc) SetOnChange(v func(Event, string, interface{}, interface{}))

func (HandlerFunc) SetOnClear

func (f HandlerFunc) SetOnClear(v func(map[string]map[Type][]Record))

func (HandlerFunc) SetOnDeleteKey

func (f HandlerFunc) SetOnDeleteKey(v func(string, map[Type][]Record))

func (HandlerFunc) SetOnDeleteKeyInRecord

func (f HandlerFunc) SetOnDeleteKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (HandlerFunc) SetOnSetKey

func (f HandlerFunc) SetOnSetKey(v func(string, map[Type][]Record, map[Type][]Record))

type MX

type MX struct {
	Pref int
	MX   string
	// contains filtered or unexported fields
}

MX is a DNS MX record.

func (*MX) FromJSon

func (m *MX) FromJSon(v string) error

func (*MX) Get

func (m *MX) Get() interface{}

func (MX) Length

func (m MX) Length(com Compressor) (int, error)

Length returns the encoded RDATA size.

func (MX) Pack

func (m MX) Pack(b []byte, com Compressor) ([]byte, error)

Pack encodes m as RDATA.

func (*MX) String

func (m *MX) String() string

func (MX) Type

func (MX) Type() Type

Type returns the RR type identifier.

func (*MX) Unpack

func (m *MX) Unpack(b []byte, dec Decompressor) ([]byte, error)

Unpack decodes m from RDATA in b.

type Message

type Message struct {
	ID                 int
	Response           bool
	OpCode             OpCode
	Authoritative      bool
	Truncated          bool
	RecursionDesired   bool
	RecursionAvailable bool
	RCode              RCode

	Questions   []Question
	Answers     []Resource
	Authorities []Resource
	Additionals []Resource
}

Message is a DNS message.

func (*Message) Pack

func (m *Message) Pack(b []byte, compress bool) ([]byte, error)

Pack encodes m as a byte slice. If b is not nil, m is appended into b. Domain name compression is enabled by setting compress.

func (*Message) Unpack

func (m *Message) Unpack(b []byte) ([]byte, error)

Unpack decodes m from b. Unused bytes are returned.

type MessageWriter

type MessageWriter interface {
	// Authoritative sets the Authoritative Answer (AA) bit of the header.
	Authoritative(bool)
	// Recursion sets the Recursion Available (RA) bit of the header.
	Recursion(bool)
	// Status sets the Response code (RCODE) bits of the header.
	Status(RCode)

	// Answer adds a record to the answers section.
	Answer(string, time.Duration, Record)
	// Authority adds a record to the authority section.
	Authority(string, time.Duration, Record)
	// Additional adds a record to the additional section
	Additional(string, time.Duration, Record)

	// Recur forwards the request query upstream, and returns the response
	// message or error.
	Recur(context.Context) (*Message, error)

	// Reply sends the response message.
	//
	// For large messages sent over a UDP connection, an ErrTruncatedMessage
	// error is returned if the message was truncated.
	Reply(context.Context) error
}

MessageWriter is used by a DNS handler to serve a DNS query.

type NS

type NS struct {
	NS string
	// contains filtered or unexported fields
}

NS is a DNS MX record.

func (*NS) FromJSon

func (n *NS) FromJSon(v string) error

func (*NS) Get

func (n *NS) Get() interface{}

func (NS) Length

func (n NS) Length(com Compressor) (int, error)

Length returns the encoded RDATA size.

func (NS) Pack

func (n NS) Pack(b []byte, com Compressor) ([]byte, error)

Pack encodes n as RDATA.

func (*NS) String

func (n *NS) String() string

func (NS) Type

func (NS) Type() Type

Type returns the RR type identifier.

func (*NS) Unpack

func (n *NS) Unpack(b []byte, dec Decompressor) ([]byte, error)

Unpack decodes n from RDATA in b.

type NameServers

type NameServers []net.Addr

NameServers is a slice of DNS nameserver addresses.

func (NameServers) Random

func (s NameServers) Random(rand io.Reader) ProxyFunc

Random picks a random Addr from s every time.

func (NameServers) RoundRobin

func (s NameServers) RoundRobin() ProxyFunc

RoundRobin picks the next Addr of s by index of the last pick.

type OPT

type OPT struct {
	Options []edns.Option
	// contains filtered or unexported fields
}

OPT is a DNS OPT record.

func (*OPT) FromJSon

func (o *OPT) FromJSon(v string) error

func (*OPT) Get

func (o *OPT) Get() interface{}

func (OPT) Length

func (o OPT) Length(_ Compressor) (int, error)

Length returns the encoded RDATA size.

func (OPT) Pack

func (o OPT) Pack(b []byte, _ Compressor) ([]byte, error)

Pack encodes o as RDATA.

func (*OPT) String

func (o *OPT) String() string

func (OPT) Type

func (o OPT) Type() Type

Type returns the RR type identifier.

func (*OPT) Unpack

func (o *OPT) Unpack(b []byte, _ Decompressor) ([]byte, error)

Unpack decodes o from RDATA in b.

type OpCode

type OpCode uint16

An OpCode is a DNS operation code.

type OverTLSAddr

type OverTLSAddr struct {
	net.Addr
}

OverTLSAddr indicates the remote DNS service implements DNS-over-TLS as defined in RFC 7858.

func (OverTLSAddr) Network

func (a OverTLSAddr) Network() string

Network returns the address's network name with a "-tls" suffix.

type PTR

type PTR struct {
	PTR string
	// contains filtered or unexported fields
}

PTR is a DNS PTR record.

func (*PTR) FromJSon

func (p *PTR) FromJSon(v string) error

func (*PTR) Get

func (p *PTR) Get() interface{}

func (PTR) Length

func (p PTR) Length(com Compressor) (int, error)

Length returns the encoded RDATA size.

func (PTR) Pack

func (p PTR) Pack(b []byte, com Compressor) ([]byte, error)

Pack encodes p as RDATA.

func (*PTR) String

func (p *PTR) String() string

func (PTR) Type

func (PTR) Type() Type

Type returns the RR type identifier.

func (*PTR) Unpack

func (p *PTR) Unpack(b []byte, dec Decompressor) ([]byte, error)

Unpack decodes p from RDATA in b.

type PacketConn

type PacketConn struct {
	net.Conn
	// contains filtered or unexported fields
}

PacketConn is a packet-oriented network connection to a DNS resolver that expects transmitted messages to adhere to RFC 1035 Section 4.2.1. "UDP usage".

func (*PacketConn) Recv

func (c *PacketConn) Recv(msg *Message) error

Recv reads a DNS message from the underlying connection.

func (*PacketConn) Send

func (c *PacketConn) Send(msg *Message) error

Send writes a DNS message to the underlying connection.

type ProxyFunc

type ProxyFunc func(context.Context, net.Addr) (net.Addr, error)

ProxyFunc modifies the address of a DNS server.

type Query

type Query struct {
	*Message

	// RemoteAddr is the address of a DNS resolver.
	RemoteAddr net.Addr
}

Query is a DNS request message bound for a DNS resolver.

type Question

type Question struct {
	Name  string
	Type  Type
	Class Class
}

A Question is a DNS query.

func (Question) Pack

func (q Question) Pack(b []byte, com Compressor) ([]byte, error)

Pack encodes q as a byte slice. If b is not nil, m is appended into b.

func (*Question) Unpack

func (q *Question) Unpack(b []byte, dec Decompressor) ([]byte, error)

Unpack decodes q from b.

type RCode

type RCode uint16

An RCode is a DNS response status code.

type RRSet

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

RRSet is a set of resource records indexed by record name and record type. RRSet is a thread type safe, preventing more than one operation from being made per time on map type

func (*RRSet) AppendRecordInKey

func (el *RRSet) AppendRecordInKey(k string, r Record)

func (*RRSet) Clear

func (el *RRSet) Clear()

Clear RRSet Antes da função ser executada, a função beforeOnClear( oldRRSet ) é executada Depois da função ser executada, a função onClear( oldRRSet ) é executada Depois da função onClear() ser executada, a função onChange() é executada

func (*RRSet) DeleteKey

func (el *RRSet) DeleteKey(k string)

Delete record by given key

func (*RRSet) DeleteRecordInKey

func (el *RRSet) DeleteRecordInKey(k string, r Record)

Delete record inside a given key

func (*RRSet) GetAll

func (el *RRSet) GetAll() map[string]map[Type][]Record

Get all records

func (*RRSet) GetKey

func (el *RRSet) GetKey(k string) (map[Type][]Record, bool)

Get record by given key

func (*RRSet) Len

func (el *RRSet) Len() int

Get length

func (*RRSet) Set

func (el *RRSet) Set(v map[string]map[Type][]Record)

Set new complete record Antes da função ser executada, a função beforeOnSet( oldRRSet, newRRSet ) é executada Depois da função ser executada, a função onSet( oldRRSet ) é executada Depois da função onSet() ser executada, a função onChange() é executada

func (*RRSet) SetBeforeDeleteKey

func (el *RRSet) SetBeforeDeleteKey(v func(string, map[Type][]Record))

func (*RRSet) SetBeforeOnAppendKeyInRecord

func (el *RRSet) SetBeforeOnAppendKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*RRSet) SetBeforeOnChange

func (el *RRSet) SetBeforeOnChange(v func(Event, string, interface{}, interface{}))

func (*RRSet) SetBeforeOnClear

func (el *RRSet) SetBeforeOnClear(v func(map[string]map[Type][]Record))

func (*RRSet) SetBeforeOnDeleteKeyInRecord

func (el *RRSet) SetBeforeOnDeleteKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*RRSet) SetBeforeOnSetKey

func (el *RRSet) SetBeforeOnSetKey(v func(string, map[Type][]Record, map[Type][]Record))

func (*RRSet) SetKey

func (el *RRSet) SetKey(k string, v map[Type][]Record)

Set a new record on given key

func (*RRSet) SetOnAppendKeyInRecord

func (el *RRSet) SetOnAppendKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*RRSet) SetOnChange

func (el *RRSet) SetOnChange(v func(Event, string, interface{}, interface{}))

func (*RRSet) SetOnClear

func (el *RRSet) SetOnClear(v func(map[string]map[Type][]Record))

func (*RRSet) SetOnDeleteKey

func (el *RRSet) SetOnDeleteKey(v func(string, map[Type][]Record))

func (*RRSet) SetOnDeleteKeyInRecord

func (el *RRSet) SetOnDeleteKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*RRSet) SetOnSetKey

func (el *RRSet) SetOnSetKey(v func(string, map[Type][]Record, map[Type][]Record))

type Record

type Record interface {
	Type() Type
	Length(Compressor) (int, error)
	Pack([]byte, Compressor) ([]byte, error)
	Unpack([]byte, Decompressor) ([]byte, error)
	Get() interface{}
	String() string
	FromJSon(string) error
}

Record is a DNS record.

type ResolveMux

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

ResolveMux is a DNS query multiplexer. It matches a question type and name suffix to a Handler.

func (*ResolveMux) Handle

func (m *ResolveMux) Handle(typ Type, suffix string, h Handler)

Handle registers the handler for the given question type and name suffix.

func (*ResolveMux) ServeDNS

func (m *ResolveMux) ServeDNS(ctx context.Context, w MessageWriter, r *Query)

ServeDNS dispatches the query to the handler(s) whose pattern most closely matches each question.

type Resource

type Resource struct {
	Name  string
	Class Class
	TTL   time.Duration

	Record
}

Resource is a DNS resource record (RR).

func (Resource) Pack

func (r Resource) Pack(b []byte, com Compressor) ([]byte, error)

Pack encodes r onto b.

func (*Resource) Unpack

func (r *Resource) Unpack(b []byte, dec Decompressor) ([]byte, error)

Unpack decodes r from b.

type RoundTripper

type RoundTripper interface {
	Do(context.Context, *Query) (*Message, error)
}

RoundTripper is an interface representing the ability to execute a single DNS transaction, obtaining a response Message for a given Query.

type SOA

type SOA struct {
	NS      string
	MBox    string
	Serial  int
	Refresh time.Duration
	Retry   time.Duration
	Expire  time.Duration
	MinTTL  time.Duration
	// contains filtered or unexported fields
}

SOA is a DNS SOA record.

func (*SOA) FromJSon

func (s *SOA) FromJSon(v string) error

func (*SOA) Get

func (s *SOA) Get() interface{}

func (SOA) Length

func (s SOA) Length(com Compressor) (int, error)

Length returns the encoded RDATA size.

func (SOA) Pack

func (s SOA) Pack(b []byte, com Compressor) ([]byte, error)

Pack encodes s as RDATA.

func (*SOA) String

func (s *SOA) String() string

func (SOA) Type

func (SOA) Type() Type

Type returns the RR type identifier.

func (*SOA) Unpack

func (s *SOA) Unpack(b []byte, dec Decompressor) ([]byte, error)

Unpack decodes s from RDATA in b.

type SRV

type SRV struct {
	Priority int
	Weight   int
	Port     int
	Target   string // Not compressed as per RFC 2782.
	// contains filtered or unexported fields
}

SRV is a DNS SRV record.

func (*SRV) FromJSon

func (s *SRV) FromJSon(v string) error

func (*SRV) Get

func (s *SRV) Get() interface{}

func (SRV) Length

func (s SRV) Length(_ Compressor) (int, error)

Length returns the encoded RDATA size.

func (SRV) Pack

func (s SRV) Pack(b []byte, _ Compressor) ([]byte, error)

Pack encodes s as RDATA.

func (*SRV) String

func (s *SRV) String() string

func (SRV) Type

func (SRV) Type() Type

Type returns the RR type identifier.

func (*SRV) Unpack

func (s *SRV) Unpack(b []byte, _ Decompressor) ([]byte, error)

Unpack decodes s from RDATA in b.

type Server

type Server struct {
	Addr      string      // TCP and UDP address to listen on, ":domain" if empty
	Handler   Handler     // handler to invoke
	TLSConfig *tls.Config // optional TLS config, used by ListenAndServeTLS

	// Forwarder relays a recursive query. If nil, recursive queries are
	// answered with a "Query Refused" message.
	Forwarder RoundTripper

	// ErrorLog specifies an optional logger for errors accepting connections,
	// reading data, and unpacking messages.
	// If nil, logging is done via the log package's standard logger.
	ErrorLog *log.Logger
}

A Server defines parameters for running a DNS server. The zero value for Server is a valid configuration

Example (Authoritative)
package main

import (
	"context"
	"fmt"
	"log"
	"net"
	"time"

	"github.com/benburkert/dns"
)

func main() {
	customTLD := &dns.Zone{
		Origin: "tld.",
		TTL:    time.Hour,
		SOA: &dns.SOA{
			NS:     "dns.tld.",
			MBox:   "hostmaster.tld.",
			Serial: 1234,
		},
		RRs: dns.RRSet{
			"1.app": {
				dns.TypeA: {
					&dns.A{A: net.IPv4(10, 42, 0, 1).To4()},
				},
				dns.TypeAAAA: {
					&dns.AAAA{AAAA: net.ParseIP("dead:beef::1")},
				},
			},
			"2.app": {
				dns.TypeA: {
					&dns.A{A: net.IPv4(10, 42, 0, 2).To4()},
				},
				dns.TypeAAAA: {
					&dns.AAAA{AAAA: net.ParseIP("dead:beef::2")},
				},
			},
			"3.app": {
				dns.TypeA: {
					&dns.A{A: net.IPv4(10, 42, 0, 3).To4()},
				},
				dns.TypeAAAA: {
					&dns.AAAA{AAAA: net.ParseIP("dead:beef::3")},
				},
			},
			"app": {
				dns.TypeA: {
					&dns.A{A: net.IPv4(10, 42, 0, 1).To4()},
					&dns.A{A: net.IPv4(10, 42, 0, 2).To4()},
					&dns.A{A: net.IPv4(10, 42, 0, 3).To4()},
				},
				dns.TypeAAAA: {
					&dns.AAAA{AAAA: net.ParseIP("dead:beef::1")},
					&dns.AAAA{AAAA: net.ParseIP("dead:beef::2")},
					&dns.AAAA{AAAA: net.ParseIP("dead:beef::3")},
				},
			},
		},
	}

	srv := &dns.Server{
		Addr:    ":53351",
		Handler: customTLD,
	}

	go srv.ListenAndServe(context.Background())
	time.Sleep(100 * time.Millisecond) // wait for bind()

	addr, err := net.ResolveTCPAddr("tcp", srv.Addr)
	if err != nil {
		log.Fatal(err)
	}

	query := &dns.Query{
		RemoteAddr: addr,
		Message: &dns.Message{
			Questions: []dns.Question{
				{
					Name:  "app.tld.",
					Type:  dns.TypeA,
					Class: dns.ClassIN,
				},
				{
					Name:  "app.tld.",
					Type:  dns.TypeAAAA,
					Class: dns.ClassIN,
				},
			},
		},
	}

	res, err := new(dns.Client).Do(context.Background(), query)
	if err != nil {
		log.Fatal(err)
	}

	for _, answer := range res.Answers {
		switch rec := answer.Record.(type) {
		case *dns.A:
			fmt.Println(rec.A)
		case *dns.AAAA:
			fmt.Println(rec.AAAA)
		default:
			fmt.Println(rec)
		}
	}

}
Output:

10.42.0.1
10.42.0.2
10.42.0.3
dead:beef::1
dead:beef::2
dead:beef::3
Example (Recursive)
package main

import (
	"context"
	"fmt"
	"log"
	"net"
	"time"

	"github.com/benburkert/dns"
)

func main() {
	srv := &dns.Server{
		Addr:    ":53352",
		Handler: dns.HandlerFunc(dns.Recursor),
		Forwarder: &dns.Client{
			Transport: &dns.Transport{
				Proxy: dns.NameServers{
					&net.TCPAddr{IP: net.IPv4(8, 8, 8, 8), Port: 53},
					&net.TCPAddr{IP: net.IPv4(8, 8, 4, 4), Port: 53},
					&net.UDPAddr{IP: net.IPv4(8, 8, 8, 8), Port: 53},
					&net.UDPAddr{IP: net.IPv4(8, 8, 4, 4), Port: 53},
				}.RoundRobin(),
			},
			Resolver: new(dns.Cache),
		},
	}

	go srv.ListenAndServe(context.Background())
	time.Sleep(100 * time.Millisecond) // wait for bind()

	addr, err := net.ResolveTCPAddr("tcp", srv.Addr)
	if err != nil {
		log.Fatal(err)
	}

	query := &dns.Query{
		RemoteAddr: addr,
		Message: &dns.Message{
			RecursionDesired: true,
			Questions: []dns.Question{
				{
					Name:  "127.1.2.3.xip.io.",
					Type:  dns.TypeA,
					Class: dns.ClassIN,
				},
			},
		},
	}

	res, err := new(dns.Client).Do(context.Background(), query)
	if err != nil {
		log.Fatal(err)
	}

	for _, answer := range res.Answers {
		switch rec := answer.Record.(type) {
		case *dns.A:
			fmt.Println(rec.A)
		default:
			fmt.Println(rec)
		}
	}

}
Output:

127.1.2.3
Example (RecursiveWithZone)
package main

import (
	"context"
	"fmt"
	"log"
	"net"
	"time"

	"github.com/benburkert/dns"
)

func main() {
	customTLD := &dns.Zone{
		Origin: "tld.",
		RRs: dns.RRSet{
			"foo": {
				dns.TypeA: {
					&dns.A{A: net.IPv4(127, 0, 0, 1).To4()},
				},
			},
		},
	}

	mux := new(dns.ResolveMux)
	mux.Handle(dns.TypeANY, "tld.", customTLD)

	srv := &dns.Server{
		Addr:    ":53353",
		Handler: mux,
		Forwarder: &dns.Client{
			Transport: &dns.Transport{
				Proxy: dns.NameServers{
					&net.TCPAddr{IP: net.IPv4(8, 8, 8, 8), Port: 53},
					&net.TCPAddr{IP: net.IPv4(8, 8, 8, 8), Port: 53},
					&net.UDPAddr{IP: net.IPv4(8, 8, 4, 4), Port: 53},
					&net.UDPAddr{IP: net.IPv4(8, 8, 4, 4), Port: 53},
				}.RoundRobin(),
			},
			Resolver: new(dns.Cache),
		},
	}

	go srv.ListenAndServe(context.Background())
	time.Sleep(100 * time.Millisecond) // wait for bind()

	addr, err := net.ResolveTCPAddr("tcp", srv.Addr)
	if err != nil {
		log.Fatal(err)
	}

	query := &dns.Query{
		RemoteAddr: addr,
		Message: &dns.Message{
			RecursionDesired: true,
			Questions: []dns.Question{
				{
					Name:  "127.0.0.127.xip.io.",
					Type:  dns.TypeA,
					Class: dns.ClassIN,
				},
				{
					Name:  "foo.tld.",
					Type:  dns.TypeA,
					Class: dns.ClassIN,
				},
			},
		},
	}

	res, err := new(dns.Client).Do(context.Background(), query)
	if err != nil {
		log.Fatal(err)
	}

	for _, answer := range res.Answers {
		switch rec := answer.Record.(type) {
		case *dns.A:
			fmt.Println(rec.A)
		default:
			fmt.Println(rec)
		}
	}

}
Output:

127.0.0.127
127.0.0.1

func (*Server) AppendRecordInKey

func (s *Server) AppendRecordInKey(k string, r Record)

func (*Server) Clear

func (s *Server) Clear()

func (*Server) DeleteKey

func (s *Server) DeleteKey(k string)

func (*Server) DeleteRecordInKey

func (s *Server) DeleteRecordInKey(k string, r Record)

func (*Server) GetAll

func (s *Server) GetAll() map[string]map[Type][]Record

func (*Server) GetKey

func (s *Server) GetKey(k string) (map[Type][]Record, bool)

func (*Server) Len

func (s *Server) Len() int

func (*Server) ListenAndServe

func (s *Server) ListenAndServe(ctx context.Context) error

ListenAndServe listens on both the TCP and UDP network address s.Addr and then calls Serve or ServePacket to handle queries on incoming connections. If srv.Addr is blank, ":domain" is used. ListenAndServe always returns a non-nil error.

func (*Server) ListenAndServeTLS

func (s *Server) ListenAndServeTLS(ctx context.Context) error

ListenAndServeTLS listens on the TCP network address s.Addr and then calls Serve to handle requests on incoming TLS connections.

If s.Addr is blank, ":853" is used.

ListenAndServeTLS always returns a non-nil error.

func (*Server) Serve

func (s *Server) Serve(ctx context.Context, ln net.Listener) error

Serve accepts incoming connections on the Listener ln, creating a new service goroutine for each. The service goroutines read TCP encoded queries and then call s.Handler to reply to them.

See RFC 1035, section 4.2.2 "TCP usage" for transport encoding of messages.

Serve always returns a non-nil error.

func (*Server) ServePacket

func (s *Server) ServePacket(ctx context.Context, conn net.PacketConn) error

ServePacket reads UDP encoded queries from the PacketConn conn, creating a new service goroutine for each. The service goroutines call s.Handler to reply.

See RFC 1035, section 4.2.1 "UDP usage" for transport encoding of messages.

ServePacket always returns a non-nil error.

func (*Server) ServeTLS

func (s *Server) ServeTLS(ctx context.Context, ln net.Listener) error

ServeTLS accepts incoming connections on the Listener ln, creating a new service goroutine for each. The service goroutines read TCP encoded queries over a TLS channel and then call s.Handler to reply to them, in another service goroutine.

See RFC 7858, section 3.3 for transport encoding of messages.

ServeTLS always returns a non-nil error.

func (*Server) Set

func (s *Server) Set(v map[string]map[Type][]Record)

func (*Server) SetBeforeDeleteKey

func (el *Server) SetBeforeDeleteKey(v func(string, map[Type][]Record))

func (*Server) SetBeforeOnAppendKeyInRecord

func (el *Server) SetBeforeOnAppendKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*Server) SetBeforeOnChange

func (el *Server) SetBeforeOnChange(v func(Event, string, interface{}, interface{}))

func (*Server) SetBeforeOnClear

func (el *Server) SetBeforeOnClear(v func(map[string]map[Type][]Record))

func (*Server) SetBeforeOnDeleteKeyInRecord

func (el *Server) SetBeforeOnDeleteKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*Server) SetBeforeOnSetKey

func (el *Server) SetBeforeOnSetKey(v func(string, map[Type][]Record, map[Type][]Record))

func (*Server) SetKey

func (s *Server) SetKey(k string, v map[Type][]Record)

func (*Server) SetOnAppendKeyInRecord

func (el *Server) SetOnAppendKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*Server) SetOnChange

func (el *Server) SetOnChange(v func(Event, string, interface{}, interface{}))

func (*Server) SetOnClear

func (el *Server) SetOnClear(v func(map[string]map[Type][]Record))

func (*Server) SetOnDeleteKey

func (el *Server) SetOnDeleteKey(v func(string, map[Type][]Record))

func (*Server) SetOnDeleteKeyInRecord

func (el *Server) SetOnDeleteKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*Server) SetOnSetKey

func (el *Server) SetOnSetKey(v func(string, map[Type][]Record, map[Type][]Record))

type StreamConn

type StreamConn struct {
	net.Conn
	// contains filtered or unexported fields
}

StreamConn is a stream-oriented network connection to a DNS resolver that expects transmitted messages to adhere to RFC 1035 Section 4.2.2. "TCP usage".

func (*StreamConn) Recv

func (c *StreamConn) Recv(msg *Message) error

Recv reads a DNS message from the underlying connection.

func (*StreamConn) Send

func (c *StreamConn) Send(msg *Message) error

Send writes a DNS message to the underlying connection.

type TXT

type TXT struct {
	TXT []string
	// contains filtered or unexported fields
}

TXT is a DNS TXT record.

func (*TXT) FromJSon

func (t *TXT) FromJSon(v string) error

func (*TXT) Get

func (t *TXT) Get() interface{}

func (TXT) Length

func (t TXT) Length(_ Compressor) (int, error)

Length returns the encoded RDATA size.

func (TXT) Pack

func (t TXT) Pack(b []byte, _ Compressor) ([]byte, error)

Pack encodes t as RDATA.

func (*TXT) String

func (t *TXT) String() string

func (TXT) Type

func (TXT) Type() Type

Type returns the RR type identifier.

func (*TXT) Unpack

func (t *TXT) Unpack(b []byte, _ Decompressor) ([]byte, error)

Unpack decodes t from RDATA in b.

type Transport

type Transport struct {
	TLSConfig *tls.Config // optional TLS config, used by DialAddr

	// DialContext func creates the underlying net connection. The DialContext
	// method of a new net.Dialer is used by default.
	DialContext func(context.Context, string, string) (net.Conn, error)

	// Proxy modifies the address of the DNS server to dial.
	Proxy ProxyFunc

	// DisablePipelining disables query pipelining for stream oriented
	// connections as defined in RFC 7766, section 6.2.1.1.
	DisablePipelining bool
	// contains filtered or unexported fields
}

Transport is an implementation of AddrDialer that manages connections to DNS servers. Transport may modify the sending and receiving of messages but does not modify messages.

func (*Transport) DialAddr

func (t *Transport) DialAddr(ctx context.Context, addr net.Addr) (Conn, error)

DialAddr dials a net Addr and returns a Conn.

type Type

type Type uint16

A Type is a type of DNS request and response.

func (Type) String

func (el Type) String() string

type Zone

type Zone struct {
	Origin string
	TTL    time.Duration

	SOA *SOA

	RRs RRSet
}

Zone is a contiguous set DNS records under an origin domain name.

func (*Zone) AppendRecordInKey

func (z *Zone) AppendRecordInKey(k string, r Record)

func (*Zone) Clear

func (z *Zone) Clear()

func (*Zone) DeleteKey

func (z *Zone) DeleteKey(k string)

func (*Zone) DeleteRecordInKey

func (z *Zone) DeleteRecordInKey(k string, r Record)

func (*Zone) GetAll

func (z *Zone) GetAll() map[string]map[Type][]Record

func (*Zone) GetKey

func (z *Zone) GetKey(k string) (map[Type][]Record, bool)

func (*Zone) Len

func (z *Zone) Len() int

func (*Zone) ServeDNS

func (z *Zone) ServeDNS(ctx context.Context, w MessageWriter, r *Query)

ServeDNS answers DNS queries in zone z.

func (*Zone) Set

func (z *Zone) Set(v map[string]map[Type][]Record)

func (*Zone) SetBeforeDeleteKey

func (z *Zone) SetBeforeDeleteKey(v func(string, map[Type][]Record))

func (*Zone) SetBeforeOnAppendKeyInRecord

func (z *Zone) SetBeforeOnAppendKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*Zone) SetBeforeOnChange

func (z *Zone) SetBeforeOnChange(v func(Event, string, interface{}, interface{}))

func (*Zone) SetBeforeOnClear

func (z *Zone) SetBeforeOnClear(v func(map[string]map[Type][]Record))

func (*Zone) SetBeforeOnDeleteKeyInRecord

func (z *Zone) SetBeforeOnDeleteKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*Zone) SetBeforeOnSetKey

func (z *Zone) SetBeforeOnSetKey(v func(string, map[Type][]Record, map[Type][]Record))

func (*Zone) SetKey

func (z *Zone) SetKey(k string, v map[Type][]Record)

func (*Zone) SetOnAppendKeyInRecord

func (z *Zone) SetOnAppendKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*Zone) SetOnChange

func (z *Zone) SetOnChange(v func(Event, string, interface{}, interface{}))

func (*Zone) SetOnClear

func (z *Zone) SetOnClear(v func(map[string]map[Type][]Record))

func (*Zone) SetOnDeleteKey

func (z *Zone) SetOnDeleteKey(v func(string, map[Type][]Record))

func (*Zone) SetOnDeleteKeyInRecord

func (z *Zone) SetOnDeleteKeyInRecord(v func(string, map[Type][]Record, map[Type][]Record))

func (*Zone) SetOnSetKey

func (z *Zone) SetOnSetKey(v func(string, map[Type][]Record, map[Type][]Record))

Directories

Path Synopsis
Package edns provides EDNS0 (RFC6891) support.
Package edns provides EDNS0 (RFC6891) support.
Package init intercepts DNS queries generated by the default net Resolver.
Package init intercepts DNS queries generated by the default net Resolver.
internal

Jump to

Keyboard shortcuts

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