fastdns

package module
v0.8.2 Latest Latest
Warning

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

Go to latest
Published: Nov 26, 2023 License: MIT Imports: 14 Imported by: 5

README

Fast DNS implementation for Go

godoc release goreport coverage

Features

  • 0 Dependency
  • Similar Interface with net/http
  • Fast DoH Server Co-create with fasthttp
  • Fast DNS Client with rich features
  • Compatible metrics with coredns
  • High Performance
    • 0-allocs dns request parser
    • 0-allocs dns records marshaller
    • worker pool + message pool
    • prefork + reuse_port + set_affinity

Getting Started

DNS Server
package main

import (
	"log"
	"net"
	"net/netip"
	"os"

	"github.com/phuslu/fastdns"
)

type DNSHandler struct {
	Debug bool
}

func (h *DNSHandler) ServeDNS(rw fastdns.ResponseWriter, req *fastdns.Message) {
	if h.Debug {
		log.Printf("%s: CLASS %s TYPE %s\n", req.Domain, req.Question.Class, req.Question.Type)
	}

	switch req.Question.Type {
	case fastdns.TypeA:
		fastdns.HOST1(rw, req, 60, netip.AddrFrom4([4]byte{8, 8, 8, 8}))
	case fastdns.TypeAAAA:
		fastdns.HOST(rw, req, 60, []netip.Addr{netip.MustParseAddr("2001:4860:4860::8888")})
	case fastdns.TypeCNAME:
		fastdns.CNAME(rw, req, 60, []string{"dns.google"}, []netip.Addr{netip.MustParseAddr("8.8.8.8")})
	case fastdns.TypeSRV:
		fastdns.SRV(rw, req, 60, []net.SRV{{"www.google.com", 443, 1000, 1000}})
	case fastdns.TypeNS:
		fastdns.NS(rw, req, 60, []net.NS{{"ns1.google.com"}, {"ns2.google.com"}})
	case fastdns.TypeMX:
		fastdns.MX(rw, req, 60, []net.MX{{"mail.gmail.com", 10}, {"smtp.gmail.com", 10}})
	case fastdns.TypeSOA:
		fastdns.SOA(rw, req, 60, net.NS{"ns1.google"}, net.NS{"ns2.google"}, 60, 90, 90, 180, 60)
	case fastdns.TypePTR:
		fastdns.PTR(rw, req, 0, "ptr.google.com")
	case fastdns.TypeTXT:
		fastdns.TXT(rw, req, 60, "greetingfromgoogle")
	default:
		fastdns.Error(rw, req, fastdns.RcodeNXDomain)
	}
}

func main() {
	addr := ":53"

	server := &fastdns.ForkServer{
		Handler: &DNSHandler{
			Debug: os.Getenv("DEBUG") != "",
		},
		Stats: &fastdns.CoreStats{
			Prefix: "coredns_",
			Family: "1",
			Proto:  "udp",
			Server: "dns://" + addr,
			Zone:   ".",
		},
		ErrorLog: log.Default(),
	}

	err := server.ListenAndServe(addr)
	if err != nil {
		log.Fatalf("dnsserver error: %+v", err)
	}
}
DNS Client
$ go install github.com/phuslu/fastdns/cmd/fastdig@master
$ fastdig ip.phus.lu @8.8.8.8

; <<>> DiG 0.0.1-Fastdns <<>> ip.phus.lu
;; global options: +cmd +noedns
;; Got answer:
;; ->>HEADER<<- opcode: Query, status: Success, id: 2775
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;ip.phus.lu.            IN      A

;; ANSWER SECTION:
ip.phus.lu.     299     IN      CNAME   phus.lu.
phus.lu.        299     IN      A       101.32.116.118

;; Query time: 15 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Apr 12 22:07:16 +08 2021
;; MSG SIZE  rcvd: 58
DoH Server
$ go install github.com/phuslu/fastdns/cmd/fastdoh@master
$ fastdoh :8080

High Performance

A Performance result as below, for daily benchmark results see github actions

# go test -v -cpu=1 -run=none -benchmem -bench=.
goos: linux
goarch: amd64
pkg: github.com/phuslu/fastdns
cpu: Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz

BenchmarkHOST                	46537387	        25.77 ns/op	       0 B/op	       0 allocs/op
BenchmarkCNAME               	26925482	        44.65 ns/op	       0 B/op	       0 allocs/op
BenchmarkSRV                 	24188922	        49.45 ns/op	       0 B/op	       0 allocs/op
BenchmarkNS                  	19585800	        61.42 ns/op	       0 B/op	       0 allocs/op
BenchmarkSOA                 	16609441	        72.44 ns/op	       0 B/op	       0 allocs/op
BenchmarkPTR                 	33774684	        35.57 ns/op	       0 B/op	       0 allocs/op
BenchmarkMX                  	30105150	        39.84 ns/op	       0 B/op	       0 allocs/op
BenchmarkTXT                 	51116004	        22.45 ns/op	       0 B/op	       0 allocs/op
BenchmarkParseMessage        	56425442	        21.32 ns/op	       0 B/op	       0 allocs/op
BenchmarkSetQuestion         	32210199	        36.20 ns/op	       0 B/op	       0 allocs/op
BenchmarkSetResponseHeader   	238730137	         5.037 ns/op	       0 B/op	       0 allocs/op
BenchmarkDecodeName          	36813590	        32.48 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendHOSTRecord    	73487632	        16.07 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendCNAMERecord   	34382904	        35.39 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendSRVRecord     	28153548	        41.41 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendNSRecord      	22970529	        52.26 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendSOARecord     	19043780	        62.86 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendPTRRecord     	44801985	        26.81 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendMXRecord      	38313138	        30.91 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendTXTRecord     	89567190	        13.43 ns/op	       0 B/op	       0 allocs/op
BenchmarkUpdateStats         	16593826	        72.32 ns/op	       0 B/op	       0 allocs/op
BenchmarkEncodeDomain        	74937819	        15.95 ns/op	       0 B/op	       0 allocs/op

PASS
ok  	github.com/phuslu/fastdns	19.026s

Here is the real-world flamegraph flamegraph when fastdns reaches 1.4M QPS on a single machine with Xeon 4216 and Intel X710.

Acknowledgment

This dns server is inspired by fasthttp, rawdns and miekg/dns.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidHeader is returned when dns message does not have the expected header size.
	ErrInvalidHeader = errors.New("dns message does not have the expected header size")
	// ErrInvalidQuestion is returned when dns message does not have the expected question size.
	ErrInvalidQuestion = errors.New("dns message does not have the expected question size")
	// ErrInvalidAnswer is returned when dns message does not have the expected answer size.
	ErrInvalidAnswer = errors.New("dns message does not have the expected answer size")
)
View Source
var (
	// ErrMaxConns is returned when dns client reaches the max connections limitation.
	ErrMaxConns = errors.New("dns client reaches the max connections limitation")
)

Functions

func AppendCNAMERecord added in v0.3.2

func AppendCNAMERecord(dst []byte, req *Message, ttl uint32, cnames []string, ips []netip.Addr) []byte

AppendCNAMERecord appends the CNAME and Host records to dst and returns the resulting dst.

func AppendHOST1Record added in v0.8.2

func AppendHOST1Record(dst []byte, req *Message, ttl uint32, ip netip.Addr) []byte

AppendHOST1Record appends a Host records to dst and returns the resulting dst.

func AppendHOSTRecord added in v0.6.2

func AppendHOSTRecord(dst []byte, req *Message, ttl uint32, ips []netip.Addr) []byte

AppendHOSTRecord appends the Host records to dst and returns the resulting dst.

func AppendMXRecord

func AppendMXRecord(dst []byte, req *Message, ttl uint32, mxs []net.MX) []byte

AppendMXRecord appends the MX records to dst and returns the resulting dst.

func AppendNSRecord added in v0.3.2

func AppendNSRecord(dst []byte, req *Message, ttl uint32, nameservers []net.NS) []byte

AppendNSRecord appends the NS records to dst and returns the resulting dst.

func AppendPTRRecord

func AppendPTRRecord(dst []byte, req *Message, ttl uint32, ptr string) []byte

AppendPTRRecord appends the PTR records to dst and returns the resulting dst.

func AppendSOARecord added in v0.3.2

func AppendSOARecord(dst []byte, req *Message, ttl uint32, mname, rname net.NS, serial, refresh, retry, expire, minimum uint32) []byte

AppendSOARecord appends the SOA records to dst and returns the resulting dst.

func AppendSRVRecord

func AppendSRVRecord(dst []byte, req *Message, ttl uint32, srvs []net.SRV) []byte

AppendSRVRecord appends the SRV records to dst and returns the resulting dst.

func AppendTXTRecord

func AppendTXTRecord(dst []byte, req *Message, ttl uint32, txt string) []byte

AppendTXTRecord appends the TXT records to dst and returns the resulting dst.

func CNAME

func CNAME(rw ResponseWriter, req *Message, ttl uint32, cnames []string, ips []netip.Addr)

CNAME replies to the request with the specified CName and Host records.

func EncodeDomain added in v0.0.8

func EncodeDomain(dst []byte, domain string) []byte

EncodeDomain encodes domain to dst.

func Error

func Error(rw ResponseWriter, req *Message, rcode Rcode)

Error replies to the request with the specified Rcode.

func HOST added in v0.0.3

func HOST(rw ResponseWriter, req *Message, ttl uint32, ips []netip.Addr)

HOST replies to the request with the specified Host records.

func HOST1 added in v0.8.2

func HOST1(rw ResponseWriter, req *Message, ttl uint32, ip netip.Addr)

HOST1 replies to the request with the specified Host record.

func MX

func MX(rw ResponseWriter, req *Message, ttl uint32, mxs []net.MX)

MX replies to the request with the specified MX records.

func NS added in v0.3.2

func NS(rw ResponseWriter, req *Message, ttl uint32, nameservers []net.NS)

NS replies to the request with the specified CName and Host records.

func PTR

func PTR(rw ResponseWriter, req *Message, ttl uint32, ptr string)

PTR replies to the request with the specified PTR records.

func ParseMessage added in v0.3.0

func ParseMessage(dst *Message, payload []byte, copying bool) error

ParseMessage parses dns request from payload into dst and returns the error.

func ReleaseMessage added in v0.3.0

func ReleaseMessage(msg *Message)

ReleaseMessage returnes the dns request to the pool.

func SOA added in v0.3.2

func SOA(rw ResponseWriter, req *Message, ttl uint32, mname, rname net.NS, serial, refresh, retry, expire, minimum uint32)

SOA replies to the request with the specified SOA records.

func SRV

func SRV(rw ResponseWriter, req *Message, ttl uint32, srvs []net.SRV)

SRV replies to the request with the specified SRV records.

func TXT

func TXT(rw ResponseWriter, req *Message, ttl uint32, txt string)

TXT replies to the request with the specified TXT records.

Types

type Class

type Class uint16

Class is a DNS class.

const (
	ClassINET   Class = 1
	ClassCSNET  Class = 2
	ClassCHAOS  Class = 3
	ClassHESIOD Class = 4
	ClassNONE   Class = 254
	ClassANY    Class = 255
)

Wire constants and supported types.

func (Class) String

func (c Class) String() string

type Client added in v0.3.4

type Client struct {
	AddrPort netip.AddrPort

	// MaxIdleConns controls the maximum number of idle (keep-alive)
	// connections. Zero means no limit.
	MaxIdleConns int

	// MaxConns optionally limits the total number of
	// connections per host, including connections in the dialing,
	// active, and idle states. On limit violation, ErrMaxConns will be return.
	//
	// Zero means no limit.
	MaxConns int

	// ReadTimeout is the maximum duration for reading the dns server response.
	ReadTimeout time.Duration
	// contains filtered or unexported fields
}

Client is an UDP client that supports DNS protocol.

func (*Client) Exchange added in v0.3.4

func (c *Client) Exchange(req, resp *Message) (err error)

Exchange executes a single DNS transaction, returning a Response for the provided Request.

type CoreStats added in v0.6.0

type CoreStats struct {
	RequestCountTotal uint64

	RequestDurationSecondsBucket_0_00025 uint64
	RequestDurationSecondsBucket_0_0005  uint64
	RequestDurationSecondsBucket_0_001   uint64
	RequestDurationSecondsBucket_0_002   uint64
	RequestDurationSecondsBucket_0_004   uint64
	RequestDurationSecondsBucket_0_008   uint64
	RequestDurationSecondsBucket_0_016   uint64
	RequestDurationSecondsBucket_0_032   uint64
	RequestDurationSecondsBucket_0_064   uint64
	RequestDurationSecondsBucket_0_128   uint64
	RequestDurationSecondsBucket_0_256   uint64
	RequestDurationSecondsBucket_0_512   uint64
	RequestDurationSecondsBucket_1_024   uint64
	RequestDurationSecondsBucket_2_048   uint64
	RequestDurationSecondsBucket_4_096   uint64
	RequestDurationSecondsBucket_8_192   uint64
	RequestDurationSecondsBucket_Inf     uint64
	RequestDurationSecondsSum            uint64
	RequestDurationSecondsCount          uint64

	RequestSizeBytesBucket_0     uint64
	RequestSizeBytesBucket_100   uint64
	RequestSizeBytesBucket_200   uint64
	RequestSizeBytesBucket_300   uint64
	RequestSizeBytesBucket_400   uint64
	RequestSizeBytesBucket_511   uint64
	RequestSizeBytesBucket_1023  uint64
	RequestSizeBytesBucket_2047  uint64
	RequestSizeBytesBucket_4095  uint64
	RequestSizeBytesBucket_8291  uint64
	RequestSizeBytesBucket_16000 uint64
	RequestSizeBytesBucket_32000 uint64
	RequestSizeBytesBucket_48000 uint64
	RequestSizeBytesBucket_64000 uint64
	RequestSizeBytesBucket_Inf   uint64
	RequestSizeBytesSum          uint64
	RequestSizeBytesCount        uint64

	RequestTypeCountTotal_A     uint64
	RequestTypeCountTotal_AAAA  uint64
	RequestTypeCountTotal_NS    uint64
	RequestTypeCountTotal_PTR   uint64
	RequestTypeCountTotal_SRV   uint64
	RequestTypeCountTotal_CNAME uint64
	RequestTypeCountTotal_SOA   uint64
	RequestTypeCountTotal_MX    uint64
	RequestTypeCountTotal_TXT   uint64

	ResponseRcodeCountTotal_NOERROR  uint64
	ResponseRcodeCountTotal_FORMERR  uint64
	ResponseRcodeCountTotal_SERVFAIL uint64
	ResponseRcodeCountTotal_NOTIMP   uint64
	ResponseRcodeCountTotal_NXDOMAIN uint64
	ResponseRcodeCountTotal_REFUSED  uint64
	ResponseRcodeCountTotal_YXDOMAIN uint64
	ResponseRcodeCountTotal_XRRSET   uint64
	ResponseRcodeCountTotal_NOTAUTH  uint64
	ResponseRcodeCountTotal_NOTZONE  uint64

	ResponseSizeBytesBucket_0     uint64
	ResponseSizeBytesBucket_100   uint64
	ResponseSizeBytesBucket_200   uint64
	ResponseSizeBytesBucket_300   uint64
	ResponseSizeBytesBucket_400   uint64
	ResponseSizeBytesBucket_511   uint64
	ResponseSizeBytesBucket_1023  uint64
	ResponseSizeBytesBucket_2047  uint64
	ResponseSizeBytesBucket_4095  uint64
	ResponseSizeBytesBucket_8291  uint64
	ResponseSizeBytesBucket_16000 uint64
	ResponseSizeBytesBucket_32000 uint64
	ResponseSizeBytesBucket_48000 uint64
	ResponseSizeBytesBucket_64000 uint64
	ResponseSizeBytesBucket_Inf   uint64
	ResponseSizeBytesSum          uint64
	ResponseSizeBytesCount        uint64

	Prefix, Family, Proto, Server, Zone string
}

func (*CoreStats) AppendOpenMetrics added in v0.6.1

func (s *CoreStats) AppendOpenMetrics(dst []byte) []byte

func (*CoreStats) UpdateStats added in v0.6.0

func (s *CoreStats) UpdateStats(addr netip.AddrPort, msg *Message, duration time.Duration)

type Flags added in v0.6.2

type Flags uint16

Flags is an arbitrary 16bit represents QR, Opcode, AA, TC, RD, RA, Z and RCODE.

0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

func (Flags) AA added in v0.6.2

func (f Flags) AA() byte

AA is AA bit in Flags

func (Flags) Opcode added in v0.6.2

func (f Flags) Opcode() Opcode

Opcode is Opcode in Flags

func (Flags) QR added in v0.6.2

func (f Flags) QR() byte

QR is QR bit in Flags

func (Flags) RA added in v0.6.2

func (f Flags) RA() byte

RA is RA bit in Flags

func (Flags) RD added in v0.6.2

func (f Flags) RD() byte

RD is RD bit in Flags

func (Flags) Rcode added in v0.6.2

func (f Flags) Rcode() Rcode

Rcode is Rcode in Flags

func (Flags) TC added in v0.6.2

func (f Flags) TC() byte

TC is TC bit in Flags

func (Flags) Z added in v0.6.2

func (f Flags) Z() byte

Z is Z bits in Flags

type ForkServer

type ForkServer struct {
	// handler to invoke
	Handler Handler

	// stats to invoke
	Stats Stats

	// ErrorLog specifies an optional logger for errors accepting
	// connections, unexpected behavior from handlers, and
	// underlying FileSystem errors.
	// If nil, logging is done via the log package's standard logger.
	ErrorLog *log.Logger

	// The maximum number of procs the server may spawn. use runtime.NumCPU() if empty
	MaxProcs int

	// SetAffinity sets the CPU affinity mask of current process.
	SetAffinity bool

	// The maximum number of concurrent clients the server may serve.
	Concurrency int
}

ForkServer implements a prefork DNS server.

func (*ForkServer) Index

func (s *ForkServer) Index() (index int)

Index indicates the index of Server instances.

func (*ForkServer) ListenAndServe

func (s *ForkServer) ListenAndServe(addr string) error

ListenAndServe serves DNS requests from the given UDP addr.

type Handler

type Handler interface {
	ServeDNS(rw ResponseWriter, req *Message)
}

Handler is implemented by any value that implements ServeDNS.

type MemResponseWriter added in v0.6.3

type MemResponseWriter struct {
	Data  []byte
	Raddr netip.AddrPort
	Laddr netip.AddrPort
}

MemResponseWriter is an implementation of ResponseWriter that supports write response to memory.

func (*MemResponseWriter) LocalAddr added in v0.6.3

func (rw *MemResponseWriter) LocalAddr() netip.AddrPort

LocalAddr returns the netip.AddrPort of the server

func (*MemResponseWriter) RemoteAddr added in v0.6.3

func (rw *MemResponseWriter) RemoteAddr() netip.AddrPort

RemoteAddr returns the netip.AddrPort of the client that sent the current request.

func (*MemResponseWriter) Write added in v0.6.3

func (rw *MemResponseWriter) Write(p []byte) (n int, err error)

Write writes a raw buffer back to the memory buffer.

type Message added in v0.3.0

type Message struct {
	// Raw refers to the raw query packet.
	Raw []byte

	// Domain represents to the parsed query domain in the query.
	Domain []byte

	// Header encapsulates the construct of the header part of the DNS query message.
	// It follows the conventions stated at RFC1035 section 4.1.1.
	Header struct {
		// ID is an arbitrary 16bit request identifier that is
		// forwarded back in the response so that we can match them up.
		//
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |                      ID                       |
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		ID uint16

		// Flags is an arbitrary 16bit represents QR, Opcode, AA, TC, RD, RA, Z and RCODE.
		//
		//   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		Flags Flags

		// QDCOUNT specifies the number of entries in the question section
		//
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |                    QDCOUNT                    |
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		QDCount uint16

		// ANCount specifies the number of resource records (RR) in the answer section
		//
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |                    ANCOUNT                    |
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		ANCount uint16

		// NSCount specifies the number of name server resource records in the authority section
		//
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |                    NSCOUNT                    |
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		NSCount uint16

		// ARCount specifies the number of resource records in the additional records section
		//
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |                    ARCOUNT                    |
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		ARCount uint16
	}

	// Question encapsulates the construct of the question part of the DNS query message.
	// It follows the conventions stated at RFC1035 section 4.1.2.
	Question struct {
		// Name refers to the raw query name to be resolved in the query.
		//
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |                                               |
		// /                     QNAME                     /
		// /                                               /
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		Name []byte

		// Type specifies the type of the query to perform.
		//
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |                     QTYPE                     |
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		Type Type

		// Class specifies the class of the query to perform.
		//
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		// |                     QCLASS                    |
		// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
		Class Class
	}
}

Message represents an DNS request received by a server or to be sent by a client.

func AcquireMessage added in v0.3.0

func AcquireMessage() *Message

AcquireMessage returns new dns request.

func (*Message) DecodeName added in v0.3.3

func (msg *Message) DecodeName(dst []byte, name []byte) []byte

DecodeName decodes dns labels to dst.

func (*Message) SetRequestQuestion added in v0.8.2

func (msg *Message) SetRequestQuestion(domain string, typ Type, class Class)

SetRequestQuestion set question for DNS request.

func (*Message) SetResponseHeader added in v0.6.2

func (msg *Message) SetResponseHeader(rcode Rcode, ancount uint16)

SetResponseHeader sets QR=1, RCODE=rcode, ANCount=ancount then updates Raw.

func (*Message) Walk added in v0.8.1

func (msg *Message) Walk(f func(name []byte, typ Type, class Class, ttl uint32, data []byte) bool) error

Walk calls f for each item in the msg in the original order of the parsed RR.

func (*Message) WalkAdditionalRecords added in v0.8.1

func (msg *Message) WalkAdditionalRecords(f func(name []byte, typ Type, class Class, ttl uint32, data []byte) bool) error

WalkAdditionalRecords calls f for each item in the msg in the original order of the parsed AR.

type Opcode

type Opcode byte

Opcode denotes a 4bit field that specified the query type.

const (
	OpcodeQuery  Opcode = 0
	OpcodeIQuery Opcode = 1
	OpcodeStatus Opcode = 2
	OpcodeNotify Opcode = 4
	OpcodeUpdate Opcode = 5
)

Wire constants and supported types.

func (Opcode) String

func (c Opcode) String() string

type Rcode

type Rcode byte

Rcode denotes a 4bit field that specifies the response code for a query.

const (
	RcodeNoError   Rcode = 0  // No Error                          [DNS]
	RcodeFormErr   Rcode = 1  // Format Error                      [DNS]
	RcodeServFail  Rcode = 2  // Server Failure                    [DNS]
	RcodeNXDomain  Rcode = 3  // Non-Existent Domain               [DNS]
	RcodeNotImp    Rcode = 4  // Not Implemented                   [DNS]
	RcodeRefused   Rcode = 5  // Query Refused                     [DNS]
	RcodeYXDomain  Rcode = 6  // Name Exists when it should not    [DNS Update]
	RcodeYXRRSet   Rcode = 7  // RR Set Exists when it should not  [DNS Update]
	RcodeNXRRSet   Rcode = 8  // RR Set that should exist does not [DNS Update]
	RcodeNotAuth   Rcode = 9  // Server Not Authoritative for zone [DNS Update]
	RcodeNotZone   Rcode = 10 // Name not contained in zone        [DNS Update/TSIG]
	RcodeBADSIG    Rcode = 16 // TSIG Signature Failure            [TSIG]
	RcodeBADVERS   Rcode = 16 // Bad OPT Version                   [EDNS0]
	RcodeBADKEY    Rcode = 17 // Key not recognized                [TSIG]
	RcodeBADTIME   Rcode = 18 // Signature out of time window      [TSIG]
	RcodeBADMODE   Rcode = 19 // Bad TKEY Mode                     [TKEY]
	RcodeBADNAME   Rcode = 20 // Duplicate key name                [TKEY]
	RcodeBADALG    Rcode = 21 // Algorithm not supported           [TKEY]
	RcodeBADTRUNC  Rcode = 22 // Bad Truncation                    [TSIG]
	RcodeBADCOOKIE Rcode = 23 // Bad/missing Server Cookie         [DNS Cookies]
)

Message Response Codes, see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml

func (Rcode) String

func (c Rcode) String() string

type ResponseWriter

type ResponseWriter interface {
	// LocalAddr returns the netip.AddrPort of the server
	LocalAddr() netip.AddrPort

	// RemoteAddr returns the netip.AddrPort of the client that sent the current request.
	RemoteAddr() netip.AddrPort

	// Write writes a raw buffer back to the client.
	Write([]byte) (int, error)
}

A ResponseWriter interface is used by an DNS handler to construct an DNS response.

type Server

type Server struct {
	// handler to invoke
	Handler Handler

	// Stats to invoke
	Stats Stats

	// ErrorLog specifies an optional logger for errors accepting
	// connections, unexpected behavior from handlers, and
	// underlying FileSystem errors.
	// If nil, logging is done via the log package's standard logger.
	ErrorLog *log.Logger

	// The maximum number of procs the server may spawn. use runtime.NumCPU() if empty
	MaxProcs int

	// The maximum number of concurrent clients the server may serve.
	Concurrency int
	// contains filtered or unexported fields
}

Server implements a mutli-listener DNS server.

func (*Server) Index

func (s *Server) Index() (index int)

Index indicates the index of Server instances.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe(addr string) error

ListenAndServe serves DNS requests from the given UDP addr.

type Stats added in v0.6.0

type Stats interface {
	UpdateStats(addr netip.AddrPort, msg *Message, duration time.Duration)
	AppendOpenMetrics(dst []byte) []byte
}

type Type

type Type uint16

Type is a DNS type.

const (
	TypeNone       Type = 0
	TypeA          Type = 1
	TypeNS         Type = 2
	TypeMD         Type = 3
	TypeMF         Type = 4
	TypeCNAME      Type = 5
	TypeSOA        Type = 6
	TypeMB         Type = 7
	TypeMG         Type = 8
	TypeMR         Type = 9
	TypeNULL       Type = 10
	TypePTR        Type = 12
	TypeHINFO      Type = 13
	TypeMINFO      Type = 14
	TypeMX         Type = 15
	TypeTXT        Type = 16
	TypeRP         Type = 17
	TypeAFSDB      Type = 18
	TypeX25        Type = 19
	TypeISDN       Type = 20
	TypeRT         Type = 21
	TypeNSAPPTR    Type = 23
	TypeSIG        Type = 24
	TypeKEY        Type = 25
	TypePX         Type = 26
	TypeGPOS       Type = 27
	TypeAAAA       Type = 28
	TypeLOC        Type = 29
	TypeNXT        Type = 30
	TypeEID        Type = 31
	TypeNIMLOC     Type = 32
	TypeSRV        Type = 33
	TypeATMA       Type = 34
	TypeNAPTR      Type = 35
	TypeKX         Type = 36
	TypeCERT       Type = 37
	TypeDNAME      Type = 39
	TypeOPT        Type = 41 // EDNS
	TypeAPL        Type = 42
	TypeDS         Type = 43
	TypeSSHFP      Type = 44
	TypeRRSIG      Type = 46
	TypeNSEC       Type = 47
	TypeDNSKEY     Type = 48
	TypeDHCID      Type = 49
	TypeNSEC3      Type = 50
	TypeNSEC3PARAM Type = 51
	TypeTLSA       Type = 52
	TypeSMIMEA     Type = 53
	TypeHIP        Type = 55
	TypeNINFO      Type = 56
	TypeRKEY       Type = 57
	TypeTALINK     Type = 58
	TypeCDS        Type = 59
	TypeCDNSKEY    Type = 60
	TypeOPENPGPKEY Type = 61
	TypeCSYNC      Type = 62
	TypeZONEMD     Type = 63
	TypeSVCB       Type = 64
	TypeHTTPS      Type = 65
	TypeSPF        Type = 99
	TypeUINFO      Type = 100
	TypeUID        Type = 101
	TypeGID        Type = 102
	TypeUNSPEC     Type = 103
	TypeNID        Type = 104
	TypeL32        Type = 105
	TypeL64        Type = 106
	TypeLP         Type = 107
	TypeEUI48      Type = 108
	TypeEUI64      Type = 109
	TypeURI        Type = 256
	TypeCAA        Type = 257
	TypeAVC        Type = 258
	TypeTKEY       Type = 249
	TypeTSIG       Type = 250
	TypeIXFR       Type = 251
	TypeAXFR       Type = 252
	TypeMAILB      Type = 253
	TypeMAILA      Type = 254
	TypeANY        Type = 255
	TypeTA         Type = 32768
	TypeDLV        Type = 32769
	TypeReserved   Type = 65535
)

Wire constants and supported types.

func ParseType added in v0.4.1

func ParseType(s string) (t Type)

ParseType converts a question type string into a question type value.

func (Type) String

func (t Type) String() string

Directories

Path Synopsis
cmd
fastdoh Module
fastdoh module

Jump to

Keyboard shortcuts

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