Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Package dnsmessage provides a mostly RFC 1035 compliant implementation of DNS message packing and unpacking. The package also supports messages with Extension Mechanisms for DNS (EDNS(0)) as defined in RFC 6891. This implementation is designed to minimize heap allocations and avoid unnecessary packing and unpacking as much as possible.
package dnsmessage

import (
	
)
Message formats
A Type is a type of DNS request and response.
type Type uint16

ResourceHeader.Type and Question.Type
Question.Type
	TypeWKS   Type = 11
	TypeHINFO Type = 13
	TypeMINFO Type = 14
	TypeAXFR  Type = 252
	TypeALL   Type = 255
)

var typeNames = map[Type]string{
	TypeA:     "TypeA",
	TypeNS:    "TypeNS",
	TypeCNAME: "TypeCNAME",
	TypeSOA:   "TypeSOA",
	TypePTR:   "TypePTR",
	TypeMX:    "TypeMX",
	TypeTXT:   "TypeTXT",
	TypeAAAA:  "TypeAAAA",
	TypeSRV:   "TypeSRV",
	TypeOPT:   "TypeOPT",
	TypeWKS:   "TypeWKS",
	TypeHINFO: "TypeHINFO",
	TypeMINFO: "TypeMINFO",
	TypeAXFR:  "TypeAXFR",
	TypeALL:   "TypeALL",
}
String implements fmt.Stringer.String.
func ( Type) () string {
	if ,  := typeNames[];  {
		return 
	}
	return printUint16(uint16())
}
GoString implements fmt.GoStringer.GoString.
func ( Type) () string {
	if ,  := typeNames[];  {
		return "dnsmessage." + 
	}
	return printUint16(uint16())
}
A Class is a type of network.
ResourceHeader.Class and Question.Class
Question.Class
	ClassANY Class = 255
)

var classNames = map[Class]string{
	ClassINET:   "ClassINET",
	ClassCSNET:  "ClassCSNET",
	ClassCHAOS:  "ClassCHAOS",
	ClassHESIOD: "ClassHESIOD",
	ClassANY:    "ClassANY",
}
String implements fmt.Stringer.String.
func ( Class) () string {
	if ,  := classNames[];  {
		return 
	}
	return printUint16(uint16())
}
GoString implements fmt.GoStringer.GoString.
func ( Class) () string {
	if ,  := classNames[];  {
		return "dnsmessage." + 
	}
	return printUint16(uint16())
}
An OpCode is a DNS operation code.
GoString implements fmt.GoStringer.GoString.
func ( OpCode) () string {
	return printUint16(uint16())
}
An RCode is a DNS response status code.
Message.Rcode
	RCodeSuccess        RCode = 0
	RCodeFormatError    RCode = 1
	RCodeServerFailure  RCode = 2
	RCodeNameError      RCode = 3
	RCodeNotImplemented RCode = 4
	RCodeRefused        RCode = 5
)

var rCodeNames = map[RCode]string{
	RCodeSuccess:        "RCodeSuccess",
	RCodeFormatError:    "RCodeFormatError",
	RCodeServerFailure:  "RCodeServerFailure",
	RCodeNameError:      "RCodeNameError",
	RCodeNotImplemented: "RCodeNotImplemented",
	RCodeRefused:        "RCodeRefused",
}
String implements fmt.Stringer.String.
func ( RCode) () string {
	if ,  := rCodeNames[];  {
		return 
	}
	return printUint16(uint16())
}
GoString implements fmt.GoStringer.GoString.
func ( RCode) () string {
	if ,  := rCodeNames[];  {
		return "dnsmessage." + 
	}
	return printUint16(uint16())
}

func ( uint8) string {
	 := byte()
	return string([]byte{
		/100 + '0',
		/10%10 + '0',
		%10 + '0',
	})
}

func ( []byte,  uint8) []byte {
	 := byte()
	if  >= 100 {
		 = append(, /100+'0')
	}
	if  >= 10 {
		 = append(, /10%10+'0')
	}
	return append(, %10+'0')
}

func ( []byte) string {
	if len() == 0 {
		return ""
	}
	 := make([]byte, 0, 5*len())
	 = printUint8Bytes(, uint8([0]))
	for ,  := range [1:] {
		 = append(, ',', ' ')
		 = printUint8Bytes(, uint8())
	}
	return string()
}

const hexDigits = "0123456789abcdef"

func ( []byte) string {
	 := make([]byte, 0, len())
	for  := 0;  < len(); ++ {
		 := []
		if  == '.' ||  == '-' ||  == ' ' ||
			'A' <=  &&  <= 'Z' ||
			'a' <=  &&  <= 'z' ||
			'0' <=  &&  <= '9' {
			 = append(, )
			continue
		}

		 :=  >> 4
		 := ( << 4) >> 4
		 = append(
			,
			'\\',
			'x',
			hexDigits[],
			hexDigits[],
		)
	}
	return string()
}

func ( uint16) string {
	return printUint32(uint32())
}

Max value is 4294967295.
	 := make([]byte, 10)
	for ,  := , uint32(1000000000);  > 0;  /= 10 {
		[0] = byte(/%10 + '0')
		if [0] == '0' && len() == len() && len() > 1 {
			 = [1:]
		}
		 = [1:]
		 %= 
	}
	return string()
}

func ( bool) string {
	if  {
		return "true"
	}
	return "false"
}

ErrNotStarted indicates that the prerequisite information isn't available yet because the previous records haven't been appropriately parsed, skipped or finished.
	ErrNotStarted = errors.New("parsing/packing of this type isn't available yet")
ErrSectionDone indicated that all records in the section have been parsed or finished.
	ErrSectionDone = errors.New("parsing/packing of this section has completed")

	errBaseLen            = errors.New("insufficient data for base length type")
	errCalcLen            = errors.New("insufficient data for calculated length type")
	errReserved           = errors.New("segment prefix is reserved")
	errTooManyPtr         = errors.New("too many pointers (>10)")
	errInvalidPtr         = errors.New("invalid pointer")
	errNilResouceBody     = errors.New("nil resource body")
	errResourceLen        = errors.New("insufficient data for resource body length")
	errSegTooLong         = errors.New("segment length too long")
	errZeroSegLen         = errors.New("zero length segment")
	errResTooLong         = errors.New("resource length too long")
	errTooManyQuestions   = errors.New("too many Questions to pack (>65535)")
	errTooManyAnswers     = errors.New("too many Answers to pack (>65535)")
	errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
	errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
	errNonCanonicalName   = errors.New("name is not in canonical format (it must end with a .)")
	errStringTooLong      = errors.New("character string exceeds maximum length (255)")
	errCompressedSRV      = errors.New("compressed name in SRV resource data")
)
Internal constants.
packStartingCap is the default initial buffer size allocated during packing. The starting capacity doesn't matter too much, but most DNS responses Will be <= 512 bytes as it is the limit for DNS over UDP.
uint16Len is the length (in bytes) of a uint16.
	uint16Len = 2
uint32Len is the length (in bytes) of a uint32.
	uint32Len = 4
headerLen is the length (in bytes) of a DNS header. A header is comprised of 6 uint16s and no padding.
s is the current level's error message.
err is the nested error.
nestedError implements error.Error.
func ( *nestedError) () string {
	return .s + ": " + .err.Error()
}
Header is a representation of a DNS message header.
type Header struct {
	ID                 uint16
	Response           bool
	OpCode             OpCode
	Authoritative      bool
	Truncated          bool
	RecursionDesired   bool
	RecursionAvailable bool
	RCode              RCode
}

func ( *Header) () ( uint16,  uint16) {
	 = .ID
	 = uint16(.OpCode)<<11 | uint16(.RCode)
	if .RecursionAvailable {
		 |= headerBitRA
	}
	if .RecursionDesired {
		 |= headerBitRD
	}
	if .Truncated {
		 |= headerBitTC
	}
	if .Authoritative {
		 |= headerBitAA
	}
	if .Response {
		 |= headerBitQR
	}
	return
}
GoString implements fmt.GoStringer.GoString.
func ( *Header) () string {
	return "dnsmessage.Header{" +
		"ID: " + printUint16(.ID) + ", " +
		"Response: " + printBool(.Response) + ", " +
		"OpCode: " + .OpCode.GoString() + ", " +
		"Authoritative: " + printBool(.Authoritative) + ", " +
		"Truncated: " + printBool(.Truncated) + ", " +
		"RecursionDesired: " + printBool(.RecursionDesired) + ", " +
		"RecursionAvailable: " + printBool(.RecursionAvailable) + ", " +
		"RCode: " + .RCode.GoString() + "}"
}
Message is a representation of a DNS message.
type Message struct {
	Header
	Questions   []Question
	Answers     []Resource
	Authorities []Resource
	Additionals []Resource
}

type section uint8

const (
	sectionNotStarted section = iota
	sectionHeader
	sectionQuestions
	sectionAnswers
	sectionAuthorities
	sectionAdditionals
	sectionDone

	headerBitQR = 1 << 15 // query/response (response=1)
	headerBitAA = 1 << 10 // authoritative
	headerBitTC = 1 << 9  // truncated
	headerBitRD = 1 << 8  // recursion desired
	headerBitRA = 1 << 7  // recursion available
)

var sectionNames = map[section]string{
	sectionHeader:      "header",
	sectionQuestions:   "Question",
	sectionAnswers:     "Answer",
	sectionAuthorities: "Authority",
	sectionAdditionals: "Additional",
}
header is the wire format for a DNS message header.
type header struct {
	id          uint16
	bits        uint16
	questions   uint16
	answers     uint16
	authorities uint16
	additionals uint16
}

func ( *header) ( section) uint16 {
	switch  {
	case sectionQuestions:
		return .questions
	case sectionAnswers:
		return .answers
	case sectionAuthorities:
		return .authorities
	case sectionAdditionals:
		return .additionals
	}
	return 0
}
pack appends the wire format of the header to msg.
func ( *header) ( []byte) []byte {
	 = packUint16(, .id)
	 = packUint16(, .bits)
	 = packUint16(, .questions)
	 = packUint16(, .answers)
	 = packUint16(, .authorities)
	return packUint16(, .additionals)
}

func ( *header) ( []byte,  int) (int, error) {
	 := 
	var  error
	if .id, ,  = unpackUint16(, );  != nil {
		return , &nestedError{"id", }
	}
	if .bits, ,  = unpackUint16(, );  != nil {
		return , &nestedError{"bits", }
	}
	if .questions, ,  = unpackUint16(, );  != nil {
		return , &nestedError{"questions", }
	}
	if .answers, ,  = unpackUint16(, );  != nil {
		return , &nestedError{"answers", }
	}
	if .authorities, ,  = unpackUint16(, );  != nil {
		return , &nestedError{"authorities", }
	}
	if .additionals, ,  = unpackUint16(, );  != nil {
		return , &nestedError{"additionals", }
	}
	return , nil
}

func ( *header) () Header {
	return Header{
		ID:                 .id,
		Response:           (.bits & headerBitQR) != 0,
		OpCode:             OpCode(.bits>>11) & 0xF,
		Authoritative:      (.bits & headerBitAA) != 0,
		Truncated:          (.bits & headerBitTC) != 0,
		RecursionDesired:   (.bits & headerBitRD) != 0,
		RecursionAvailable: (.bits & headerBitRA) != 0,
		RCode:              RCode(.bits & 0xF),
	}
}
A Resource is a DNS resource record.
type Resource struct {
	Header ResourceHeader
	Body   ResourceBody
}

func ( *Resource) () string {
	return "dnsmessage.Resource{" +
		"Header: " + .Header.GoString() +
		", Body: &" + .Body.GoString() +
		"}"
}
A ResourceBody is a DNS resource record minus the header.
pack packs a Resource except for its header.
	pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error)
realType returns the actual type of the Resource. This is used to fill in the header Type field.
	realType() Type
GoString implements fmt.GoStringer.GoString.
	GoString() string
}
pack appends the wire format of the Resource to msg.
func ( *Resource) ( []byte,  map[string]int,  int) ([]byte, error) {
	if .Body == nil {
		return , errNilResouceBody
	}
	 := 
	.Header.Type = .Body.realType()
	, ,  := .Header.pack(, , )
	if  != nil {
		return , &nestedError{"ResourceHeader", }
	}
	 := len()
	,  = .Body.pack(, , )
	if  != nil {
		return , &nestedError{"content", }
	}
	if  := .Header.fixLen(, , );  != nil {
		return , 
	}
	return , nil
}
A Parser allows incrementally parsing a DNS message. When parsing is started, the Header is parsed. Next, each Question can be either parsed or skipped. Alternatively, all Questions can be skipped at once. When all Questions have been parsed, attempting to parse Questions will return (nil, nil) and attempting to skip Questions will return (true, nil). After all Questions have been either parsed or skipped, all Answers, Authorities and Additionals can be either parsed or skipped in the same way, and each type of Resource must be fully parsed or skipped before proceeding to the next type of Resource. Note that there is no requirement to fully skip or parse the message.
Start parses the header and enables the parsing of Questions.
func ( *Parser) ( []byte) (Header, error) {
	if .msg != nil {
		* = Parser{}
	}
	.msg = 
	var  error
	if .off,  = .header.unpack(, 0);  != nil {
		return Header{}, &nestedError{"unpacking header", }
	}
	.section = sectionQuestions
	return .header.header(), nil
}

func ( *Parser) ( section) error {
	if .section <  {
		return ErrNotStarted
	}
	if .section >  {
		return ErrSectionDone
	}
	.resHeaderValid = false
	if .index == int(.header.count()) {
		.index = 0
		.section++
		return ErrSectionDone
	}
	return nil
}

func ( *Parser) ( section) (Resource, error) {
	var  Resource
	var  error
	.Header,  = .resourceHeader()
	if  != nil {
		return , 
	}
	.resHeaderValid = false
	.Body, .off,  = unpackResourceBody(.msg, .off, .Header)
	if  != nil {
		return Resource{}, &nestedError{"unpacking " + sectionNames[], }
	}
	.index++
	return , nil
}

func ( *Parser) ( section) (ResourceHeader, error) {
	if .resHeaderValid {
		return .resHeader, nil
	}
	if  := .checkAdvance();  != nil {
		return ResourceHeader{}, 
	}
	var  ResourceHeader
	,  := .unpack(.msg, .off)
	if  != nil {
		return ResourceHeader{}, 
	}
	.resHeaderValid = true
	.resHeader = 
	.off = 
	return , nil
}

func ( *Parser) ( section) error {
	if .resHeaderValid {
		 := .off + int(.resHeader.Length)
		if  > len(.msg) {
			return errResourceLen
		}
		.off = 
		.resHeaderValid = false
		.index++
		return nil
	}
	if  := .checkAdvance();  != nil {
		return 
	}
	var  error
	.off,  = skipResource(.msg, .off)
	if  != nil {
		return &nestedError{"skipping: " + sectionNames[], }
	}
	.index++
	return nil
}
Question parses a single Question.
func ( *Parser) () (Question, error) {
	if  := .checkAdvance(sectionQuestions);  != nil {
		return Question{}, 
	}
	var  Name
	,  := .unpack(.msg, .off)
	if  != nil {
		return Question{}, &nestedError{"unpacking Question.Name", }
	}
	, ,  := unpackType(.msg, )
	if  != nil {
		return Question{}, &nestedError{"unpacking Question.Type", }
	}
	, ,  := unpackClass(.msg, )
	if  != nil {
		return Question{}, &nestedError{"unpacking Question.Class", }
	}
	.off = 
	.index++
	return Question{, , }, nil
}
AllQuestions parses all Questions.
Multiple questions are valid according to the spec, but servers don't actually support them. There will be at most one question here. Do not pre-allocate based on info in p.header, since the data is untrusted.
	 := []Question{}
	for {
		,  := .Question()
		if  == ErrSectionDone {
			return , nil
		}
		if  != nil {
			return nil, 
		}
		 = append(, )
	}
}
SkipQuestion skips a single Question.
func ( *Parser) () error {
	if  := .checkAdvance(sectionQuestions);  != nil {
		return 
	}
	,  := skipName(.msg, .off)
	if  != nil {
		return &nestedError{"skipping Question Name", }
	}
	if ,  = skipType(.msg, );  != nil {
		return &nestedError{"skipping Question Type", }
	}
	if ,  = skipClass(.msg, );  != nil {
		return &nestedError{"skipping Question Class", }
	}
	.off = 
	.index++
	return nil
}
SkipAllQuestions skips all Questions.
func ( *Parser) () error {
	for {
		if  := .SkipQuestion();  == ErrSectionDone {
			return nil
		} else if  != nil {
			return 
		}
	}
}
AnswerHeader parses a single Answer ResourceHeader.
Answer parses a single Answer Resource.
func ( *Parser) () (Resource, error) {
	return .resource(sectionAnswers)
}
AllAnswers parses all Answer Resources.
The most common query is for A/AAAA, which usually returns a handful of IPs. Pre-allocate up to a certain limit, since p.header is untrusted data.
	 := int(.header.answers)
	if  > 20 {
		 = 20
	}
	 := make([]Resource, 0, )
	for {
		,  := .Answer()
		if  == ErrSectionDone {
			return , nil
		}
		if  != nil {
			return nil, 
		}
		 = append(, )
	}
}
SkipAnswer skips a single Answer Resource.
SkipAllAnswers skips all Answer Resources.
func ( *Parser) () error {
	for {
		if  := .SkipAnswer();  == ErrSectionDone {
			return nil
		} else if  != nil {
			return 
		}
	}
}
AuthorityHeader parses a single Authority ResourceHeader.
Authority parses a single Authority Resource.
AllAuthorities parses all Authority Resources.
Authorities contains SOA in case of NXDOMAIN and friends, otherwise it is empty. Pre-allocate up to a certain limit, since p.header is untrusted data.
	 := int(.header.authorities)
	if  > 10 {
		 = 10
	}
	 := make([]Resource, 0, )
	for {
		,  := .Authority()
		if  == ErrSectionDone {
			return , nil
		}
		if  != nil {
			return nil, 
		}
		 = append(, )
	}
}
SkipAuthority skips a single Authority Resource.
SkipAllAuthorities skips all Authority Resources.
func ( *Parser) () error {
	for {
		if  := .SkipAuthority();  == ErrSectionDone {
			return nil
		} else if  != nil {
			return 
		}
	}
}
AdditionalHeader parses a single Additional ResourceHeader.
Additional parses a single Additional Resource.
AllAdditionals parses all Additional Resources.
Additionals usually contain OPT, and sometimes A/AAAA glue records. Pre-allocate up to a certain limit, since p.header is untrusted data.
	 := int(.header.additionals)
	if  > 10 {
		 = 10
	}
	 := make([]Resource, 0, )
	for {
		,  := .Additional()
		if  == ErrSectionDone {
			return , nil
		}
		if  != nil {
			return nil, 
		}
		 = append(, )
	}
}
SkipAdditional skips a single Additional Resource.
SkipAllAdditionals skips all Additional Resources.
func ( *Parser) () error {
	for {
		if  := .SkipAdditional();  == ErrSectionDone {
			return nil
		} else if  != nil {
			return 
		}
	}
}
CNAMEResource parses a single CNAMEResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (CNAMEResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeCNAME {
		return CNAMEResource{}, ErrNotStarted
	}
	,  := unpackCNAMEResource(.msg, .off)
	if  != nil {
		return CNAMEResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
MXResource parses a single MXResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (MXResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeMX {
		return MXResource{}, ErrNotStarted
	}
	,  := unpackMXResource(.msg, .off)
	if  != nil {
		return MXResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
NSResource parses a single NSResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (NSResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeNS {
		return NSResource{}, ErrNotStarted
	}
	,  := unpackNSResource(.msg, .off)
	if  != nil {
		return NSResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
PTRResource parses a single PTRResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (PTRResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypePTR {
		return PTRResource{}, ErrNotStarted
	}
	,  := unpackPTRResource(.msg, .off)
	if  != nil {
		return PTRResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
SOAResource parses a single SOAResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (SOAResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeSOA {
		return SOAResource{}, ErrNotStarted
	}
	,  := unpackSOAResource(.msg, .off)
	if  != nil {
		return SOAResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
TXTResource parses a single TXTResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (TXTResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeTXT {
		return TXTResource{}, ErrNotStarted
	}
	,  := unpackTXTResource(.msg, .off, .resHeader.Length)
	if  != nil {
		return TXTResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
SRVResource parses a single SRVResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (SRVResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeSRV {
		return SRVResource{}, ErrNotStarted
	}
	,  := unpackSRVResource(.msg, .off)
	if  != nil {
		return SRVResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
AResource parses a single AResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (AResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeA {
		return AResource{}, ErrNotStarted
	}
	,  := unpackAResource(.msg, .off)
	if  != nil {
		return AResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
AAAAResource parses a single AAAAResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (AAAAResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeAAAA {
		return AAAAResource{}, ErrNotStarted
	}
	,  := unpackAAAAResource(.msg, .off)
	if  != nil {
		return AAAAResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
OPTResource parses a single OPTResource. One of the XXXHeader methods must have been called before calling this method.
func ( *Parser) () (OPTResource, error) {
	if !.resHeaderValid || .resHeader.Type != TypeOPT {
		return OPTResource{}, ErrNotStarted
	}
	,  := unpackOPTResource(.msg, .off, .resHeader.Length)
	if  != nil {
		return OPTResource{}, 
	}
	.off += int(.resHeader.Length)
	.resHeaderValid = false
	.index++
	return , nil
}
Unpack parses a full Message.
func ( *Message) ( []byte) error {
	var  Parser
	var  error
	if .Header,  = .Start();  != nil {
		return 
	}
	if .Questions,  = .AllQuestions();  != nil {
		return 
	}
	if .Answers,  = .AllAnswers();  != nil {
		return 
	}
	if .Authorities,  = .AllAuthorities();  != nil {
		return 
	}
	if .Additionals,  = .AllAdditionals();  != nil {
		return 
	}
	return nil
}
Pack packs a full Message.
func ( *Message) () ([]byte, error) {
	return .AppendPack(make([]byte, 0, packStartingCap))
}
AppendPack is like Pack but appends the full Message to b and returns the extended buffer.
Validate the lengths. It is very unlikely that anyone will try to pack more than 65535 of any particular type, but it is possible and we should fail gracefully.
	if len(.Questions) > int(^uint16(0)) {
		return nil, errTooManyQuestions
	}
	if len(.Answers) > int(^uint16(0)) {
		return nil, errTooManyAnswers
	}
	if len(.Authorities) > int(^uint16(0)) {
		return nil, errTooManyAuthorities
	}
	if len(.Additionals) > int(^uint16(0)) {
		return nil, errTooManyAdditionals
	}

	var  header
	.id, .bits = .Header.pack()

	.questions = uint16(len(.Questions))
	.answers = uint16(len(.Answers))
	.authorities = uint16(len(.Authorities))
	.additionals = uint16(len(.Additionals))

	 := len()
	 := .pack()
RFC 1035 allows (but does not require) compression for packing. RFC 1035 requires unpacking implementations to support compression, so unconditionally enabling it is fine. DNS lookups are typically done over UDP, and RFC 1035 states that UDP DNS messages can be a maximum of 512 bytes long. Without compression, many DNS response messages are over this limit, so enabling compression will help ensure compliance.
	 := map[string]int{}

	for  := range .Questions {
		var  error
		if ,  = .Questions[].pack(, , );  != nil {
			return nil, &nestedError{"packing Question", }
		}
	}
	for  := range .Answers {
		var  error
		if ,  = .Answers[].pack(, , );  != nil {
			return nil, &nestedError{"packing Answer", }
		}
	}
	for  := range .Authorities {
		var  error
		if ,  = .Authorities[].pack(, , );  != nil {
			return nil, &nestedError{"packing Authority", }
		}
	}
	for  := range .Additionals {
		var  error
		if ,  = .Additionals[].pack(, , );  != nil {
			return nil, &nestedError{"packing Additional", }
		}
	}

	return , nil
}
GoString implements fmt.GoStringer.GoString.
func ( *Message) () string {
	 := "dnsmessage.Message{Header: " + .Header.GoString() + ", " +
		"Questions: []dnsmessage.Question{"
	if len(.Questions) > 0 {
		 += .Questions[0].GoString()
		for ,  := range .Questions[1:] {
			 += ", " + .GoString()
		}
	}
	 += "}, Answers: []dnsmessage.Resource{"
	if len(.Answers) > 0 {
		 += .Answers[0].GoString()
		for ,  := range .Answers[1:] {
			 += ", " + .GoString()
		}
	}
	 += "}, Authorities: []dnsmessage.Resource{"
	if len(.Authorities) > 0 {
		 += .Authorities[0].GoString()
		for ,  := range .Authorities[1:] {
			 += ", " + .GoString()
		}
	}
	 += "}, Additionals: []dnsmessage.Resource{"
	if len(.Additionals) > 0 {
		 += .Additionals[0].GoString()
		for ,  := range .Additionals[1:] {
			 += ", " + .GoString()
		}
	}
	return  + "}}"
}
A Builder allows incrementally packing a DNS message. Example usage: buf := make([]byte, 2, 514) b := NewBuilder(buf, Header{...}) b.EnableCompression() // Optionally start a section and add things to that section. // Repeat adding sections as necessary. buf, err := b.Finish() // If err is nil, buf[2:] will contain the built bytes.
msg is the storage for the message being built.
	msg []byte
section keeps track of the current section being built.
header keeps track of what should go in the header when Finish is called.
start is the starting index of the bytes allocated in msg for header.
compression is a mapping from name suffixes to their starting index in msg.
NewBuilder creates a new builder with compression disabled. Note: Most users will want to immediately enable compression with the EnableCompression method. See that method's comment for why you may or may not want to enable compression. The DNS message is appended to the provided initial buffer buf (which may be nil) as it is built. The final message is returned by the (*Builder).Finish method, which may return the same underlying array if there was sufficient capacity in the slice.
func ( []byte,  Header) Builder {
	if  == nil {
		 = make([]byte, 0, packStartingCap)
	}
	 := Builder{msg: , start: len()}
	.header.id, .header.bits = .pack()
	var  [headerLen]byte
	.msg = append(.msg, [:]...)
	.section = sectionHeader
	return 
}
EnableCompression enables compression in the Builder. Leaving compression disabled avoids compression related allocations, but can result in larger message sizes. Be careful with this mode as it can cause messages to exceed the UDP size limit. According to RFC 1035, section 4.1.4, the use of compression is optional, but all implementations must accept both compressed and uncompressed DNS messages. Compression should be enabled before any sections are added for best results.
func ( *Builder) () {
	.compression = map[string]int{}
}

func ( *Builder) ( section) error {
	if .section <= sectionNotStarted {
		return ErrNotStarted
	}
	if .section >  {
		return ErrSectionDone
	}
	return nil
}
StartQuestions prepares the builder for packing Questions.
func ( *Builder) () error {
	if  := .startCheck(sectionQuestions);  != nil {
		return 
	}
	.section = sectionQuestions
	return nil
}
StartAnswers prepares the builder for packing Answers.
func ( *Builder) () error {
	if  := .startCheck(sectionAnswers);  != nil {
		return 
	}
	.section = sectionAnswers
	return nil
}
StartAuthorities prepares the builder for packing Authorities.
func ( *Builder) () error {
	if  := .startCheck(sectionAuthorities);  != nil {
		return 
	}
	.section = sectionAuthorities
	return nil
}
StartAdditionals prepares the builder for packing Additionals.
func ( *Builder) () error {
	if  := .startCheck(sectionAdditionals);  != nil {
		return 
	}
	.section = sectionAdditionals
	return nil
}

func ( *Builder) () error {
	var  *uint16
	var  error
	switch .section {
	case sectionQuestions:
		 = &.header.questions
		 = errTooManyQuestions
	case sectionAnswers:
		 = &.header.answers
		 = errTooManyAnswers
	case sectionAuthorities:
		 = &.header.authorities
		 = errTooManyAuthorities
	case sectionAdditionals:
		 = &.header.additionals
		 = errTooManyAdditionals
	}
	if * == ^uint16(0) {
		return 
	}
	*++
	return nil
}
Question adds a single Question.
func ( *Builder) ( Question) error {
	if .section < sectionQuestions {
		return ErrNotStarted
	}
	if .section > sectionQuestions {
		return ErrSectionDone
	}
	,  := .pack(.msg, .compression, .start)
	if  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}

func ( *Builder) () error {
	if .section < sectionAnswers {
		return ErrNotStarted
	}
	if .section > sectionAdditionals {
		return ErrSectionDone
	}
	return nil
}
CNAMEResource adds a single CNAMEResource.
func ( *Builder) ( ResourceHeader,  CNAMEResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"CNAMEResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
MXResource adds a single MXResource.
func ( *Builder) ( ResourceHeader,  MXResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"MXResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
NSResource adds a single NSResource.
func ( *Builder) ( ResourceHeader,  NSResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"NSResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
PTRResource adds a single PTRResource.
func ( *Builder) ( ResourceHeader,  PTRResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"PTRResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
SOAResource adds a single SOAResource.
func ( *Builder) ( ResourceHeader,  SOAResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"SOAResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
TXTResource adds a single TXTResource.
func ( *Builder) ( ResourceHeader,  TXTResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"TXTResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
SRVResource adds a single SRVResource.
func ( *Builder) ( ResourceHeader,  SRVResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"SRVResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
AResource adds a single AResource.
func ( *Builder) ( ResourceHeader,  AResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"AResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
AAAAResource adds a single AAAAResource.
func ( *Builder) ( ResourceHeader,  AAAAResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"AAAAResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
OPTResource adds a single OPTResource.
func ( *Builder) ( ResourceHeader,  OPTResource) error {
	if  := .checkResourceSection();  != nil {
		return 
	}
	.Type = .realType()
	, ,  := .pack(.msg, .compression, .start)
	if  != nil {
		return &nestedError{"ResourceHeader", }
	}
	 := len()
	if ,  = .pack(, .compression, .start);  != nil {
		return &nestedError{"OPTResource body", }
	}
	if  := .fixLen(, , );  != nil {
		return 
	}
	if  := .incrementSectionCount();  != nil {
		return 
	}
	.msg = 
	return nil
}
Finish ends message building and generates a binary message.
func ( *Builder) () ([]byte, error) {
	if .section < sectionHeader {
		return nil, ErrNotStarted
	}
Space for the header was allocated in NewBuilder.
	.header.pack(.msg[.start:.start])
	return .msg, nil
}
A ResourceHeader is the header of a DNS resource record. There are many types of DNS resource records, but they all share the same header.
Name is the domain name for which this resource record pertains.
Type is the type of DNS resource record. This field will be set automatically during packing.
Class is the class of network to which this DNS resource record pertains.
TTL is the length of time (measured in seconds) which this resource record is valid for (time to live). All Resources in a set should have the same TTL (RFC 2181 Section 5.2).
Length is the length of data in the resource record after the header. This field will be set automatically during packing.
GoString implements fmt.GoStringer.GoString.
func ( *ResourceHeader) () string {
	return "dnsmessage.ResourceHeader{" +
		"Name: " + .Name.GoString() + ", " +
		"Type: " + .Type.GoString() + ", " +
		"Class: " + .Class.GoString() + ", " +
		"TTL: " + printUint32(.TTL) + ", " +
		"Length: " + printUint16(.Length) + "}"
}
pack appends the wire format of the ResourceHeader to oldMsg. lenOff is the offset in msg where the Length field was packed.
func ( *ResourceHeader) ( []byte,  map[string]int,  int) ( []byte,  int,  error) {
	 = 
	if ,  = .Name.pack(, , );  != nil {
		return , 0, &nestedError{"Name", }
	}
	 = packType(, .Type)
	 = packClass(, .Class)
	 = packUint32(, .TTL)
	 = len()
	 = packUint16(, .Length)
	return , , nil
}

func ( *ResourceHeader) ( []byte,  int) (int, error) {
	 := 
	var  error
	if ,  = .Name.unpack(, );  != nil {
		return , &nestedError{"Name", }
	}
	if .Type, ,  = unpackType(, );  != nil {
		return , &nestedError{"Type", }
	}
	if .Class, ,  = unpackClass(, );  != nil {
		return , &nestedError{"Class", }
	}
	if .TTL, ,  = unpackUint32(, );  != nil {
		return , &nestedError{"TTL", }
	}
	if .Length, ,  = unpackUint16(, );  != nil {
		return , &nestedError{"Length", }
	}
	return , nil
}
fixLen updates a packed ResourceHeader to include the length of the ResourceBody. lenOff is the offset of the ResourceHeader.Length field in msg. preLen is the length that msg was before the ResourceBody was packed.
func ( *ResourceHeader) ( []byte,  int,  int) error {
	 := len() - 
	if  > int(^uint16(0)) {
		return errResTooLong
	}
Fill in the length now that we know how long the content is.
	packUint16([:], uint16())
	.Length = uint16()

	return nil
}
EDNS(0) wire constants.
const (
	edns0Version = 0

	edns0DNSSECOK     = 0x00008000
	ednsVersionMask   = 0x00ff0000
	edns0DNSSECOKMask = 0x00ff8000
)
SetEDNS0 configures h for EDNS(0). The provided extRCode must be an extedned RCode.
func ( *ResourceHeader) ( int,  RCode,  bool) error {
	.Name = Name{Data: [nameLen]byte{'.'}, Length: 1} // RFC 6891 section 6.1.2
	.Type = TypeOPT
	.Class = Class()
	.TTL = uint32() >> 4 << 24
	if  {
		.TTL |= edns0DNSSECOK
	}
	return nil
}
DNSSECAllowed reports whether the DNSSEC OK bit is set.
func ( *ResourceHeader) () bool {
	return .TTL&edns0DNSSECOKMask == edns0DNSSECOK // RFC 6891 section 6.1.3
}
ExtendedRCode returns an extended RCode. The provided rcode must be the RCode in DNS message header.
func ( *ResourceHeader) ( RCode) RCode {
	if .TTL&ednsVersionMask == edns0Version { // RFC 6891 section 6.1.3
		return RCode(.TTL>>24<<4) | 
	}
	return 
}

func ( []byte,  int) (int, error) {
	,  := skipName(, )
	if  != nil {
		return , &nestedError{"Name", }
	}
	if ,  = skipType(, );  != nil {
		return , &nestedError{"Type", }
	}
	if ,  = skipClass(, );  != nil {
		return , &nestedError{"Class", }
	}
	if ,  = skipUint32(, );  != nil {
		return , &nestedError{"TTL", }
	}
	, ,  := unpackUint16(, )
	if  != nil {
		return , &nestedError{"Length", }
	}
	if  += int();  > len() {
		return , errResourceLen
	}
	return , nil
}
packUint16 appends the wire format of field to msg.
func ( []byte,  uint16) []byte {
	return append(, byte(>>8), byte())
}

func ( []byte,  int) (uint16, int, error) {
	if +uint16Len > len() {
		return 0, , errBaseLen
	}
	return uint16([])<<8 | uint16([+1]),  + uint16Len, nil
}

func ( []byte,  int) (int, error) {
	if +uint16Len > len() {
		return , errBaseLen
	}
	return  + uint16Len, nil
}
packType appends the wire format of field to msg.
func ( []byte,  Type) []byte {
	return packUint16(, uint16())
}

func ( []byte,  int) (Type, int, error) {
	, ,  := unpackUint16(, )
	return Type(), , 
}

func ( []byte,  int) (int, error) {
	return skipUint16(, )
}
packClass appends the wire format of field to msg.
func ( []byte,  Class) []byte {
	return packUint16(, uint16())
}

func ( []byte,  int) (Class, int, error) {
	, ,  := unpackUint16(, )
	return Class(), , 
}

func ( []byte,  int) (int, error) {
	return skipUint16(, )
}
packUint32 appends the wire format of field to msg.
func ( []byte,  uint32) []byte {
	return append(
		,
		byte(>>24),
		byte(>>16),
		byte(>>8),
		byte(),
	)
}

func ( []byte,  int) (uint32, int, error) {
	if +uint32Len > len() {
		return 0, , errBaseLen
	}
	 := uint32([])<<24 | uint32([+1])<<16 | uint32([+2])<<8 | uint32([+3])
	return ,  + uint32Len, nil
}

func ( []byte,  int) (int, error) {
	if +uint32Len > len() {
		return , errBaseLen
	}
	return  + uint32Len, nil
}
packText appends the wire format of field to msg.
func ( []byte,  string) ([]byte, error) {
	 := len()
	if  > 255 {
		return nil, errStringTooLong
	}
	 = append(, byte())
	 = append(, ...)

	return , nil
}

func ( []byte,  int) (string, int, error) {
	if  >= len() {
		return "", , errBaseLen
	}
	 :=  + 1
	 :=  + int([])
	if  > len() {
		return "", , errCalcLen
	}
	return string([:]), , nil
}
packBytes appends the wire format of field to msg.
func ( []byte,  []byte) []byte {
	return append(, ...)
}

func ( []byte,  int,  []byte) (int, error) {
	 :=  + len()
	if  > len() {
		return , errBaseLen
	}
	copy(, [:])
	return , nil
}

const nameLen = 255
A Name is a non-encoded domain name. It is used instead of strings to avoid allocations.
type Name struct {
	Data   [nameLen]byte
	Length uint8
}
NewName creates a new Name from a string.
func ( string) (Name, error) {
	if len([]byte()) > nameLen {
		return Name{}, errCalcLen
	}
	 := Name{Length: uint8(len())}
	copy(.Data[:], []byte())
	return , nil
}
MustNewName creates a new Name from a string and panics on error.
func ( string) Name {
	,  := NewName()
	if  != nil {
		panic("creating name: " + .Error())
	}
	return 
}
String implements fmt.Stringer.String.
func ( Name) () string {
	return string(.Data[:.Length])
}
GoString implements fmt.GoStringer.GoString.
func ( *Name) () string {
	return `dnsmessage.MustNewName("` + printString(.Data[:.Length]) + `")`
}
pack appends the wire format of the Name to msg. Domain names are a sequence of counted strings split at the dots. They end with a zero-length string. Compression can be used to reuse domain suffixes. The compression map will be updated with new domain suffixes. If compression is nil, compression will not be used.
func ( *Name) ( []byte,  map[string]int,  int) ([]byte, error) {
	 := 
Add a trailing dot to canonicalize name.
	if .Length == 0 || .Data[.Length-1] != '.' {
		return , errNonCanonicalName
	}
Allow root domain.
	if .Data[0] == '.' && .Length == 1 {
		return append(, 0), nil
	}
Emit sequence of counted strings, chopping at dots.
Check for the end of the segment.
The two most significant bits have special meaning. It isn't allowed for segments to be long enough to need them.
			if - >= 1<<6 {
				return , errSegTooLong
			}
Segments must have a non-zero length.
			if - == 0 {
				return , errZeroSegLen
			}

			 = append(, byte(-))

			for  := ;  < ; ++ {
				 = append(, .Data[])
			}

			 =  + 1
			continue
		}
We can only compress domain suffixes starting with a new segment. A pointer is two bytes with the two most significant bits set to 1 to indicate that it is a pointer.
		if ( == 0 || .Data[-1] == '.') &&  != nil {
Hit. Emit a pointer instead of the rest of the domain.
				return append(, byte(>>8|0xC0), byte()), nil
			}
Miss. Add the suffix to the compression table if the offset can be stored in the available 14 bytes.
			if len() <= int(^uint16(0)>>2) {
				[string(.Data[:])] = len() - 
			}
		}
	}
	return append(, 0), nil
}
unpack unpacks a domain name.
func ( *Name) ( []byte,  int) (int, error) {
	return .unpackCompressed(, , true /* allowCompression */)
}

currOff is the current working offset.
	 := 
newOff is the offset where the next record will start. Pointers lead to data that belongs to other names and thus doesn't count towards to the usage of this name.
	 := 
ptr is the number of pointers followed.
	var  int
Name is a slice representation of the name data.
	 := .Data[:0]

:
	for {
		if  >= len() {
			return , errBaseLen
		}
		 := int([])
		++
		switch  & 0xC0 {
		case 0x00: // String segment
A zero length signals the end of the name.
				break 
			}
			 :=  + 
			if  > len() {
				return , errCalcLen
			}
			 = append(, [:]...)
			 = append(, '.')
			 = 
		case 0xC0: // Pointer
			if ! {
				return , errCompressedSRV
			}
			if  >= len() {
				return , errInvalidPtr
			}
			 := []
			++
			if  == 0 {
				 = 
Don't follow too many pointers, maybe there's a loop.
			if ++;  > 10 {
				return , errTooManyPtr
			}
			 = (^0xC0)<<8 | int()
Prefixes 0x80 and 0x40 are reserved.
			return , errReserved
		}
	}
	if len() == 0 {
		 = append(, '.')
	}
	if len() > len(.Data) {
		return , errCalcLen
	}
	.Length = uint8(len())
	if  == 0 {
		 = 
	}
	return , nil
}

newOff is the offset where the next record will start. Pointers lead to data that belongs to other names and thus doesn't count towards to the usage of this name.
	 := 

:
	for {
		if  >= len() {
			return , errBaseLen
		}
		 := int([])
		++
		switch  & 0xC0 {
		case 0x00:
A zero length signals the end of the name.
				break 
literal string
			 += 
			if  > len() {
				return , errCalcLen
			}
Pointer to somewhere else in msg.
Pointers are two bytes.
			++
Don't follow the pointer as the data here has ended.
			break 
Prefixes 0x80 and 0x40 are reserved.
			return , errReserved
		}
	}

	return , nil
}
A Question is a DNS query.
type Question struct {
	Name  Name
	Type  Type
	Class Class
}
pack appends the wire format of the Question to msg.
func ( *Question) ( []byte,  map[string]int,  int) ([]byte, error) {
	,  := .Name.pack(, , )
	if  != nil {
		return , &nestedError{"Name", }
	}
	 = packType(, .Type)
	return packClass(, .Class), nil
}
GoString implements fmt.GoStringer.GoString.
func ( *Question) () string {
	return "dnsmessage.Question{" +
		"Name: " + .Name.GoString() + ", " +
		"Type: " + .Type.GoString() + ", " +
		"Class: " + .Class.GoString() + "}"
}

func ( []byte,  int,  ResourceHeader) (ResourceBody, int, error) {
	var (
		    ResourceBody
		  error
		 string
	)
	switch .Type {
	case TypeA:
		var  AResource
		,  = unpackAResource(, )
		 = &
		 = "A"
	case TypeNS:
		var  NSResource
		,  = unpackNSResource(, )
		 = &
		 = "NS"
	case TypeCNAME:
		var  CNAMEResource
		,  = unpackCNAMEResource(, )
		 = &
		 = "CNAME"
	case TypeSOA:
		var  SOAResource
		,  = unpackSOAResource(, )
		 = &
		 = "SOA"
	case TypePTR:
		var  PTRResource
		,  = unpackPTRResource(, )
		 = &
		 = "PTR"
	case TypeMX:
		var  MXResource
		,  = unpackMXResource(, )
		 = &
		 = "MX"
	case TypeTXT:
		var  TXTResource
		,  = unpackTXTResource(, , .Length)
		 = &
		 = "TXT"
	case TypeAAAA:
		var  AAAAResource
		,  = unpackAAAAResource(, )
		 = &
		 = "AAAA"
	case TypeSRV:
		var  SRVResource
		,  = unpackSRVResource(, )
		 = &
		 = "SRV"
	case TypeOPT:
		var  OPTResource
		,  = unpackOPTResource(, , .Length)
		 = &
		 = "OPT"
	}
	if  != nil {
		return nil, , &nestedError{ + " record", }
	}
	if  == nil {
		return nil, , errors.New("invalid resource type: " + .Type.String())
	}
	return ,  + int(.Length), nil
}
A CNAMEResource is a CNAME Resource record.
type CNAMEResource struct {
	CNAME Name
}

func ( *CNAMEResource) () Type {
	return TypeCNAME
}
pack appends the wire format of the CNAMEResource to msg.
func ( *CNAMEResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	return .CNAME.pack(, , )
}
GoString implements fmt.GoStringer.GoString.
func ( *CNAMEResource) () string {
	return "dnsmessage.CNAMEResource{CNAME: " + .CNAME.GoString() + "}"
}

func ( []byte,  int) (CNAMEResource, error) {
	var  Name
	if ,  := .unpack(, );  != nil {
		return CNAMEResource{}, 
	}
	return CNAMEResource{}, nil
}
An MXResource is an MX Resource record.
type MXResource struct {
	Pref uint16
	MX   Name
}

func ( *MXResource) () Type {
	return TypeMX
}
pack appends the wire format of the MXResource to msg.
func ( *MXResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	 := 
	 = packUint16(, .Pref)
	,  := .MX.pack(, , )
	if  != nil {
		return , &nestedError{"MXResource.MX", }
	}
	return , nil
}
GoString implements fmt.GoStringer.GoString.
func ( *MXResource) () string {
	return "dnsmessage.MXResource{" +
		"Pref: " + printUint16(.Pref) + ", " +
		"MX: " + .MX.GoString() + "}"
}

func ( []byte,  int) (MXResource, error) {
	, ,  := unpackUint16(, )
	if  != nil {
		return MXResource{}, &nestedError{"Pref", }
	}
	var  Name
	if ,  := .unpack(, );  != nil {
		return MXResource{}, &nestedError{"MX", }
	}
	return MXResource{, }, nil
}
An NSResource is an NS Resource record.
type NSResource struct {
	NS Name
}

func ( *NSResource) () Type {
	return TypeNS
}
pack appends the wire format of the NSResource to msg.
func ( *NSResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	return .NS.pack(, , )
}
GoString implements fmt.GoStringer.GoString.
func ( *NSResource) () string {
	return "dnsmessage.NSResource{NS: " + .NS.GoString() + "}"
}

func ( []byte,  int) (NSResource, error) {
	var  Name
	if ,  := .unpack(, );  != nil {
		return NSResource{}, 
	}
	return NSResource{}, nil
}
A PTRResource is a PTR Resource record.
type PTRResource struct {
	PTR Name
}

func ( *PTRResource) () Type {
	return TypePTR
}
pack appends the wire format of the PTRResource to msg.
func ( *PTRResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	return .PTR.pack(, , )
}
GoString implements fmt.GoStringer.GoString.
func ( *PTRResource) () string {
	return "dnsmessage.PTRResource{PTR: " + .PTR.GoString() + "}"
}

func ( []byte,  int) (PTRResource, error) {
	var  Name
	if ,  := .unpack(, );  != nil {
		return PTRResource{}, 
	}
	return PTRResource{}, nil
}
An SOAResource is an SOA Resource record.
MinTTL the is the default TTL of Resources records which did not contain a TTL value and the TTL of negative responses. (RFC 2308 Section 4)
	MinTTL uint32
}

func ( *SOAResource) () Type {
	return TypeSOA
}
pack appends the wire format of the SOAResource to msg.
func ( *SOAResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	 := 
	,  := .NS.pack(, , )
	if  != nil {
		return , &nestedError{"SOAResource.NS", }
	}
	,  = .MBox.pack(, , )
	if  != nil {
		return , &nestedError{"SOAResource.MBox", }
	}
	 = packUint32(, .Serial)
	 = packUint32(, .Refresh)
	 = packUint32(, .Retry)
	 = packUint32(, .Expire)
	return packUint32(, .MinTTL), nil
}
GoString implements fmt.GoStringer.GoString.
func ( *SOAResource) () string {
	return "dnsmessage.SOAResource{" +
		"NS: " + .NS.GoString() + ", " +
		"MBox: " + .MBox.GoString() + ", " +
		"Serial: " + printUint32(.Serial) + ", " +
		"Refresh: " + printUint32(.Refresh) + ", " +
		"Retry: " + printUint32(.Retry) + ", " +
		"Expire: " + printUint32(.Expire) + ", " +
		"MinTTL: " + printUint32(.MinTTL) + "}"
}

func ( []byte,  int) (SOAResource, error) {
	var  Name
	,  := .unpack(, )
	if  != nil {
		return SOAResource{}, &nestedError{"NS", }
	}
	var  Name
	if ,  = .unpack(, );  != nil {
		return SOAResource{}, &nestedError{"MBox", }
	}
	, ,  := unpackUint32(, )
	if  != nil {
		return SOAResource{}, &nestedError{"Serial", }
	}
	, ,  := unpackUint32(, )
	if  != nil {
		return SOAResource{}, &nestedError{"Refresh", }
	}
	, ,  := unpackUint32(, )
	if  != nil {
		return SOAResource{}, &nestedError{"Retry", }
	}
	, ,  := unpackUint32(, )
	if  != nil {
		return SOAResource{}, &nestedError{"Expire", }
	}
	, ,  := unpackUint32(, )
	if  != nil {
		return SOAResource{}, &nestedError{"MinTTL", }
	}
	return SOAResource{, , , , , , }, nil
}
A TXTResource is a TXT Resource record.
type TXTResource struct {
	TXT []string
}

func ( *TXTResource) () Type {
	return TypeTXT
}
pack appends the wire format of the TXTResource to msg.
func ( *TXTResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	 := 
	for ,  := range .TXT {
		var  error
		,  = packText(, )
		if  != nil {
			return , 
		}
	}
	return , nil
}
GoString implements fmt.GoStringer.GoString.
func ( *TXTResource) () string {
	 := "dnsmessage.TXTResource{TXT: []string{"
	if len(.TXT) == 0 {
		return  + "}}"
	}
	 += `"` + printString([]byte(.TXT[0]))
	for ,  := range .TXT[1:] {
		 += `", "` + printString([]byte())
	}
	return  + `"}}`
}

func ( []byte,  int,  uint16) (TXTResource, error) {
	 := make([]string, 0, 1)
	for  := uint16(0);  < ; {
		var  string
		var  error
		if , ,  = unpackText(, );  != nil {
			return TXTResource{}, &nestedError{"text", }
Check if we got too many bytes.
		if - < uint16(len())+1 {
			return TXTResource{}, errCalcLen
		}
		 += uint16(len()) + 1
		 = append(, )
	}
	return TXTResource{}, nil
}
An SRVResource is an SRV Resource record.
type SRVResource struct {
	Priority uint16
	Weight   uint16
	Port     uint16
	Target   Name // Not compressed as per RFC 2782.
}

func ( *SRVResource) () Type {
	return TypeSRV
}
pack appends the wire format of the SRVResource to msg.
func ( *SRVResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	 := 
	 = packUint16(, .Priority)
	 = packUint16(, .Weight)
	 = packUint16(, .Port)
	,  := .Target.pack(, nil, )
	if  != nil {
		return , &nestedError{"SRVResource.Target", }
	}
	return , nil
}
GoString implements fmt.GoStringer.GoString.
func ( *SRVResource) () string {
	return "dnsmessage.SRVResource{" +
		"Priority: " + printUint16(.Priority) + ", " +
		"Weight: " + printUint16(.Weight) + ", " +
		"Port: " + printUint16(.Port) + ", " +
		"Target: " + .Target.GoString() + "}"
}

func ( []byte,  int) (SRVResource, error) {
	, ,  := unpackUint16(, )
	if  != nil {
		return SRVResource{}, &nestedError{"Priority", }
	}
	, ,  := unpackUint16(, )
	if  != nil {
		return SRVResource{}, &nestedError{"Weight", }
	}
	, ,  := unpackUint16(, )
	if  != nil {
		return SRVResource{}, &nestedError{"Port", }
	}
	var  Name
	if ,  := .unpackCompressed(, , false /* allowCompression */);  != nil {
		return SRVResource{}, &nestedError{"Target", }
	}
	return SRVResource{, , , }, nil
}
An AResource is an A Resource record.
type AResource struct {
	A [4]byte
}

func ( *AResource) () Type {
	return TypeA
}
pack appends the wire format of the AResource to msg.
func ( *AResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	return packBytes(, .A[:]), nil
}
GoString implements fmt.GoStringer.GoString.
func ( *AResource) () string {
	return "dnsmessage.AResource{" +
		"A: [4]byte{" + printByteSlice(.A[:]) + "}}"
}

func ( []byte,  int) (AResource, error) {
	var  [4]byte
	if ,  := unpackBytes(, , [:]);  != nil {
		return AResource{}, 
	}
	return AResource{}, nil
}
An AAAAResource is an AAAA Resource record.
type AAAAResource struct {
	AAAA [16]byte
}

func ( *AAAAResource) () Type {
	return TypeAAAA
}
GoString implements fmt.GoStringer.GoString.
func ( *AAAAResource) () string {
	return "dnsmessage.AAAAResource{" +
		"AAAA: [16]byte{" + printByteSlice(.AAAA[:]) + "}}"
}
pack appends the wire format of the AAAAResource to msg.
func ( *AAAAResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	return packBytes(, .AAAA[:]), nil
}

func ( []byte,  int) (AAAAResource, error) {
	var  [16]byte
	if ,  := unpackBytes(, , [:]);  != nil {
		return AAAAResource{}, 
	}
	return AAAAResource{}, nil
}
An OPTResource is an OPT pseudo Resource record. The pseudo resource record is part of the extension mechanisms for DNS as defined in RFC 6891.
type OPTResource struct {
	Options []Option
}
An Option represents a DNS message option within OPTResource. The message option is part of the extension mechanisms for DNS as defined in RFC 6891.
type Option struct {
	Code uint16 // option code
	Data []byte
}
GoString implements fmt.GoStringer.GoString.
func ( *Option) () string {
	return "dnsmessage.Option{" +
		"Code: " + printUint16(.Code) + ", " +
		"Data: []byte{" + printByteSlice(.Data) + "}}"
}

func ( *OPTResource) () Type {
	return TypeOPT
}

func ( *OPTResource) ( []byte,  map[string]int,  int) ([]byte, error) {
	for ,  := range .Options {
		 = packUint16(, .Code)
		 := uint16(len(.Data))
		 = packUint16(, )
		 = packBytes(, .Data)
	}
	return , nil
}
GoString implements fmt.GoStringer.GoString.
func ( *OPTResource) () string {
	 := "dnsmessage.OPTResource{Options: []dnsmessage.Option{"
	if len(.Options) == 0 {
		return  + "}}"
	}
	 += .Options[0].GoString()
	for ,  := range .Options[1:] {
		 += ", " + .GoString()
	}
	return  + "}}"
}

func ( []byte,  int,  uint16) (OPTResource, error) {
	var  []Option
	for  := ;  < +int(); {
		var  error
		var  Option
		.Code, ,  = unpackUint16(, )
		if  != nil {
			return OPTResource{}, &nestedError{"Code", }
		}
		var  uint16
		, ,  = unpackUint16(, )
		if  != nil {
			return OPTResource{}, &nestedError{"Data", }
		}
		.Data = make([]byte, )
		if copy(.Data, [:]) != int() {
			return OPTResource{}, &nestedError{"Data", errCalcLen}
		}
		 += int()
		 = append(, )
	}
	return OPTResource{}, nil