dns

package module
v0.0.0-...-9977bf8 Latest Latest
Warning

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

Go to latest
Published: Dec 14, 2012 License: BSD-3-Clause Imports: 34 Imported by: 0

README

Alternative (more granular) approach to a DNS library.

Less is more.

Complete and usable DNS library. All widely used Resource Records are supported, including the DNSSEC types. It follows a lean and mean philosophy. If there is stuff you should know as a DNS programmer there isn't a convenience function for it. Server side and client side programming is supported, i.e. you can build servers and resolvers with it.

If you like this, you may also be interested in:

Goals

  • KISS;
  • Small API, if its easy to code in Go, don't make a function for it.

Features

  • UDP/TCP queries, IPv4 and IPv6;
  • RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE [for all record types] are supported);
  • Fast:
    • Reply speed around ~ 50K qps (faster hardware results in more qps);
    • Parsing RRs with ~ 100K RR/s, that's 5M records in about 50 seconds;
  • Server side programming (mimicking the net/http package);
  • Client side programming;
  • DNSSEC: signing, validating and key generation for DSA, RSA and ECDSA;
  • EDNS0, NSID;
  • AXFR/IXFR;
  • TSIG;
  • DNS name compression.

Have fun!

Miek Gieben - 2010-2012 - miek@miek.nl

Building

Building is done with the go tool. If you have setup your GOPATH correctly, the following should work:

go get github.com/miekg/dns
go build dns

A short "how to use the API" is at the beginning of dns.go (this also will show when you call go doc github.com/miekg/dns. Sample programs can be found in the ex directory. They can also be build with: go build.

Supported RFCs

all of them

  • 103{4,5} - DNS standard
  • 1982 - Serial Arithmetic
  • 1876 - LOC record
  • 1995 - IXFR
  • 1996 - DNS notify
  • 2136 - DNS Update (dynamic updates)
  • 2181 - RRset definition
  • 2537 - RSAMD5 DNS keys
  • 2065 - DNSSEC (updated in later RFCs)
  • 2671 - EDNS record
  • 2782 - SRV record
  • 2845 - TSIG record
  • 2915 - NAPTR record
  • 3110 - RSASHA1 DNS keys
  • 3225 - DO bit (DNSSEC OK)
  • 340{1,2,3} - NAPTR record
  • 3445 - Limiting the scope of (DNS)KEY
  • 3597 - Unkown RRs
  • 403{3,4,5} - DNSSEC + validation functions
  • 4255 - SSHFP record
  • 4408 - SPF record
  • 4509 - SHA256 Hash in DS
  • 4592 - Wildcards in the DNS
  • 4635 - HMAC SHA TSIG
  • 4701 - DHCID
  • 4892 - id.server
  • 5001 - NSID
  • 5155 - NSEC3 record
  • 5205 - HIP record
  • 5702 - SHA2 in the DNS
  • 5936 - AXFR
  • 6605 - ECDSA
  • 6742 - ILNP DNS
  • xxxx - URI record (draft)
  • xxxx - EDNS0 DNS Update Lease (draft)

Loosely based upon

  • ldns
  • NSD
  • Net::DNS
  • GRONG

Documentation

Overview

Package dns implements a full featured interface to the Domain Name System. Server- and client-side programming is supported. The package allows complete control over what is send out to the DNS. The package API follows the less-is-more principle, by presenting a small, clean interface.

The package dns supports (asynchronous) querying/replying, incoming/outgoing AXFR/IXFR, TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing. Note that domain names MUST be fully qualified, before sending them, unqualified names in a message will result in a packing failure.

Resource records are native types. They are not stored in wire format. Basic usage pattern for creating a new resource record:

r := new(dns.MX)
r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}
r.Pref = 10
r.Mx = "mx.miek.nl."

Or directly from a string:

mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")

Or when the default TTL (3600) and class (IN) suit you:

mx, err := dns.NewRR("miek.nl. MX 10 mx.miek.nl.")

Or even:

mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")

In the DNS messages are exchanged, these messages contain resource records (sets). Use pattern for creating a message:

m := dns.new(Msg)
m.SetQuestion("miek.nl.", dns.TypeMX)

Or when not certain if the domain name is fully qualified:

m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)

The message m is now a message with the question section set to ask the MX records for the miek.nl. zone.

The following is slightly more verbose, but more flexible:

m1 := new(dns.Msg)
m1.Id = Id()
m1.RecursionDesired = true
m1.Question = make([]Question, 1)
m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}

After creating a message it can be send. Basic use pattern for synchronous querying the DNS at a server configured on 127.0.0.1 and port 53:

c := new(Client)
in, rtt, err := c.Exchange(m1, "127.0.0.1:53")

For asynchronous queries it is easy to wrap Exchange() in a goroutine.

From a birds eye view a dns message consists out of four sections. The question section: in.Question, the answer section: in.Answer, the authority section: in.Ns and the additional section: in.Extra.

Each of these sections (except the Question section) contain a []RR. Basic use pattern for accessing the rdata of a TXT RR as the first RR in the Answer section:

if t, ok := in.Answer[0].(*TXT); ok {
	// do something with t.Txt
}

DNSSEC

DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses public key cryptography to sign resource records. The public keys are stored in DNSKEY records and the signatures in RRSIG records.

Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit to an request.

m := new(dns.Msg)
m.SetEdns0(4096, true)

Signature generation, signature verification and key generation are all supported. Writing a DNSSEC validating resolver is hard, if you need something like that you might want to use the Unbound wrapper found at github.com/miekg/unbound .

EDNS0

EDNS0 is an extension mechanism for the DNS defined in RFC 2671. It defines a standard RR type, the OPT RR, which is then completely abused. Basic use pattern for creating an (empty) OPT RR:

o := new(dns.OPT)
o.Hdr.Name = "." // MUST be the root zone, per definition.
o.Hdr.Rrtype = dns.TypeOPT

The rdata of an OPT RR consists out of a slice of EDNS0 interfaces. Currently only a few have been standardized: EDNS0_NSID (RFC 5001) and EDNS0_SUBNET (draft). Note that these options may be combined in an OPT RR. Basic use pattern for a server to check if (and which) options are set:

// o is a dns.OPT
for _, s := range o.Options {
	switch e := s.(type) {
	case *dns.EDNS0_NSID:
		// do stuff with e.Nsid
	case *dns.EDNS0_SUBNET:
		// access e.Family, e.Address, etc.
	}
}

TRANSACTION SIGNATURE (TSIG)

An TSIG or transaction signature adds a HMAC TSIG record to each message sent. The supported algorithms include: HmacMD5, HmacSHA1 and HmacSHA256.

Basic use pattern when querying with a TSIG name "axfr." (note that these key names must be fully qualified - as they are domain names) and the base64 secret "so6ZGir4GPAqINNh9U5c3A==":

c := new(dns.Client)
c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
m := new(dns.Msg)
m.SetQuestion("miek.nl.", dns.TypeMX)
m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
...
// When sending the TSIG RR is calculated and filled in before sending

When requesting an AXFR (almost all TSIG usage is when requesting zone transfers), with TSIG, this is the basic use pattern. In this example we request an AXFR for miek.nl. with TSIG key named "axfr." and secret "so6ZGir4GPAqINNh9U5c3A==" and using the server 85.223.71.124

c := new(dns.Client)
c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
m := new(dns.Msg)
m.SetAxfr("miek.nl.")
m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
t, err := c.TransferIn(m, "85.223.71.124:53")
for r := range t { /* ... */ }

You can now read the records from the AXFR as they come in. Each envelope is checked with TSIG. If something is not correct an error is returned.

Basic use pattern validating and replying to a message that has TSIG set.

server := &dns.Server{Addr: ":53", Net: "udp"}
server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
go server.ListenAndServe()
dns.HandleFunc(".", handleRequest)

func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
	m := new(Msg)
	m.SetReply(r)
	if r.IsTsig() {
		if w.TsigStatus() == nil {
			// *Msg r has an TSIG record and it was validated
			m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
		} else {
			// *Msg r has an TSIG records and it was not valided
		}
	}
	w.WriteMsg(m)
}

DYNAMIC UPDATES

Dynamic updates reuses the DNS message format, but renames three of the sections. Question is Zone, Answer is Prerequisite, Authority is Update, only the Additional is not renamed. See RFC 2136 for the gory details.

You can set a rather complex set of rules for the existence of absence of certain resource records or names in a zone to specify if resource records should be added or removed. The table from RFC 2136 supplemented with the Go DNS function shows which functions exist to specify the prerequisites.

3.2.4 - Table Of Metavalues Used In Prerequisite Section

CLASS    TYPE     RDATA    Meaning                    Function
--------------------------------------------------------------
ANY      ANY      empty    Name is in use             NameUsed
ANY      rrset    empty    RRset exists (value indep) RRsetUsed
NONE     ANY      empty    Name is not in use         NameNotUsed
NONE     rrset    empty    RRset does not exist       RRsetNotUsed
zone     rrset    rr       RRset exists (value dep)   Used

The prerequisite section can also be left empty. If you have decided on the prerequisites you can tell what RRs should be added or deleted. The next table shows the options you have and what functions to call.

3.4.2.6 - Table Of Metavalues Used In Update Section

CLASS    TYPE     RDATA    Meaning                     Function
---------------------------------------------------------------
ANY      ANY      empty    Delete all RRsets from name RemoveName
ANY      rrset    empty    Delete an RRset             RemoveRRset
NONE     rrset    rr       Delete an RR from RRset     Remove
zone     rrset    rr       Add to an RRset             Insert

Index

Examples

Constants

View Source
const (
	DefaultMsgSize = 4096 // Standard default for larger than 512 packets.

	MaxMsgSize = 65536 // Largest possible DNS packet.

)
View Source
const (
	RSAMD5           = 1
	DH               = 2
	DSA              = 3
	ECC              = 4
	RSASHA1          = 5
	DSANSEC3SHA1     = 6
	RSASHA1NSEC3SHA1 = 7
	RSASHA256        = 8
	RSASHA512        = 10
	ECCGOST          = 12
	ECDSAP256SHA256  = 13
	ECDSAP384SHA384  = 14
	INDIRECT         = 252
	PRIVATEDNS       = 253 // Private (experimental keys)
	PRIVATEOID       = 254
)

DNSSEC encryption algorithm codes.

View Source
const (
	SHA1   // RFC 4034
	SHA256 // RFC 4509
	GOST94 // RFC 5933
	SHA384 // Experimental
	SHA512 // Experimental
)

DNSSEC hashing algorithm codes.

View Source
const (
	SEP    = 1
	ZONE   = 1 << 7
	REVOKE = 1 << 8
)

DNSKEY flag values.

View Source
const (
	EDNS0LLQ         = 0x1    // not used
	EDNS0UL          = 0x2    // not used
	EDNS0UPDATELEASE = 0x2    // update lease draft
	EDNS0NSID        = 0x3    // nsid (RFC5001)
	EDNS0SUBNET      = 0x50fa // client-subnet draft

)

EDNS0 Option codes.

View Source
const (
	HmacMD5    = "hmac-md5.sig-alg.reg.int."
	HmacSHA1   = "hmac-sha1."
	HmacSHA256 = "hmac-sha256."
)

HMAC hashing codes. These are transmitted as domain names.

View Source
const (
	// valid RR_Header.Rrtype and Question.qtype
	TypeA          uint16 = 1
	TypeNS         uint16 = 2
	TypeMD         uint16 = 3
	TypeMF         uint16 = 4
	TypeCNAME      uint16 = 5
	TypeSOA        uint16 = 6
	TypeMB         uint16 = 7
	TypeMG         uint16 = 8
	TypeMR         uint16 = 9
	TypeNULL       uint16 = 10
	TypeWKS        uint16 = 11
	TypePTR        uint16 = 12
	TypeHINFO      uint16 = 13
	TypeMINFO      uint16 = 14
	TypeMX         uint16 = 15
	TypeTXT        uint16 = 16
	TypeRP         uint16 = 17
	TypeAFSDB      uint16 = 18
	TypeX25        uint16 = 19
	TypeISDN       uint16 = 20
	TypeRT         uint16 = 21
	TypeSIG        uint16 = 24
	TypeKEY        uint16 = 25
	TypeAAAA       uint16 = 28
	TypeLOC        uint16 = 29
	TypeNXT        uint16 = 30
	TypeSRV        uint16 = 33
	TypeATMA       uint16 = 34
	TypeNAPTR      uint16 = 35
	TypeKX         uint16 = 36
	TypeCERT       uint16 = 37
	TypeDNAME      uint16 = 39
	TypeOPT        uint16 = 41 // EDNS
	TypeDS         uint16 = 43
	TypeSSHFP      uint16 = 44
	TypeIPSECKEY   uint16 = 45
	TypeRRSIG      uint16 = 46
	TypeNSEC       uint16 = 47
	TypeDNSKEY     uint16 = 48
	TypeDHCID      uint16 = 49
	TypeNSEC3      uint16 = 50
	TypeNSEC3PARAM uint16 = 51
	TypeTLSA       uint16 = 52
	TypeHIP        uint16 = 55
	TypeNINFO      uint16 = 56
	TypeRKEY       uint16 = 57
	TypeTALINK     uint16 = 58
	TypeCDS        uint16 = 59
	TypeSPF        uint16 = 99
	TypeNID        uint16 = 104
	TypeL32        uint16 = 105
	TypeL64        uint16 = 106
	TypeLP         uint16 = 107

	TypeTKEY uint16 = 249
	TypeTSIG uint16 = 250
	// valid Question.Qtype only
	TypeIXFR  uint16 = 251
	TypeAXFR  uint16 = 252
	TypeMAILB uint16 = 253
	TypeMAILA uint16 = 254
	TypeANY   uint16 = 255

	TypeURI uint16 = 256
	TypeCAA uint16 = 257
	TypeTA  uint16 = 32768
	TypeDLV uint16 = 32769

	// valid Question.Qclass
	ClassINET   = 1
	ClassCSNET  = 2
	ClassCHAOS  = 3
	ClassHESIOD = 4
	ClassNONE   = 254
	ClassANY    = 255

	// Msg.rcode
	RcodeSuccess        = 0
	RcodeFormatError    = 1
	RcodeServerFailure  = 2
	RcodeNameError      = 3
	RcodeNotImplemented = 4
	RcodeRefused        = 5
	RcodeYXDomain       = 6
	RcodeYXRrset        = 7
	RcodeNXRrset        = 8
	RcodeNotAuth        = 9
	RcodeNotZone        = 10
	RcodeBadSig         = 16 // TSIG
	RcodeBadKey         = 17
	RcodeBadTime        = 18
	RcodeBadMode        = 19 // TKEY
	RcodeBadName        = 20
	RcodeBadAlg         = 21
	RcodeBadTrunc       = 22 // TSIG

	// Opcode
	OpcodeQuery  = 0
	OpcodeIQuery = 1
	OpcodeStatus = 2
	// There is no 3
	OpcodeNotify = 4
	OpcodeUpdate = 5
)

Wire constants and supported types.

Variables

View Source
var (
	ErrFqdn      error = &Error{Err: "domain must be fully qualified"}
	ErrId        error = &Error{Err: "id mismatch"}
	ErrRdata     error = &Error{Err: "bad rdata"}
	ErrBuf       error = &Error{Err: "buffer size too small"}
	ErrShortRead error = &Error{Err: "short read"}
	ErrConn      error = &Error{Err: "conn holds both UDP and TCP connection"}
	ErrConnEmpty error = &Error{Err: "conn has no connection"}
	ErrServ      error = &Error{Err: "no servers could be reached"}
	ErrKey       error = &Error{Err: "bad key"}
	ErrPrivKey   error = &Error{Err: "bad private key"}
	ErrKeySize   error = &Error{Err: "bad key size"}
	ErrKeyAlg    error = &Error{Err: "bad key algorithm"}
	ErrAlg       error = &Error{Err: "bad algorithm"}
	ErrTime      error = &Error{Err: "bad time"}
	ErrNoSig     error = &Error{Err: "no signature found"}
	ErrSig       error = &Error{Err: "bad signature"}
	ErrSecret    error = &Error{Err: "no secrets defined"}
	ErrSigGen    error = &Error{Err: "bad signature generation"}
	ErrAuth      error = &Error{Err: "bad authentication"}
	ErrSoa       error = &Error{Err: "no SOA"}
	ErrRRset     error = &Error{Err: "bad rrset"}
)
View Source
var AlgorithmToString = map[uint8]string{
	RSAMD5:           "RSAMD5",
	DH:               "DH",
	DSA:              "DSA",
	RSASHA1:          "RSASHA1",
	DSANSEC3SHA1:     "DSA-NSEC3-SHA1",
	RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1",
	RSASHA256:        "RSASHA256",
	RSASHA512:        "RSASHA512",
	ECCGOST:          "ECC-GOST",
	ECDSAP256SHA256:  "ECDSAP256SHA256",
	ECDSAP384SHA384:  "ECDSAP384SHA384",
	INDIRECT:         "INDIRECT",
	PRIVATEDNS:       "PRIVATEDNS",
	PRIVATEOID:       "PRIVATEOID",
}

Map for algorithm names.

View Source
var Authors = []string{"Miek Gieben", "Ask Bjørn Hansen", "Dave Cheney", "Dusty Wilson", "Peter van Dijk"}

Authors is a list of authors that helped create or make Go DNS better.

View Source
var ClassToString = map[uint16]string{
	ClassINET:   "IN",
	ClassCSNET:  "CS",
	ClassCHAOS:  "CH",
	ClassHESIOD: "HS",
	ClassNONE:   "NONE",
	ClassANY:    "ANY",
}

Map of strings for each CLASS wire type.

View Source
var DefaultServeMux = NewServeMux()

DefaultServeMux is the default ServeMux used by Serve.

View Source
var DefaultSignatureConfig = newSignatureConfig()

DefaultSignaturePolicy has the following values. Validity is 4 weeks, Refresh is set to 3 days, Jitter to 12 hours and InceptionOffset to 300 seconds. HonorSepFlag is set to true, SignerRoutines is set to runtime.NumCPU() + 1. The Minttl value is zero.

View Source
var OpcodeToString = map[int]string{
	OpcodeQuery:  "QUERY",
	OpcodeIQuery: "IQUERY",
	OpcodeStatus: "STATUS",
	OpcodeNotify: "NOTIFY",
	OpcodeUpdate: "UPDATE",
}

Map of strings for opcodes.

View Source
var RcodeToString = map[int]string{
	RcodeSuccess:        "NOERROR",
	RcodeFormatError:    "FORMERR",
	RcodeServerFailure:  "SERVFAIL",
	RcodeNameError:      "NXDOMAIN",
	RcodeNotImplemented: "NOTIMPL",
	RcodeRefused:        "REFUSED",
	RcodeYXDomain:       "YXDOMAIN",
	RcodeYXRrset:        "YXRRSET",
	RcodeNXRrset:        "NXRRSET",
	RcodeNotAuth:        "NOTAUTH",
	RcodeNotZone:        "NOTZONE",
	RcodeBadSig:         "BADSIG",
	RcodeBadKey:         "BADKEY",
	RcodeBadTime:        "BADTIME",
	RcodeBadMode:        "BADMODE",
	RcodeBadName:        "BADNAME",
	RcodeBadAlg:         "BADALG",
	RcodeBadTrunc:       "BADTRUNC",
}

Map of strings for rcodes.

View Source
var StringToAlgorithm = reverseInt8(AlgorithmToString)

Map of algorithm strings.

View Source
var StringToClass = reverseInt16(ClassToString)
View Source
var StringToOpcode = reverseInt(OpcodeToString)

Map of opcodes strings.

View Source
var StringToRcode = reverseInt(RcodeToString)

Map of rcodes strings.

View Source
var StringToType = reverseInt16(TypeToString)

Reverse, needed for string parsing.

View Source
var TypeToString = map[uint16]string{
	TypeCNAME:      "CNAME",
	TypeHINFO:      "HINFO",
	TypeTLSA:       "TSLA",
	TypeMB:         "MB",
	TypeMG:         "MG",
	TypeRP:         "RP",
	TypeMD:         "MD",
	TypeMF:         "MF",
	TypeMINFO:      "MINFO",
	TypeMR:         "MR",
	TypeMX:         "MX",
	TypeWKS:        "WKS",
	TypeNS:         "NS",
	TypeNULL:       "NULL",
	TypeAFSDB:      "AFSDB",
	TypeX25:        "X25",
	TypeISDN:       "ISDN",
	TypePTR:        "PTR",
	TypeRT:         "RT",
	TypeSOA:        "SOA",
	TypeTXT:        "TXT",
	TypeSRV:        "SRV",
	TypeATMA:       "ATMA",
	TypeNAPTR:      "NAPTR",
	TypeKX:         "KX",
	TypeCERT:       "CERT",
	TypeDNAME:      "DNAME",
	TypeA:          "A",
	TypeAAAA:       "AAAA",
	TypeLOC:        "LOC",
	TypeOPT:        "OPT",
	TypeDS:         "DS",
	TypeDHCID:      "DHCID",
	TypeHIP:        "HIP",
	TypeNINFO:      "NINFO",
	TypeRKEY:       "RKEY",
	TypeCDS:        "CDS",
	TypeCAA:        "CAA",
	TypeIPSECKEY:   "IPSECKEY",
	TypeSSHFP:      "SSHFP",
	TypeRRSIG:      "RRSIG",
	TypeNSEC:       "NSEC",
	TypeDNSKEY:     "DNSKEY",
	TypeNSEC3:      "NSEC3",
	TypeNSEC3PARAM: "NSEC3PARAM",
	TypeTALINK:     "TALINK",
	TypeSPF:        "SPF",
	TypeNID:        "NID",
	TypeL32:        "L32",
	TypeL64:        "L64",
	TypeLP:         "LP",
	TypeTKEY:       "TKEY",
	TypeTSIG:       "TSIG",
	TypeAXFR:       "AXFR",
	TypeIXFR:       "IXFR",
	TypeANY:        "ANY",
	TypeURI:        "URI",
	TypeTA:         "TA",
	TypeDLV:        "DLV",
}

Map of strings for each RR wire type.

View Source
var Version = "v1.0"

Version holds the current version.

Functions

func CertificateToDANE

func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) string

CertificateToDANE converts a certificate to a hex string as used in the TLSA record.

func CompareLabels

func CompareLabels(s1, s2 string) (n int)

CompareLabels compares the strings s1 and s2 and returns how many labels they have in common starting from the right. The comparison stops at the first inequality. The labels are not downcased before the comparison.

www.miek.nl. and miek.nl. have two labels in common: miek and nl www.miek.nl. and www.bla.nl. have one label in common: nl

func Fqdn

func Fqdn(s string) string

Fqdns return the fully qualified domain name from s. If s is already fully qualified, it behaves as the identity function.

func Handle

func Handle(pattern string, handler Handler)

Handle registers the handler with the given pattern in the DefaultServeMux. The documentation for ServeMux explains how patterns are matched.

func HandleAuthors

func HandleAuthors(w ResponseWriter, r *Msg)

AuthorHandler returns a HandlerFunc that returns the authors of Go DNS for 'authors.bind' or 'authors.server' queries in the CHAOS Class. Note with:

HandleFunc("authors.bind.", HandleAuthors)

the handler is registered for all DNS classes, thereby potentially hijacking the authors.bind. zone in the IN class. If you need the authors.bind zone to exist in the IN class, you need to register some other handler, check the class in there and then call HandleAuthors.

func HandleFailed

func HandleFailed(w ResponseWriter, r *Msg)

FailedHandler returns a HandlerFunc returns SERVFAIL for every request it gets.

func HandleFunc

func HandleFunc(pattern string, handler func(ResponseWriter, *Msg))

HandleFunc registers the handler function with the given pattern in the DefaultServeMux.

func HandleRemove

func HandleRemove(pattern string)

HandleRemove deregisters the handle with the given pattern in the DefaultServeMux.

func HandleVersion

func HandleVersion(w ResponseWriter, r *Msg)

VersionHandler returns a HandlerFunc that returns the version of Go DNS for 'version.bind' or 'version.server' queries in the CHAOS Class. Note with:

HandleFunc("version.bind.", HandleVersion)

the handler is registered for all DNS classes, thereby potentially hijacking the version.bind. zone in the IN class. If you need the version.bind zone to exist in the IN class, you need to register some other handler, check the class in there and then call HandleVersion.

func HashName

func HashName(label string, ha uint8, iter uint16, salt string) string

HashName hashes a string (label) according to RFC 5155. It returns the hashed string.

func Id

func Id() uint16

Id return a 16 bits random number to be used as a message id. The random provided should be good enough.

func IsDomainName

func IsDomainName(s string) (uint8, uint8, bool)

IsDomainName checks if s is a valid domainname, it returns the number of labels, total length and true, when a domain name is valid. When false is returned the labelcount and length are not defined.

func IsFqdn

func IsFqdn(s string) bool

IsFqdn checks if a domain name is fully qualified.

func IsSubDomain

func IsSubDomain(parent, child string) bool

IsSubDomain checks if child is indeed a child of the parent.

func LenLabels

func LenLabels(s string) (labels int)

LenLabels returns the number of labels in a domain name.

func ListenAndServe

func ListenAndServe(addr string, network string, handler Handler) error

Start a server on addresss and network speficied. Invoke handler for incoming queries.

func PackDomainName

func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error)

PackDomainName packs a domain name s into msg[off:]. If compression is wanted compress must be true and the compression map needs to hold a mapping between domain names and offsets pointing into msg[].

func PackRR

func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error)

Resource record packer, pack rr into msg[off:]. See PackDomainName for documentation about the compression.

func PackStruct

func PackStruct(any interface{}, msg []byte, off int) (off1 int, err error)

func ParseZone

func ParseZone(r io.Reader, origin, file string) chan Token

ParseZone reads a RFC 1035 style one from r. It returns Tokens on the returned channel, which consist out the parsed RR or an error. If there is an error the RR is nil. The string file is only used in error reporting. The string origin is used as the initial origin, as if the file would start with: $ORIGIN origin . The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported. The channel t is closed by ParseZone when the end of r is reached.

Basic usage pattern when reading from a string (z) containing the zone data:

for x := range dns.ParseZone(strings.NewReader(z), "", "") {
	if x.Error != nil {
		// Do something with x.RR
	}
}

func ReverseAddr

func ReverseAddr(addr string) (arpa string, err error)

ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP address addr suitable for rDNS (PTR) record lookup or an error if it fails to parse the IP address.

func SplitLabels

func SplitLabels(s string) []string

SplitLabels splits a domainname string into its labels. www.miek.nl. returns []string{"www", "miek", "nl"} The root label (.) returns nil.

func StringToTime

func StringToTime(s string) (uint32, error)

StringToTime translates the RRSIG's incep. and expir. times from string values like "20110403154150" to an 32 bit integer. It takes serial arithmetic (RFC 1982) into account.

func TLSAName

func TLSAName(name, service, network string) string

TLSAName returns the ownername of a TLSA resource record as per the rules specified in RFC 6698, Section 3. When an error occurs the empty string is returned.

func TimeToString

func TimeToString(t uint32) string

TimeToString translates the RRSIG's incep. and expir. times to the string representation used when printing the record. It takes serial arithmetic (RFC 1982) into account.

func TransferOut

func TransferOut(w ResponseWriter, q *Msg, c chan *Envelope, e *error) error

TransferOut performs an outgoing [AI]XFR depending on the request message. The caller is responsible for sending the correct sequence of RR sets through the channel c. For reasons of symmetry Envelope is re-used. Errors are signaled via the error pointer, when an error occurs the function sets the error and returns (it does not close the channel). TSIG and enveloping is handled by TransferOut.

Basic use pattern for sending an AXFR:

// q contains the AXFR request
c := make(chan *Envelope)
var e *error
err := TransferOut(w, q, c, e)
w.Hijack()		// hijack the connection so that the package doesn't close it
for _, rrset := range rrsets {	// rrsets is a []RR
	c <- &{Envelope{RR: rrset}
	if e != nil {
		close(c)
		break
	}
}
// w.Close() // Don't! Let the client close the connection

func TsigGenerate

func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error)

TsigGenerate fills out the TSIG record attached to the message. The message should contain a "stub" TSIG RR with the algorithm, key name (owner name of the RR), time fudge (defaults to 300 seconds) and the current time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for the first time requestMAC is set to the empty string and timersOnly is false. If something goes wrong an error is returned, otherwise it is nil.

func TsigVerify

func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error

TsigVerify verifies the TSIG on a message. If the signature does not validate err contains the error, otherwise it is nil.

func UnpackDomainName

func UnpackDomainName(msg []byte, off int) (s string, off1 int, err error)

UnpackDomainName unpacks a domain name into a string.

func UnpackStruct

func UnpackStruct(any interface{}, msg []byte, off int) (off1 int, err error)

Types

type A

type A struct {
	Hdr RR_Header
	A   net.IP `dns:"a"`
}

func (*A) Copy

func (rr *A) Copy() RR

func (*A) Header

func (rr *A) Header() *RR_Header

func (*A) Len

func (rr *A) Len() int

func (*A) String

func (rr *A) String() string

type AAAA

type AAAA struct {
	Hdr  RR_Header
	AAAA net.IP `dns:"aaaa"`
}

func (*AAAA) Copy

func (rr *AAAA) Copy() RR

func (*AAAA) Header

func (rr *AAAA) Header() *RR_Header

func (*AAAA) Len

func (rr *AAAA) Len() int

func (*AAAA) String

func (rr *AAAA) String() string

type AFSDB

type AFSDB struct {
	Hdr      RR_Header
	Subtype  uint16
	Hostname string `dns:"cdomain-name"`
}

func (*AFSDB) Copy

func (rr *AFSDB) Copy() RR

func (*AFSDB) Header

func (rr *AFSDB) Header() *RR_Header

func (*AFSDB) Len

func (rr *AFSDB) Len() int

func (*AFSDB) String

func (rr *AFSDB) String() string

type ANY

type ANY struct {
	Hdr RR_Header
}

func (*ANY) Copy

func (rr *ANY) Copy() RR

func (*ANY) Header

func (rr *ANY) Header() *RR_Header

func (*ANY) Len

func (rr *ANY) Len() int

func (*ANY) String

func (rr *ANY) String() string

type CDS

type CDS struct {
	Hdr        RR_Header
	KeyTag     uint16
	Algorithm  uint8
	DigestType uint8
	Digest     string `dns:"hex"`
}

func (*CDS) Copy

func (rr *CDS) Copy() RR

func (*CDS) Header

func (rr *CDS) Header() *RR_Header

func (*CDS) Len

func (rr *CDS) Len() int

func (*CDS) String

func (rr *CDS) String() string

type CERT

type CERT struct {
	Hdr         RR_Header
	Type        uint16
	KeyTag      uint16
	Algorithm   uint8
	Certificate string `dns:"base64"`
}

See RFC 4398.

func (*CERT) Copy

func (rr *CERT) Copy() RR

func (*CERT) Header

func (rr *CERT) Header() *RR_Header

func (*CERT) Len

func (rr *CERT) Len() int

func (*CERT) String

func (rr *CERT) String() string

type CNAME

type CNAME struct {
	Hdr    RR_Header
	Target string `dns:"cdomain-name"`
}

func (*CNAME) Copy

func (rr *CNAME) Copy() RR

func (*CNAME) Header

func (rr *CNAME) Header() *RR_Header

func (*CNAME) Len

func (rr *CNAME) Len() int

func (*CNAME) String

func (rr *CNAME) String() string

type Client

type Client struct {
	Net          string            // if "tcp" a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
	Attempts     int               // number of attempts, if not set defaults to 1
	Retry        bool              // retry with TCP
	ReadTimeout  time.Duration     // the net.Conn.SetReadTimeout value for new connections (ns), defaults to 2 * 1e9
	WriteTimeout time.Duration     // the net.Conn.SetWriteTimeout value for new connections (ns), defaults to 2 * 1e9
	TsigSecret   map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
}

A Client defines parameter for a DNS client. A nil Client is usable for sending queries.

func (*Client) Exchange

func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error)

Exchange performs an synchronous query. It sends the message m to the address contained in a and waits for an reply. Basic use pattern with a *dns.Client:

c := new(dns.Client)
in, rtt, err := c.Exchange(message, "127.0.0.1:53")

func (*Client) TransferIn

func (c *Client) TransferIn(q *Msg, a string) (chan *Envelope, error)

TransferIn performs a [AI]XFR request (depends on the message's Qtype). It returns a channel of *Envelope on which the replies from the server are sent. At the end of the transfer the channel is closed. The messages are TSIG checked if needed, no other post-processing is performed. The caller must dissect the returned messages.

Basic use pattern for receiving an AXFR:

// m contains the AXFR request
t, e := c.TransferIn(m, "127.0.0.1:53")
for r := range t {
	// ... deal with r.RR or r.Error
}

type ClientConfig

type ClientConfig struct {
	Servers  []string // servers to use
	Search   []string // suffixes to append to local name
	Port     string   // what port to use
	Ndots    int      // number of dots in name to trigger absolute lookup
	Timeout  int      // seconds before giving up on packet
	Attempts int      // lost packets before giving up on server
}

Wraps the contents of the /etc/resolv.conf.

func ClientConfigFromFile

func ClientConfigFromFile(conf string) (*ClientConfig, error)

ClientConfigFromFile parses a resolv.conf(5) like file and returns a *ClientConfig.

type DHCID

type DHCID struct {
	Hdr    RR_Header
	Digest string `dns:"base64"`
}

func (*DHCID) Copy

func (rr *DHCID) Copy() RR

func (*DHCID) Header

func (rr *DHCID) Header() *RR_Header

func (*DHCID) Len

func (rr *DHCID) Len() int

func (*DHCID) String

func (rr *DHCID) String() string

type DLV

type DLV struct {
	Hdr        RR_Header
	KeyTag     uint16
	Algorithm  uint8
	DigestType uint8
	Digest     string `dns:"hex"`
}

func (*DLV) Copy

func (rr *DLV) Copy() RR

func (*DLV) Header

func (rr *DLV) Header() *RR_Header

func (*DLV) Len

func (rr *DLV) Len() int

func (*DLV) String

func (rr *DLV) String() string

type DNAME

type DNAME struct {
	Hdr    RR_Header
	Target string `dns:"domain-name"`
}

See RFC 2672.

func (*DNAME) Copy

func (rr *DNAME) Copy() RR

func (*DNAME) Header

func (rr *DNAME) Header() *RR_Header

func (*DNAME) Len

func (rr *DNAME) Len() int

func (*DNAME) String

func (rr *DNAME) String() string

type DNSKEY

type DNSKEY struct {
	Hdr       RR_Header
	Flags     uint16
	Protocol  uint8
	Algorithm uint8
	PublicKey string `dns:"base64"`
}

func (*DNSKEY) Copy

func (rr *DNSKEY) Copy() RR

func (*DNSKEY) Generate

func (r *DNSKEY) Generate(bits int) (PrivateKey, error)

Generate generates a DNSKEY of the given bit size. The public part is put inside the DNSKEY record. The Algorithm in the key must be set as this will define what kind of DNSKEY will be generated. The ECDSA algorithms imply a fixed keysize, in that case bits should be set to the size of the algorithm.

func (*DNSKEY) Header

func (rr *DNSKEY) Header() *RR_Header

func (*DNSKEY) KeyTag

func (k *DNSKEY) KeyTag() uint16

KeyTag calculates the keytag (or key-id) of the DNSKEY.

func (*DNSKEY) Len

func (rr *DNSKEY) Len() int

func (*DNSKEY) NewPrivateKey

func (k *DNSKEY) NewPrivateKey(s string) (PrivateKey, error)

func (*DNSKEY) PrivateKeyString

func (r *DNSKEY) PrivateKeyString(p PrivateKey) (s string)

PrivateKeyString converts a PrivateKey to a string. This string has the same format as the private-key-file of BIND9 (Private-key-format: v1.3). It needs some info from the key (hashing, keytag), so its a method of the DNSKEY.

func (*DNSKEY) ReadPrivateKey

func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error)

NewPrivateKey reads a private key from the io.Reader q. The string file is only used in error reporting. The public key must be known, because some cryptographics algorithms embed the public inside the privatekey.

func (*DNSKEY) String

func (rr *DNSKEY) String() string

func (*DNSKEY) ToDS

func (k *DNSKEY) ToDS(h int) *DS

ToDS converts a DNSKEY record to a DS record.

type DS

type DS struct {
	Hdr        RR_Header
	KeyTag     uint16
	Algorithm  uint8
	DigestType uint8
	Digest     string `dns:"hex"`
}

func (*DS) Copy

func (rr *DS) Copy() RR

func (*DS) Header

func (rr *DS) Header() *RR_Header

func (*DS) Len

func (rr *DS) Len() int

func (*DS) String

func (rr *DS) String() string

type EDNS0

type EDNS0 interface {
	// Option returns the option code for the option.
	Option() uint16

	// String returns the string representation of the option.
	String() string
	// contains filtered or unexported methods
}

EDNS0 defines an EDNS0 Option. An OPT RR can have multiple option appended to it. Basic use pattern for adding an option to and OPT RR:

// o is the OPT RR, e is the EDNS0 option
o.Option = append(o.Option, e)

type EDNS0_NSID

type EDNS0_NSID struct {
	Code uint16 // Always EDNS0NSID
	Nsid string // This string needs to be hex encoded
}

The nsid EDNS0 option is used to retrieve some sort of nameserver identifier. When seding a request Nsid must be set to the empty string The identifier is an opaque string encoded as hex. Basic use pattern for creating an nsid option:

o := new(dns.OPT)
o.Hdr.Name = "."
o.Hdr.Rrtype = dns.TypeOPT
e := new(dns.EDNS0_NSID)
e.Code = dns.EDNS0NSID
o.Option = append(o.Option, e)

func (*EDNS0_NSID) Option

func (e *EDNS0_NSID) Option() uint16

func (*EDNS0_NSID) String

func (e *EDNS0_NSID) String() string

type EDNS0_SUBNET

type EDNS0_SUBNET struct {
	Code          uint16 // Always EDNS0SUBNET
	Family        uint16 // 1 for IP, 2 for IP6
	SourceNetmask uint8
	SourceScope   uint8
	Address       net.IP
}

The subnet EDNS0 option is used to give the remote nameserver an idea of where the client lives. It can then give back a different answer depending on the location or network topology. Basic use pattern for creating an subnet option:

o := new(dns.OPT)
o.Hdr.Name = "."
o.Hdr.Rrtype = dns.TypeOPT
e := new(dns.EDNS0_SUBNET)
e.Code = dns.EDNS0SUBNET
e.Family = 1	// 1 for IPv4 source address, 2 for IPv6
e.NetMask = 32	// 32 for IPV4, 128 for IPv6
e.SourceScope = 0
e.Address = net.ParseIP("127.0.0.1").To4()	// for IPv4
// e.Address = net.ParseIP("2001:7b8:32a::2")	// for IPV6
o.Option = append(o.Option, e)

func (*EDNS0_SUBNET) Option

func (e *EDNS0_SUBNET) Option() uint16

func (*EDNS0_SUBNET) String

func (e *EDNS0_SUBNET) String() (s string)

type EDNS0_UPDATE_LEASE

type EDNS0_UPDATE_LEASE struct {
	Code  uint16 // Always EDNS0UPDATELEASE
	Lease uint32
}

func (*EDNS0_UPDATE_LEASE) Option

func (e *EDNS0_UPDATE_LEASE) Option() uint16

func (*EDNS0_UPDATE_LEASE) String

func (e *EDNS0_UPDATE_LEASE) String() string

type Envelope

type Envelope struct {
	RR    []RR  // The set of RRs in the answer section of the AXFR reply message.
	Error error // If something went wrong, this contains the error.
}

Envelope is used when doing [IA]XFR with a remote server.

type Error

type Error struct {
	Err     string
	Name    string
	Server  net.Addr
	Timeout bool
}

Error represents a DNS error

func (*Error) Error

func (e *Error) Error() string

type HINFO

type HINFO struct {
	Hdr RR_Header
	Cpu string
	Os  string
}

func (*HINFO) Copy

func (rr *HINFO) Copy() RR

func (*HINFO) Header

func (rr *HINFO) Header() *RR_Header

func (*HINFO) Len

func (rr *HINFO) Len() int

func (*HINFO) String

func (rr *HINFO) String() string

type HIP

type HIP struct {
	Hdr                RR_Header
	HitLength          uint8
	PublicKeyAlgorithm uint8
	PublicKeyLength    uint16
	Hit                string   `dns:"hex"`
	PublicKey          string   `dns:"base64"`
	RendezvousServers  []string `dns:"domain-name"`
}
Example
h := `www.example.com      IN  HIP ( 2 200100107B1A74DF365639CC39F1D578
                AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ
b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
        rvs.example.com. )`
if hip, err := NewRR(h); err == nil {
	fmt.Printf("%s\n", hip.String())
}
Output:

www.example.com.	3600	IN	HIP	 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.

func (*HIP) Copy

func (rr *HIP) Copy() RR

func (*HIP) Header

func (rr *HIP) Header() *RR_Header

func (*HIP) Len

func (rr *HIP) Len() int

func (*HIP) String

func (rr *HIP) String() string

type Handler

type Handler interface {
	ServeDNS(w ResponseWriter, r *Msg)
}

type HandlerFunc

type HandlerFunc func(ResponseWriter, *Msg)

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 object that calls f.

func (HandlerFunc) ServeDNS

func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg)

ServerDNS calls f(w, r)

type Header struct {
	Id                                 uint16
	Bits                               uint16
	Qdcount, Ancount, Nscount, Arcount uint16
}

The wire format for the DNS packet header.

type IPSECKEY

type IPSECKEY struct {
	Hdr         RR_Header
	Precedence  uint8
	GatewayType uint8
	Algorithm   uint8
	Gateway     string `dns:"ipseckey"`
	PublicKey   string `dns:"base64"`
}

func (*IPSECKEY) Copy

func (rr *IPSECKEY) Copy() RR

func (*IPSECKEY) Header

func (rr *IPSECKEY) Header() *RR_Header

func (*IPSECKEY) Len

func (rr *IPSECKEY) Len() int

func (*IPSECKEY) String

func (rr *IPSECKEY) String() string

type KX

type KX struct {
	Hdr        RR_Header
	Preference uint16
	Exchanger  string `dns:"domain-name"`
}

func (*KX) Copy

func (rr *KX) Copy() RR

func (*KX) Header

func (rr *KX) Header() *RR_Header

func (*KX) Len

func (rr *KX) Len() int

func (*KX) String

func (rr *KX) String() string

type L32

type L32 struct {
	Hdr        RR_Header
	Preference uint16
	Locator32  net.IP `dns:"a"`
}

func (*L32) Copy

func (rr *L32) Copy() RR

func (*L32) Header

func (rr *L32) Header() *RR_Header

func (*L32) Len

func (rr *L32) Len() int

func (*L32) String

func (rr *L32) String() string

type L64

type L64 struct {
	Hdr        RR_Header
	Preference uint16
	Locator64  uint64
}

func (*L64) Copy

func (rr *L64) Copy() RR

func (*L64) Header

func (rr *L64) Header() *RR_Header

func (*L64) Len

func (rr *L64) Len() int

func (*L64) String

func (rr *L64) String() string

type LOC

type LOC struct {
	Hdr       RR_Header
	Version   uint8
	Size      uint8
	HorizPre  uint8
	VertPre   uint8
	Latitude  uint32
	Longitude uint32
	Altitude  uint32
}

func (*LOC) Copy

func (rr *LOC) Copy() RR

func (*LOC) Header

func (rr *LOC) Header() *RR_Header

func (*LOC) Len

func (rr *LOC) Len() int

func (*LOC) String

func (rr *LOC) String() string

type LP

type LP struct {
	Hdr        RR_Header
	Preference uint16
	Fqdn       string `dns:"domain-name"`
}

func (*LP) Copy

func (rr *LP) Copy() RR

func (*LP) Header

func (rr *LP) Header() *RR_Header

func (*LP) Len

func (rr *LP) Len() int

func (*LP) String

func (rr *LP) String() string

type MB

type MB struct {
	Hdr RR_Header
	Mb  string `dns:"cdomain-name"`
}

func (*MB) Copy

func (rr *MB) Copy() RR

func (*MB) Header

func (rr *MB) Header() *RR_Header

func (*MB) Len

func (rr *MB) Len() int

func (*MB) String

func (rr *MB) String() string

type MD

type MD struct {
	Hdr RR_Header
	Md  string `dns:"cdomain-name"`
}

func (*MD) Copy

func (rr *MD) Copy() RR

func (*MD) Header

func (rr *MD) Header() *RR_Header

func (*MD) Len

func (rr *MD) Len() int

func (*MD) String

func (rr *MD) String() string

type MF

type MF struct {
	Hdr RR_Header
	Mf  string `dns:"cdomain-name"`
}

func (*MF) Copy

func (rr *MF) Copy() RR

func (*MF) Header

func (rr *MF) Header() *RR_Header

func (*MF) Len

func (rr *MF) Len() int

func (*MF) String

func (rr *MF) String() string

type MG

type MG struct {
	Hdr RR_Header
	Mg  string `dns:"cdomain-name"`
}

func (*MG) Copy

func (rr *MG) Copy() RR

func (*MG) Header

func (rr *MG) Header() *RR_Header

func (*MG) Len

func (rr *MG) Len() int

func (*MG) String

func (rr *MG) String() string

type MINFO

type MINFO struct {
	Hdr   RR_Header
	Rmail string `dns:"cdomain-name"`
	Email string `dns:"cdomain-name"`
}

func (*MINFO) Copy

func (rr *MINFO) Copy() RR

func (*MINFO) Header

func (rr *MINFO) Header() *RR_Header

func (*MINFO) Len

func (rr *MINFO) Len() int

func (*MINFO) String

func (rr *MINFO) String() string

type MR

type MR struct {
	Hdr RR_Header
	Mr  string `dns:"cdomain-name"`
}

func (*MR) Copy

func (rr *MR) Copy() RR

func (*MR) Header

func (rr *MR) Header() *RR_Header

func (*MR) Len

func (rr *MR) Len() int

func (*MR) String

func (rr *MR) String() string

type MX

type MX struct {
	Hdr        RR_Header
	Preference uint16
	Mx         string `dns:"cdomain-name"`
}

func (*MX) Copy

func (rr *MX) Copy() RR

func (*MX) Header

func (rr *MX) Header() *RR_Header

func (*MX) Len

func (rr *MX) Len() int

func (*MX) String

func (rr *MX) String() string

type Msg

type Msg struct {
	MsgHdr
	Compress bool       // If true, the message will be compressed when converted to wire format.
	Size     int        // Number of octects in the message received from the wire.
	Question []Question // Holds the RR(s) of the question section.
	Answer   []RR       // Holds the RR(s) of the answer section.
	Ns       []RR       // Holds the RR(s) of the authority section.
	Extra    []RR       // Holds the RR(s) of the additional section.
}

The layout of a DNS message.

func (*Msg) Insert

func (u *Msg) Insert(rr []RR)

Insert creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1.

func (*Msg) IsEdns0

func (dns *Msg) IsEdns0() *OPT

IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0 record in the additional section will do. It returns the OPT record found or nil.

func (*Msg) IsTsig

func (dns *Msg) IsTsig() *TSIG

IsTsig checks if the message has a TSIG record as the last record in the additional section. It returns the TSIG record found or nil.

func (*Msg) Len

func (dns *Msg) Len() int

Len return the message length when in (un)compressed wire format. If dns.Compress is true compression is taken into account, currently this only counts owner name compression. There is no check for nil valued sections (allocated, but contains no RRs).

func (*Msg) NameNotUsed

func (u *Msg) NameNotUsed(rr []RR)

NameNotUsed sets the RRs in the prereq section to "Name is in not use" RRs. RFC 2136 section 2.4.5.

func (*Msg) NameUsed

func (u *Msg) NameUsed(rr []RR)

NameUsed sets the RRs in the prereq section to "Name is in use" RRs. RFC 2136 section 2.4.4.

func (*Msg) Pack

func (dns *Msg) Pack() (msg []byte, err error)

Pack packs a Msg: it is converted to to wire format. If the dns.Compress is true the message will be in compressed wire format.

func (*Msg) RRsetNotUsed

func (u *Msg) RRsetNotUsed(rr []RR)

RRsetNotUsed sets the RRs in the prereq section to "RRset does not exist" RRs. RFC 2136 section 2.4.3.

func (*Msg) RRsetUsed

func (u *Msg) RRsetUsed(rr []RR)

RRsetUsed sets the RRs in the prereq section to "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1.

func (*Msg) Remove

func (u *Msg) Remove(rr []RR)

Remove creates a dynamic update packet deletes RR from the RRSset, see RFC 2136 section 2.5.4

func (*Msg) RemoveName

func (u *Msg) RemoveName(rr []RR)

RemoveName creates a dynamic update packet that deletes all RRsets of a name, see RFC 2136 section 2.5.3

func (*Msg) RemoveRRset

func (u *Msg) RemoveRRset(rr []RR)

RemoveRRset creates a dynamic update packet that deletes an RRset, see RFC 2136 section 2.5.2.

func (*Msg) SetAxfr

func (dns *Msg) SetAxfr(z string) *Msg

SetAxfr creates dns.Msg for requesting an AXFR.

func (*Msg) SetEdns0

func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg

SetEdns0 appends a EDNS0 OPT RR to the message. TSIG should always the last RR in a message.

func (*Msg) SetIxfr

func (dns *Msg) SetIxfr(z string, serial uint32) *Msg

SetIxfr creates dns.Msg for requesting an IXFR.

func (*Msg) SetNotify

func (dns *Msg) SetNotify(z string) *Msg

SetNotify creates a notify packet.

func (*Msg) SetQuestion

func (dns *Msg) SetQuestion(z string, t uint16) *Msg

SetQuestion creates a question packet.

func (*Msg) SetRcode

func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg

SetRcode creates an error packet suitable for the request.

func (*Msg) SetRcodeFormatError

func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg

SetRcodeFormatError creates a packet with FormError set.

func (*Msg) SetReply

func (dns *Msg) SetReply(request *Msg) *Msg

SetReply creates a reply packet from a request message.

func (*Msg) SetTsig

func (dns *Msg) SetTsig(z, algo string, fudge, timesigned int64) *Msg

SetTsig appends a TSIG RR to the message. This is only a skeleton TSIG RR that is added as the last RR in the additional section. The Tsig is calculated when the message is being send.

func (*Msg) SetUpdate

func (dns *Msg) SetUpdate(z string) *Msg

SetUpdate makes the message a dynamic update packet. It sets the ZONE section to: z, TypeSOA, ClassINET.

func (*Msg) String

func (dns *Msg) String() string

Convert a complete message to a string with dig-like output.

func (*Msg) Unpack

func (dns *Msg) Unpack(msg []byte) (err error)

Unpack unpacks a binary message to a Msg structure.

func (*Msg) Used

func (u *Msg) Used(rr []RR)

Used sets the RRs in the prereq section to "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2.

type MsgHdr

type MsgHdr struct {
	Id                 uint16
	Response           bool
	Opcode             int
	Authoritative      bool
	Truncated          bool
	RecursionDesired   bool
	RecursionAvailable bool
	Zero               bool
	AuthenticatedData  bool
	CheckingDisabled   bool
	Rcode              int
}

A manually-unpacked version of (id, bits). This is in its own struct for easy printing.

func (*MsgHdr) String

func (h *MsgHdr) String() string

Convert a MsgHdr to a string, with dig-like headers:

;; opcode: QUERY, status: NOERROR, id: 48404

;; flags: qr aa rd ra;

type NAPTR

type NAPTR struct {
	Hdr         RR_Header
	Order       uint16
	Preference  uint16
	Flags       string
	Service     string
	Regexp      string
	Replacement string `dns:"domain-name"`
}

func (*NAPTR) Copy

func (rr *NAPTR) Copy() RR

func (*NAPTR) Header

func (rr *NAPTR) Header() *RR_Header

func (*NAPTR) Len

func (rr *NAPTR) Len() int

func (*NAPTR) String

func (rr *NAPTR) String() string

type NID

type NID struct {
	Hdr        RR_Header
	Preference uint16
	NodeID     uint64
}

func (*NID) Copy

func (rr *NID) Copy() RR

func (*NID) Header

func (rr *NID) Header() *RR_Header

func (*NID) Len

func (rr *NID) Len() int

func (*NID) String

func (rr *NID) String() string

type NINFO

type NINFO struct {
	Hdr    RR_Header
	ZSData []string `dns:"txt"`
}

func (*NINFO) Copy

func (rr *NINFO) Copy() RR

func (*NINFO) Header

func (rr *NINFO) Header() *RR_Header

func (*NINFO) Len

func (rr *NINFO) Len() int

func (*NINFO) String

func (rr *NINFO) String() string

type NS

type NS struct {
	Hdr RR_Header
	Ns  string `dns:"cdomain-name"`
}

func (*NS) Copy

func (rr *NS) Copy() RR

func (*NS) Header

func (rr *NS) Header() *RR_Header

func (*NS) Len

func (rr *NS) Len() int

func (*NS) String

func (rr *NS) String() string

type NSEC

type NSEC struct {
	Hdr        RR_Header
	NextDomain string   `dns:"domain-name"`
	TypeBitMap []uint16 `dns:"nsec"`
}

func (*NSEC) Copy

func (rr *NSEC) Copy() RR

func (*NSEC) Cover

func (rr *NSEC) Cover(domain string) bool

Cover checks if domain is covered by the NSEC record. Domain must be given in plain text.

func (*NSEC) Header

func (rr *NSEC) Header() *RR_Header

func (*NSEC) Len

func (rr *NSEC) Len() int

func (*NSEC) Match

func (rr *NSEC) Match(domain string) bool

Implement the Match method of Denialer

func (*NSEC) MatchType

func (rr *NSEC) MatchType(rrtype uint16) bool

func (*NSEC) String

func (rr *NSEC) String() string

type NSEC3

type NSEC3 struct {
	Hdr        RR_Header
	Hash       uint8
	Flags      uint8
	Iterations uint16
	SaltLength uint8
	Salt       string `dns:"size-hex"`
	HashLength uint8
	NextDomain string   `dns:"size-base32"`
	TypeBitMap []uint16 `dns:"nsec"`
}

func (*NSEC3) Copy

func (rr *NSEC3) Copy() RR

func (*NSEC3) Cover

func (rr *NSEC3) Cover(domain string) bool

Cover checks if domain is covered by the NSEC3 record. Domain must be given in plain text (i.e. not hashed) TODO(mg): this doesn't loop around TODO(mg): make a CoverHashed variant?

func (*NSEC3) HashNames

func (rr *NSEC3) HashNames(domain string)

Implement the HashNames method of Denialer

func (*NSEC3) Header

func (rr *NSEC3) Header() *RR_Header

func (*NSEC3) Len

func (rr *NSEC3) Len() int

func (*NSEC3) Match

func (rr *NSEC3) Match(domain string) bool

Implement the Match method of Denialer

func (*NSEC3) MatchType

func (rr *NSEC3) MatchType(rrtype uint16) bool

func (*NSEC3) String

func (rr *NSEC3) String() string

type NSEC3PARAM

type NSEC3PARAM struct {
	Hdr        RR_Header
	Hash       uint8
	Flags      uint8
	Iterations uint16
	SaltLength uint8
	Salt       string `dns:"hex"`
}

func (*NSEC3PARAM) Copy

func (rr *NSEC3PARAM) Copy() RR

func (*NSEC3PARAM) Header

func (rr *NSEC3PARAM) Header() *RR_Header

func (*NSEC3PARAM) Len

func (rr *NSEC3PARAM) Len() int

func (*NSEC3PARAM) String

func (rr *NSEC3PARAM) String() string

type OPT

type OPT struct {
	Hdr    RR_Header
	Option []EDNS0 `dns:"opt"`
}

func (*OPT) Copy

func (rr *OPT) Copy() RR

func (*OPT) Do

func (rr *OPT) Do() bool

Do returns the value of the DO (DNSSEC OK) bit.

func (*OPT) Header

func (rr *OPT) Header() *RR_Header

func (*OPT) Len

func (rr *OPT) Len() int

func (*OPT) SetDo

func (rr *OPT) SetDo()

SetDo sets the DO (DNSSEC OK) bit.

func (*OPT) SetUDPSize

func (rr *OPT) SetUDPSize(size uint16)

SetUDPSize sets the UDP buffer size.

func (*OPT) SetVersion

func (rr *OPT) SetVersion(v uint8)

SetVersion sets the version of EDNS. This is usually zero.

func (*OPT) String

func (rr *OPT) String() string

func (*OPT) UDPSize

func (rr *OPT) UDPSize() uint16

UDPSize returns the UDP buffer size.

func (*OPT) Version

func (rr *OPT) Version() uint8

Version returns the EDNS version used. Only zero is defined.

type PTR

type PTR struct {
	Hdr RR_Header
	Ptr string `dns:"cdomain-name"`
}

func (*PTR) Copy

func (rr *PTR) Copy() RR

func (*PTR) Header

func (rr *PTR) Header() *RR_Header

func (*PTR) Len

func (rr *PTR) Len() int

func (*PTR) String

func (rr *PTR) String() string

type ParseError

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

ParseError is a parsing error. It contains the parse error and the location in the io.Reader where the error occured.

func (*ParseError) Error

func (e *ParseError) Error() (s string)

type PrivateKey

type PrivateKey interface{}

Empty interface that is used as a wrapper around all possible private key implementations from the crypto package.

type Question

type Question struct {
	Name   string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed)
	Qtype  uint16
	Qclass uint16
}

DNS queries.

func (*Question) Len

func (q *Question) Len() int

func (*Question) String

func (q *Question) String() (s string)

type RFC3597

type RFC3597 struct {
	Hdr   RR_Header
	Rdata string `dns:"hex"`
}

RFC3597 representes an unknown RR.

func (*RFC3597) Copy

func (rr *RFC3597) Copy() RR

func (*RFC3597) Header

func (rr *RFC3597) Header() *RR_Header

func (*RFC3597) Len

func (rr *RFC3597) Len() int

func (*RFC3597) String

func (rr *RFC3597) String() string

type RKEY

type RKEY struct {
	Hdr       RR_Header
	Flags     uint16
	Protocol  uint8
	Algorithm uint8
	PublicKey string `dns:"base64"`
}

func (*RKEY) Copy

func (rr *RKEY) Copy() RR

func (*RKEY) Header

func (rr *RKEY) Header() *RR_Header

func (*RKEY) Len

func (rr *RKEY) Len() int

func (*RKEY) String

func (rr *RKEY) String() string

type RP

type RP struct {
	Hdr  RR_Header
	Mbox string `dns:"domain-name"`
	Txt  string `dns:"domain-name"`
}

func (*RP) Copy

func (rr *RP) Copy() RR

func (*RP) Header

func (rr *RP) Header() *RR_Header

func (*RP) Len

func (rr *RP) Len() int

func (*RP) String

func (rr *RP) String() string

type RR

type RR interface {
	// Header returns the header of an resource record. The header contains
	// everything up to the rdata.
	Header() *RR_Header
	// String returns the text representation of the resource record.
	String() string
	// Len returns the length (in octects) of the uncompressed RR in wire format.
	Len() int
	// Copy returns a copy of the RR
	Copy() RR
}

An RR represents a resource record.

func NewRR

func NewRR(s string) (RR, error)

NewRR reads the RR contained in the string s. Only the first RR is returned. The class defaults to IN and TTL defaults to 3600. The full zone file syntax like $TTL, $ORIGIN, etc. is supported.

func ReadRR

func ReadRR(q io.Reader, filename string) (RR, error)

ReadRR reads the RR contained in q. Only the first RR is returned. The class defaults to IN and TTL defaults to 3600.

func UnpackRR

func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error)

Resource record unpacker, unpack msg[off:] into an RR.

type RRSIG

type RRSIG struct {
	Hdr         RR_Header
	TypeCovered uint16
	Algorithm   uint8
	Labels      uint8
	OrigTtl     uint32
	Expiration  uint32
	Inception   uint32
	KeyTag      uint16
	SignerName  string `dns:"domain-name"`
	Signature   string `dns:"base64"`
}

func (*RRSIG) Copy

func (rr *RRSIG) Copy() RR

func (*RRSIG) Header

func (rr *RRSIG) Header() *RR_Header

func (*RRSIG) Len

func (rr *RRSIG) Len() int

func (*RRSIG) Sign

func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error

Sign signs an RRSet. The signature needs to be filled in with the values: Inception, Expiration, KeyTag, SignerName and Algorithm. The rest is copied from the RRset. Sign returns true when the signing went OK, otherwise false. There is no check if RRSet is a proper (RFC 2181) RRSet.

func (*RRSIG) String

func (rr *RRSIG) String() string

func (*RRSIG) ValidityPeriod

func (rr *RRSIG) ValidityPeriod() bool

ValidityPeriod uses RFC1982 serial arithmetic to calculate if a signature period is valid.

func (*RRSIG) Verify

func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error

Verify validates an RRSet with the signature and key. This is only the cryptographic test, the signature validity period must be checked separately. This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.

type RR_Header

type RR_Header struct {
	Name     string `dns:"cdomain-name"`
	Rrtype   uint16
	Class    uint16
	Ttl      uint32
	Rdlength uint16 // length of data after header
}

DNS resource records. There are many types of RRs, but they all share the same header.

func (*RR_Header) Copy

func (h *RR_Header) Copy() RR

Just to imlement the RR interface

func (*RR_Header) CopyHeader

func (h *RR_Header) CopyHeader() *RR_Header

func (*RR_Header) Header

func (h *RR_Header) Header() *RR_Header

func (*RR_Header) Len

func (h *RR_Header) Len() int

func (*RR_Header) String

func (h *RR_Header) String() string

type RT

type RT struct {
	Hdr        RR_Header
	Preference uint16
	Host       string `dns:"cdomain-name"`
}

func (*RT) Copy

func (rr *RT) Copy() RR

func (*RT) Header

func (rr *RT) Header() *RR_Header

func (*RT) Len

func (rr *RT) Len() int

func (*RT) String

func (rr *RT) String() string

type ResponseWriter

type ResponseWriter interface {
	// RemoteAddr returns the net.Addr of the client that sent the current request.
	RemoteAddr() net.Addr
	// WriteMsg writes a reply back to the client.
	WriteMsg(*Msg) error
	// Write writes a raw buffer back to the client.
	Write([]byte) (int, error)
	// Close closes the connection.
	Close() error
	// TsigStatus returns the status of the Tsig.
	TsigStatus() error
	// TsigTimersOnly sets the tsig timers only boolean.
	TsigTimersOnly(bool)
	// Hijack lets the caller take over the connection.
	// After a call to Hijack(), the DNS package will not do anything with the connection
	Hijack()
}

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

type SOA

type SOA struct {
	Hdr     RR_Header
	Ns      string `dns:"cdomain-name"`
	Mbox    string `dns:"cdomain-name"`
	Serial  uint32
	Refresh uint32
	Retry   uint32
	Expire  uint32
	Minttl  uint32
}
Example
s := "example.com. 1000 SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100"
if soa, err := NewRR(s); err == nil {
	fmt.Printf("%s\n", soa.String())
}
Output:

example.com.	1000	IN	SOA	master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100

func (*SOA) Copy

func (rr *SOA) Copy() RR

func (*SOA) Header

func (rr *SOA) Header() *RR_Header

func (*SOA) Len

func (rr *SOA) Len() int

func (*SOA) String

func (rr *SOA) String() string

type SPF

type SPF struct {
	Hdr RR_Header
	Txt []string `dns:"txt"`
}

func (*SPF) Copy

func (rr *SPF) Copy() RR

func (*SPF) Header

func (rr *SPF) Header() *RR_Header

func (*SPF) Len

func (rr *SPF) Len() int

func (*SPF) String

func (rr *SPF) String() string

type SRV

type SRV struct {
	Hdr      RR_Header
	Priority uint16
	Weight   uint16
	Port     uint16
	Target   string `dns:"domain-name"`
}

func (*SRV) Copy

func (rr *SRV) Copy() RR

func (*SRV) Header

func (rr *SRV) Header() *RR_Header

func (*SRV) Len

func (rr *SRV) Len() int

func (*SRV) String

func (rr *SRV) String() string

type SSHFP

type SSHFP struct {
	Hdr         RR_Header
	Algorithm   uint8
	Type        uint8
	FingerPrint string `dns:"hex"`
}

func (*SSHFP) Copy

func (rr *SSHFP) Copy() RR

func (*SSHFP) Header

func (rr *SSHFP) Header() *RR_Header

func (*SSHFP) Len

func (rr *SSHFP) Len() int

func (*SSHFP) String

func (rr *SSHFP) String() string

type ServeMux

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

ServeMux is an DNS request multiplexer. It matches the zone name of each incoming request against a list of registered patterns add calls the handler for the pattern that most closely matches the zone name. ServeMux is DNSSEC aware, meaning that queries for the DS record are redirected to the parent zone (if that is also registered), otherwise the child gets the query.

func NewServeMux

func NewServeMux() *ServeMux

NewServeMux allocates and returns a new ServeMux.

func (*ServeMux) Handle

func (mux *ServeMux) Handle(pattern string, handler Handler)

Handle adds a handler to the ServeMux for pattern.

func (*ServeMux) HandleFunc

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg))

Handle adds a handler to the ServeMux for pattern.

func (*ServeMux) HandleRemove

func (mux *ServeMux) HandleRemove(pattern string)

HandleRemove deregistrars the handler specific for pattern from the ServeMux.

func (*ServeMux) ServeDNS

func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg)

ServeDNS dispatches the request to the handler whose pattern most closely matches the request message. If DefaultServeMux is used the correct thing for DS queries is done: a possible parent is sought. If no handler is found a standard SERVFAIL message is returned If the request message does not have a single question in the question section a SERVFAIL is returned.

type Server

type Server struct {
	Addr         string            // address to listen on, ":dns" if empty
	Net          string            // if "tcp" it will invoke a TCP listener, otherwise an UDP one
	Handler      Handler           // handler to invoke, dns.DefaultServeMux if nil
	UDPSize      int               // default buffer size to use to read incoming UDP messages
	ReadTimeout  time.Duration     // the net.Conn.SetReadTimeout value for new connections
	WriteTimeout time.Duration     // the net.Conn.SetWriteTimeout value for new connections
	TsigSecret   map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
}

A Server defines parameters for running an DNS server.

func (*Server) ListenAndServe

func (srv *Server) ListenAndServe() error

ListenAndServe starts a nameserver on the configured address in *Server.

type SignatureConfig

type SignatureConfig struct {
	// Validity period of the signatures, typically 2 to 4 weeks.
	Validity time.Duration
	// When the end of the validity approaches, how much time should remain
	// before we start to resign. Typical value is 3 days.
	Refresh time.Duration
	// Jitter is an random amount of time added or subtracted from the
	// expiration time to ensure not all signatures expire a the same time.
	// Typical value is 12 hours, which means the actual jitter value is
	// between -12..0..+12.
	Jitter time.Duration
	// InceptionOffset is subtracted from the inception time to ensure badly
	// calibrated clocks on the internet can still validate a signature.
	// Typical value is 300 seconds.
	InceptionOffset time.Duration
	// HonorSepFlag is a boolean which when try instructs the signer to use
	// a KSK/ZSK split and only sign the keyset with the KSK(s). If not
	// set all records are signed with all keys. If this flag is true and
	// a single KSK is used for signing, only the keyset is signed.
	HonorSepFlag bool
	// SignerRoutines specifies the number of signing goroutines, if not
	// set runtime.NumCPU() + 1 is used as the value.
	SignerRoutines int
	// SOA Minttl value must be used as the ttl on NSEC/NSEC3 records.
	Minttl uint32
}

SignatureConfig holds the parameters for zone (re)signing. This is copied from OpenDNSSEC. See: https://wiki.opendnssec.org/display/DOCS/kasp.xml

type TA

type TA struct {
	Hdr        RR_Header
	KeyTag     uint16
	Algorithm  uint8
	DigestType uint8
	Digest     string `dns:"hex"`
}

func (*TA) Copy

func (rr *TA) Copy() RR

func (*TA) Header

func (rr *TA) Header() *RR_Header

func (*TA) Len

func (rr *TA) Len() int

func (*TA) String

func (rr *TA) String() string
type TALINK struct {
	Hdr          RR_Header
	PreviousName string `dns:"domain"`
	NextName     string `dns:"domain"`
}

func (*TALINK) Copy

func (rr *TALINK) Copy() RR

func (*TALINK) Header

func (rr *TALINK) Header() *RR_Header

func (*TALINK) Len

func (rr *TALINK) Len() int

func (*TALINK) String

func (rr *TALINK) String() string

type TKEY

type TKEY struct {
	Hdr        RR_Header
	Algorithm  string `dns:"domain-name"`
	Inception  uint32
	Expiration uint32
	Mode       uint16
	Error      uint16
	KeySize    uint16
	Key        string
	OtherLen   uint16
	OtherData  string
}

func (*TKEY) Copy

func (rr *TKEY) Copy() RR

func (*TKEY) Header

func (rr *TKEY) Header() *RR_Header

func (*TKEY) Len

func (rr *TKEY) Len() int

func (*TKEY) String

func (rr *TKEY) String() string

type TLSA

type TLSA struct {
	Hdr          RR_Header
	Usage        uint8
	Selector     uint8
	MatchingType uint8
	Certificate  string `dns:"hex"`
}

func (*TLSA) Copy

func (rr *TLSA) Copy() RR

func (*TLSA) Header

func (rr *TLSA) Header() *RR_Header

func (*TLSA) Len

func (rr *TLSA) Len() int

func (*TLSA) Sign

func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) error

Sign creates a TLSA record from an SSL certificate.

func (*TLSA) String

func (rr *TLSA) String() string

func (*TLSA) Verify

func (r *TLSA) Verify(cert *x509.Certificate) error

Verify verifies a TLSA record against an SSL certificate. If it is OK a nil error is returned.

type TSIG

type TSIG struct {
	Hdr        RR_Header
	Algorithm  string `dns:"domain-name"`
	TimeSigned uint64 `dns:"uint48"`
	Fudge      uint16
	MACSize    uint16
	MAC        string `dns:"size-hex"`
	OrigId     uint16
	Error      uint16
	OtherLen   uint16
	OtherData  string `dns:"size-hex"`
}

func (*TSIG) Copy

func (rr *TSIG) Copy() RR

func (*TSIG) Header

func (rr *TSIG) Header() *RR_Header

func (*TSIG) Len

func (rr *TSIG) Len() int

func (*TSIG) String

func (rr *TSIG) String() string

type TXT

type TXT struct {
	Hdr RR_Header
	Txt []string `dns:"txt"`
}

func (*TXT) Copy

func (rr *TXT) Copy() RR

func (*TXT) Header

func (rr *TXT) Header() *RR_Header

func (*TXT) Len

func (rr *TXT) Len() int

func (*TXT) String

func (rr *TXT) String() string

type Token

type Token struct {
	RR                // the scanned resource record when error is not nil
	Error *ParseError // when an error occured, this has the error specifics
}

Tokens are returned when a zone file is parsed.

type URI

type URI struct {
	Hdr      RR_Header
	Priority uint16
	Weight   uint16
	Target   string `dns:"txt"`
}

func (*URI) Copy

func (rr *URI) Copy() RR

func (*URI) Header

func (rr *URI) Header() *RR_Header

func (*URI) Len

func (rr *URI) Len() int

func (*URI) String

func (rr *URI) String() string

type WKS

type WKS struct {
	Hdr      RR_Header
	Address  net.IP `dns:"a"`
	Protocol uint8
	BitMap   []uint16 `dns:"wks"`
}

func (*WKS) Copy

func (rr *WKS) Copy() RR

func (*WKS) Header

func (rr *WKS) Header() *RR_Header

func (*WKS) Len

func (rr *WKS) Len() int

func (*WKS) String

func (rr *WKS) String() string

type X25

type X25 struct {
	Hdr         RR_Header
	PSDNAddress string
}

func (*X25) Copy

func (rr *X25) Copy() RR

func (*X25) Header

func (rr *X25) Header() *RR_Header

func (*X25) Len

func (rr *X25) Len() int

func (*X25) String

func (rr *X25) String() string

type Zone

type Zone struct {
	Origin string // Origin of the zone

	Wildcard int // Whenever we see a wildcard name, this is incremented

	ModTime      time.Time // When is the zone last modified
	*radix.Radix           // Zone data
	*sync.RWMutex
	// contains filtered or unexported fields
}

Zone represents a DNS zone. It's safe for concurrent use by multilpe goroutines.

Example
zone := `$ORIGIN .
$TTL 3600       ; 1 hour
name                    IN SOA  a6.nstld.com. hostmaster.nic.name. (
                                203362132  ; serial
                                300        ; refresh (5 minutes)
                                300        ; retry (5 minutes)
                                1209600    ; expire (2 weeks)
                                300        ; minimum (5 minutes)
                                )
$TTL 10800      ; 3 hours
name.	10800	IN	NS	name.
               IN       NS      g6.nstld.com.
               7200     NS      h6.nstld.com.
             3600 IN    NS      j6.nstld.com.
             IN 3600    NS      k6.nstld.com.
                        NS      l6.nstld.com.
                        NS      a6.nstld.com.
                        NS      c6.nstld.com.
                        NS      d6.nstld.com.
                        NS      f6.nstld.com.
                        NS      m6.nstld.com.
( 
			NS	m7.nstld.com.
)
$ORIGIN name.
0-0onlus                NS      ns7.ehiweb.it.
                        NS      ns8.ehiweb.it.
0-g                     MX      10 mx01.nic
                        MX      10 mx02.nic
                        MX      10 mx03.nic
                        MX      10 mx04.nic
$ORIGIN 0-g.name
moutamassey             NS      ns01.yahoodomains.jp.
                        NS      ns02.yahoodomains.jp.
`
to := ParseZone(strings.NewReader(zone), "", "testzone")
for x := range to {
	fmt.Printf("%s\n", x.RR)
}
Output:

name.	3600	IN	SOA	a6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300
name.	10800	IN	NS	name.
name.	10800	IN	NS	g6.nstld.com.
name.	7200	IN	NS	h6.nstld.com.
name.	3600	IN	NS	j6.nstld.com.
name.	3600	IN	NS	k6.nstld.com.
name.	10800	IN	NS	l6.nstld.com.
name.	10800	IN	NS	a6.nstld.com.
name.	10800	IN	NS	c6.nstld.com.
name.	10800	IN	NS	d6.nstld.com.
name.	10800	IN	NS	f6.nstld.com.
name.	10800	IN	NS	m6.nstld.com.
name.	10800	IN	NS	m7.nstld.com.
0-0onlus.name.	10800	IN	NS	ns7.ehiweb.it.
0-0onlus.name.	10800	IN	NS	ns8.ehiweb.it.
0-g.name.	10800	IN	MX	10 mx01.nic.name.
0-g.name.	10800	IN	MX	10 mx02.nic.name.
0-g.name.	10800	IN	MX	10 mx03.nic.name.
0-g.name.	10800	IN	MX	10 mx04.nic.name.
moutamassey.0-g.name.name.	10800	IN	NS	ns01.yahoodomains.jp.
moutamassey.0-g.name.name.	10800	IN	NS	ns02.yahoodomains.jp.

func NewZone

func NewZone(origin string) *Zone

NewZone creates an initialized zone with Origin set to origin.

func (*Zone) Apex

func (z *Zone) Apex() *ZoneData

Apex returns the zone's apex records (SOA, NS and possibly other). If the apex can not be found (thereby making it an illegal DNS zone) it returns nil. Updating the zone's SOA serial, provided the apex exists:

z.Apex.RR[TypeSOA][0].(*SOA).Serial++

Note the a) this increment is not protected by locks and b) if you use DNSSEC you MUST resign the SOA record.

func (*Zone) Find

func (z *Zone) Find(s string) (node *ZoneData, exact bool)

Find looks up the ownername s in the zone and returns the data and true when an exact match is found. If an exact find isn't possible the first parent node with a non-nil Value is returned and the boolean is false.

func (*Zone) FindFunc

func (z *Zone) FindFunc(s string, f func(interface{}) bool) (*ZoneData, bool, bool)

FindFunc works like Find, but the function f is executed on each node which has a non-nil Value during the tree traversal. If f returns true, that node is returned.

func (*Zone) Insert

func (z *Zone) Insert(r RR) error

Insert inserts the RR r into the zone. There is no check for duplicate data, although Remove will remove all duplicates.

func (*Zone) Remove

func (z *Zone) Remove(r RR) error

Remove removes the RR r from the zone. If the RR can not be found, this is a no-op.

func (*Zone) RemoveName

func (z *Zone) RemoveName(s string) error

RemoveName removes all the RRs with ownername matching s from the zone. Typical use of this method is when processing a RemoveName dynamic update packet.

func (*Zone) RemoveRRset

func (z *Zone) RemoveRRset(s string, t uint16) error

RemoveRRset removes all the RRs with the ownername matching s and the type matching t from the zone. Typical use of this method is when processing a RemoveRRset dynamic update packet.

func (*Zone) Sign

func (z *Zone) Sign(keys map[*DNSKEY]PrivateKey, config *SignatureConfig) error

Sign (re)signs the zone z with the given keys. NSECs and RRSIGs are added as needed. The public keys themselves are not added to the zone. If config is nil DefaultSignatureConfig is used. The signatureConfig describes how the zone must be signed and if the SEP flag (for KSK) should be honored. If signatures approach their expriration time, they are refreshed with the current set of keys. Valid signatures are left alone.

Basic use pattern for signing a zone with the default SignatureConfig:

// A single PublicKey/PrivateKey have been read from disk.
e := z.Sign(map[*dns.DNSKEY]dns.PrivateKey{pubkey.(*dns.DNSKEY): privkey}, nil)
if e != nil {
	// signing error
}
// Admire your signed zone...

type ZoneData

type ZoneData struct {
	Name       string              // Domain name for this node
	RR         map[uint16][]RR     // Map of the RR type to the RR
	Signatures map[uint16][]*RRSIG // DNSSEC signatures for the RRs, stored under type covered
	NonAuth    bool                // Always false, except for NSsets that differ from z.Origin
	*sync.RWMutex
}

ZoneData holds all the RRs having their owner name equal to Name.

func NewZoneData

func NewZoneData(s string) *ZoneData

NewZoneData creates a new zone data element.

func (*ZoneData) Sign

func (node *ZoneData) Sign(next string, keys map[*DNSKEY]PrivateKey, keytags map[*DNSKEY]uint16, config *SignatureConfig) error

Sign signs a single ZoneData node. The zonedata itself is locked for writing, during the execution. It is important that the nodes' next record does not change. The caller must take care that the zone itself is also locked for writing. For a more complete description see zone.Sign. Note, because this method has no (direct) access to the zone's SOA record, the SOA's Minttl value should be set in *config.

func (*ZoneData) String

func (zd *ZoneData) String() string

String returns a string representation of a ZoneData. There is no String for the entire zone, because this will (most likely) take up a huge amount of memory. Basic use pattern for printing an entire zone:

// z contains the zone
z.Radix.NextDo(func(i interface{}) {
	fmt.Printf("%s", i.(*dns.ZoneData).String()) })

Directories

Path Synopsis
ex
chaos
Chaos is a small program that prints the version.bind and hostname.bind for each address of the nameserver given as argument.
Chaos is a small program that prints the version.bind and hostname.bind for each address of the nameserver given as argument.
check-soa
Go equivalent of the "DNS & BIND" book check-soa program.
Go equivalent of the "DNS & BIND" book check-soa program.
q
Q is a small utility which acts and behaves like 'dig' from BIND.
Q is a small utility which acts and behaves like 'dig' from BIND.
reflect
Reflect is a small name server which sends back the IP address of its client, the recursive resolver.
Reflect is a small name server which sends back the IP address of its client, the recursive resolver.

Jump to

Keyboard shortcuts

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