1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package dnsmessage provides a mostly RFC 1035 compliant implementation of
6// DNS message packing and unpacking.
7//
8// The package also supports messages with Extension Mechanisms for DNS
9// (EDNS(0)) as defined in RFC 6891.
10//
11// This implementation is designed to minimize heap allocations and avoid
12// unnecessary packing and unpacking as much as possible.
13package dnsmessage
14
15import (
16	"errors"
17	"fmt"
18)
19
20// Message formats
21
22// A Type is a type of DNS request and response.
23type Type uint16
24
25const (
26	// ResourceHeader.Type and Question.Type
27	TypeA     Type = 1
28	TypeNS    Type = 2
29	TypeCNAME Type = 5
30	TypeSOA   Type = 6
31	TypePTR   Type = 12
32	TypeMX    Type = 15
33	TypeTXT   Type = 16
34	TypeAAAA  Type = 28
35	TypeSRV   Type = 33
36	TypeOPT   Type = 41
37
38	// Question.Type
39	TypeWKS   Type = 11
40	TypeHINFO Type = 13
41	TypeMINFO Type = 14
42	TypeAXFR  Type = 252
43	TypeALL   Type = 255
44)
45
46var typeNames = map[Type]string{
47	TypeA:     "TypeA",
48	TypeNS:    "TypeNS",
49	TypeCNAME: "TypeCNAME",
50	TypeSOA:   "TypeSOA",
51	TypePTR:   "TypePTR",
52	TypeMX:    "TypeMX",
53	TypeTXT:   "TypeTXT",
54	TypeAAAA:  "TypeAAAA",
55	TypeSRV:   "TypeSRV",
56	TypeOPT:   "TypeOPT",
57	TypeWKS:   "TypeWKS",
58	TypeHINFO: "TypeHINFO",
59	TypeMINFO: "TypeMINFO",
60	TypeAXFR:  "TypeAXFR",
61	TypeALL:   "TypeALL",
62}
63
64// String implements fmt.Stringer.String.
65func (t Type) String() string {
66	if n, ok := typeNames[t]; ok {
67		return n
68	}
69	return printUint16(uint16(t))
70}
71
72// GoString implements fmt.GoStringer.GoString.
73func (t Type) GoString() string {
74	if n, ok := typeNames[t]; ok {
75		return "dnsmessage." + n
76	}
77	return printUint16(uint16(t))
78}
79
80// A Class is a type of network.
81type Class uint16
82
83const (
84	// ResourceHeader.Class and Question.Class
85	ClassINET   Class = 1
86	ClassCSNET  Class = 2
87	ClassCHAOS  Class = 3
88	ClassHESIOD Class = 4
89
90	// Question.Class
91	ClassANY Class = 255
92)
93
94var classNames = map[Class]string{
95	ClassINET:   "ClassINET",
96	ClassCSNET:  "ClassCSNET",
97	ClassCHAOS:  "ClassCHAOS",
98	ClassHESIOD: "ClassHESIOD",
99	ClassANY:    "ClassANY",
100}
101
102// String implements fmt.Stringer.String.
103func (c Class) String() string {
104	if n, ok := classNames[c]; ok {
105		return n
106	}
107	return printUint16(uint16(c))
108}
109
110// GoString implements fmt.GoStringer.GoString.
111func (c Class) GoString() string {
112	if n, ok := classNames[c]; ok {
113		return "dnsmessage." + n
114	}
115	return printUint16(uint16(c))
116}
117
118// An OpCode is a DNS operation code.
119type OpCode uint16
120
121// GoString implements fmt.GoStringer.GoString.
122func (o OpCode) GoString() string {
123	return printUint16(uint16(o))
124}
125
126// An RCode is a DNS response status code.
127type RCode uint16
128
129const (
130	// Message.Rcode
131	RCodeSuccess        RCode = 0
132	RCodeFormatError    RCode = 1
133	RCodeServerFailure  RCode = 2
134	RCodeNameError      RCode = 3
135	RCodeNotImplemented RCode = 4
136	RCodeRefused        RCode = 5
137)
138
139var rCodeNames = map[RCode]string{
140	RCodeSuccess:        "RCodeSuccess",
141	RCodeFormatError:    "RCodeFormatError",
142	RCodeServerFailure:  "RCodeServerFailure",
143	RCodeNameError:      "RCodeNameError",
144	RCodeNotImplemented: "RCodeNotImplemented",
145	RCodeRefused:        "RCodeRefused",
146}
147
148// String implements fmt.Stringer.String.
149func (r RCode) String() string {
150	if n, ok := rCodeNames[r]; ok {
151		return n
152	}
153	return printUint16(uint16(r))
154}
155
156// GoString implements fmt.GoStringer.GoString.
157func (r RCode) GoString() string {
158	if n, ok := rCodeNames[r]; ok {
159		return "dnsmessage." + n
160	}
161	return printUint16(uint16(r))
162}
163
164func printPaddedUint8(i uint8) string {
165	b := byte(i)
166	return string([]byte{
167		b/100 + '0',
168		b/10%10 + '0',
169		b%10 + '0',
170	})
171}
172
173func printUint8Bytes(buf []byte, i uint8) []byte {
174	b := byte(i)
175	if i >= 100 {
176		buf = append(buf, b/100+'0')
177	}
178	if i >= 10 {
179		buf = append(buf, b/10%10+'0')
180	}
181	return append(buf, b%10+'0')
182}
183
184func printByteSlice(b []byte) string {
185	if len(b) == 0 {
186		return ""
187	}
188	buf := make([]byte, 0, 5*len(b))
189	buf = printUint8Bytes(buf, uint8(b[0]))
190	for _, n := range b[1:] {
191		buf = append(buf, ',', ' ')
192		buf = printUint8Bytes(buf, uint8(n))
193	}
194	return string(buf)
195}
196
197const hexDigits = "0123456789abcdef"
198
199func printString(str []byte) string {
200	buf := make([]byte, 0, len(str))
201	for i := 0; i < len(str); i++ {
202		c := str[i]
203		if c == '.' || c == '-' || c == ' ' ||
204			'A' <= c && c <= 'Z' ||
205			'a' <= c && c <= 'z' ||
206			'0' <= c && c <= '9' {
207			buf = append(buf, c)
208			continue
209		}
210
211		upper := c >> 4
212		lower := (c << 4) >> 4
213		buf = append(
214			buf,
215			'\\',
216			'x',
217			hexDigits[upper],
218			hexDigits[lower],
219		)
220	}
221	return string(buf)
222}
223
224func printUint16(i uint16) string {
225	return printUint32(uint32(i))
226}
227
228func printUint32(i uint32) string {
229	// Max value is 4294967295.
230	buf := make([]byte, 10)
231	for b, d := buf, uint32(1000000000); d > 0; d /= 10 {
232		b[0] = byte(i/d%10 + '0')
233		if b[0] == '0' && len(b) == len(buf) && len(buf) > 1 {
234			buf = buf[1:]
235		}
236		b = b[1:]
237		i %= d
238	}
239	return string(buf)
240}
241
242func printBool(b bool) string {
243	if b {
244		return "true"
245	}
246	return "false"
247}
248
249var (
250	// ErrNotStarted indicates that the prerequisite information isn't
251	// available yet because the previous records haven't been appropriately
252	// parsed, skipped or finished.
253	ErrNotStarted = errors.New("parsing/packing of this type isn't available yet")
254
255	// ErrSectionDone indicated that all records in the section have been
256	// parsed or finished.
257	ErrSectionDone = errors.New("parsing/packing of this section has completed")
258
259	errBaseLen            = errors.New("insufficient data for base length type")
260	errCalcLen            = errors.New("insufficient data for calculated length type")
261	errReserved           = errors.New("segment prefix is reserved")
262	errTooManyPtr         = errors.New("too many pointers (>10)")
263	errInvalidPtr         = errors.New("invalid pointer")
264	errNilResouceBody     = errors.New("nil resource body")
265	errResourceLen        = errors.New("insufficient data for resource body length")
266	errSegTooLong         = errors.New("segment length too long")
267	errZeroSegLen         = errors.New("zero length segment")
268	errResTooLong         = errors.New("resource length too long")
269	errTooManyQuestions   = errors.New("too many Questions to pack (>65535)")
270	errTooManyAnswers     = errors.New("too many Answers to pack (>65535)")
271	errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
272	errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
273	errNonCanonicalName   = errors.New("name is not in canonical format (it must end with a .)")
274	errStringTooLong      = errors.New("character string exceeds maximum length (255)")
275	errCompressedSRV      = errors.New("compressed name in SRV resource data")
276)
277
278// Internal constants.
279const (
280	// packStartingCap is the default initial buffer size allocated during
281	// packing.
282	//
283	// The starting capacity doesn't matter too much, but most DNS responses
284	// Will be <= 512 bytes as it is the limit for DNS over UDP.
285	packStartingCap = 512
286
287	// uint16Len is the length (in bytes) of a uint16.
288	uint16Len = 2
289
290	// uint32Len is the length (in bytes) of a uint32.
291	uint32Len = 4
292
293	// headerLen is the length (in bytes) of a DNS header.
294	//
295	// A header is comprised of 6 uint16s and no padding.
296	headerLen = 6 * uint16Len
297)
298
299type nestedError struct {
300	// s is the current level's error message.
301	s string
302
303	// err is the nested error.
304	err error
305}
306
307// nestedError implements error.Error.
308func (e *nestedError) Error() string {
309	return e.s + ": " + e.err.Error()
310}
311
312// Header is a representation of a DNS message header.
313type Header struct {
314	ID                 uint16
315	Response           bool
316	OpCode             OpCode
317	Authoritative      bool
318	Truncated          bool
319	RecursionDesired   bool
320	RecursionAvailable bool
321	RCode              RCode
322}
323
324func (m *Header) pack() (id uint16, bits uint16) {
325	id = m.ID
326	bits = uint16(m.OpCode)<<11 | uint16(m.RCode)
327	if m.RecursionAvailable {
328		bits |= headerBitRA
329	}
330	if m.RecursionDesired {
331		bits |= headerBitRD
332	}
333	if m.Truncated {
334		bits |= headerBitTC
335	}
336	if m.Authoritative {
337		bits |= headerBitAA
338	}
339	if m.Response {
340		bits |= headerBitQR
341	}
342	return
343}
344
345// GoString implements fmt.GoStringer.GoString.
346func (m *Header) GoString() string {
347	return "dnsmessage.Header{" +
348		"ID: " + printUint16(m.ID) + ", " +
349		"Response: " + printBool(m.Response) + ", " +
350		"OpCode: " + m.OpCode.GoString() + ", " +
351		"Authoritative: " + printBool(m.Authoritative) + ", " +
352		"Truncated: " + printBool(m.Truncated) + ", " +
353		"RecursionDesired: " + printBool(m.RecursionDesired) + ", " +
354		"RecursionAvailable: " + printBool(m.RecursionAvailable) + ", " +
355		"RCode: " + m.RCode.GoString() + "}"
356}
357
358// Message is a representation of a DNS message.
359type Message struct {
360	Header
361	Questions   []Question
362	Answers     []Resource
363	Authorities []Resource
364	Additionals []Resource
365}
366
367type section uint8
368
369const (
370	sectionNotStarted section = iota
371	sectionHeader
372	sectionQuestions
373	sectionAnswers
374	sectionAuthorities
375	sectionAdditionals
376	sectionDone
377
378	headerBitQR = 1 << 15 // query/response (response=1)
379	headerBitAA = 1 << 10 // authoritative
380	headerBitTC = 1 << 9  // truncated
381	headerBitRD = 1 << 8  // recursion desired
382	headerBitRA = 1 << 7  // recursion available
383)
384
385var sectionNames = map[section]string{
386	sectionHeader:      "header",
387	sectionQuestions:   "Question",
388	sectionAnswers:     "Answer",
389	sectionAuthorities: "Authority",
390	sectionAdditionals: "Additional",
391}
392
393// header is the wire format for a DNS message header.
394type header struct {
395	id          uint16
396	bits        uint16
397	questions   uint16
398	answers     uint16
399	authorities uint16
400	additionals uint16
401}
402
403func (h *header) count(sec section) uint16 {
404	switch sec {
405	case sectionQuestions:
406		return h.questions
407	case sectionAnswers:
408		return h.answers
409	case sectionAuthorities:
410		return h.authorities
411	case sectionAdditionals:
412		return h.additionals
413	}
414	return 0
415}
416
417// pack appends the wire format of the header to msg.
418func (h *header) pack(msg []byte) []byte {
419	msg = packUint16(msg, h.id)
420	msg = packUint16(msg, h.bits)
421	msg = packUint16(msg, h.questions)
422	msg = packUint16(msg, h.answers)
423	msg = packUint16(msg, h.authorities)
424	return packUint16(msg, h.additionals)
425}
426
427func (h *header) unpack(msg []byte, off int) (int, error) {
428	newOff := off
429	var err error
430	if h.id, newOff, err = unpackUint16(msg, newOff); err != nil {
431		return off, &nestedError{"id", err}
432	}
433	if h.bits, newOff, err = unpackUint16(msg, newOff); err != nil {
434		return off, &nestedError{"bits", err}
435	}
436	if h.questions, newOff, err = unpackUint16(msg, newOff); err != nil {
437		return off, &nestedError{"questions", err}
438	}
439	if h.answers, newOff, err = unpackUint16(msg, newOff); err != nil {
440		return off, &nestedError{"answers", err}
441	}
442	if h.authorities, newOff, err = unpackUint16(msg, newOff); err != nil {
443		return off, &nestedError{"authorities", err}
444	}
445	if h.additionals, newOff, err = unpackUint16(msg, newOff); err != nil {
446		return off, &nestedError{"additionals", err}
447	}
448	return newOff, nil
449}
450
451func (h *header) header() Header {
452	return Header{
453		ID:                 h.id,
454		Response:           (h.bits & headerBitQR) != 0,
455		OpCode:             OpCode(h.bits>>11) & 0xF,
456		Authoritative:      (h.bits & headerBitAA) != 0,
457		Truncated:          (h.bits & headerBitTC) != 0,
458		RecursionDesired:   (h.bits & headerBitRD) != 0,
459		RecursionAvailable: (h.bits & headerBitRA) != 0,
460		RCode:              RCode(h.bits & 0xF),
461	}
462}
463
464// A Resource is a DNS resource record.
465type Resource struct {
466	Header ResourceHeader
467	Body   ResourceBody
468}
469
470func (r *Resource) GoString() string {
471	return "dnsmessage.Resource{" +
472		"Header: " + r.Header.GoString() +
473		", Body: &" + r.Body.GoString() +
474		"}"
475}
476
477// A ResourceBody is a DNS resource record minus the header.
478type ResourceBody interface {
479	// pack packs a Resource except for its header.
480	pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error)
481
482	// realType returns the actual type of the Resource. This is used to
483	// fill in the header Type field.
484	realType() Type
485
486	// GoString implements fmt.GoStringer.GoString.
487	GoString() string
488}
489
490// pack appends the wire format of the Resource to msg.
491func (r *Resource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
492	if r.Body == nil {
493		return msg, errNilResouceBody
494	}
495	oldMsg := msg
496	r.Header.Type = r.Body.realType()
497	msg, lenOff, err := r.Header.pack(msg, compression, compressionOff)
498	if err != nil {
499		return msg, &nestedError{"ResourceHeader", err}
500	}
501	preLen := len(msg)
502	msg, err = r.Body.pack(msg, compression, compressionOff)
503	if err != nil {
504		return msg, &nestedError{"content", err}
505	}
506	if err := r.Header.fixLen(msg, lenOff, preLen); err != nil {
507		return oldMsg, err
508	}
509	return msg, nil
510}
511
512// A Parser allows incrementally parsing a DNS message.
513//
514// When parsing is started, the Header is parsed. Next, each Question can be
515// either parsed or skipped. Alternatively, all Questions can be skipped at
516// once. When all Questions have been parsed, attempting to parse Questions
517// will return (nil, nil) and attempting to skip Questions will return
518// (true, nil). After all Questions have been either parsed or skipped, all
519// Answers, Authorities and Additionals can be either parsed or skipped in the
520// same way, and each type of Resource must be fully parsed or skipped before
521// proceeding to the next type of Resource.
522//
523// Note that there is no requirement to fully skip or parse the message.
524type Parser struct {
525	msg    []byte
526	header header
527
528	section        section
529	off            int
530	index          int
531	resHeaderValid bool
532	resHeader      ResourceHeader
533}
534
535// Start parses the header and enables the parsing of Questions.
536func (p *Parser) Start(msg []byte) (Header, error) {
537	if p.msg != nil {
538		*p = Parser{}
539	}
540	p.msg = msg
541	var err error
542	if p.off, err = p.header.unpack(msg, 0); err != nil {
543		return Header{}, &nestedError{"unpacking header", err}
544	}
545	p.section = sectionQuestions
546	return p.header.header(), nil
547}
548
549func (p *Parser) checkAdvance(sec section) error {
550	if p.section < sec {
551		return ErrNotStarted
552	}
553	if p.section > sec {
554		return ErrSectionDone
555	}
556	p.resHeaderValid = false
557	if p.index == int(p.header.count(sec)) {
558		p.index = 0
559		p.section++
560		return ErrSectionDone
561	}
562	return nil
563}
564
565func (p *Parser) resource(sec section) (Resource, error) {
566	var r Resource
567	var err error
568	r.Header, err = p.resourceHeader(sec)
569	if err != nil {
570		return r, err
571	}
572	p.resHeaderValid = false
573	r.Body, p.off, err = unpackResourceBody(p.msg, p.off, r.Header)
574	if err != nil {
575		return Resource{}, &nestedError{"unpacking " + sectionNames[sec], err}
576	}
577	p.index++
578	return r, nil
579}
580
581func (p *Parser) resourceHeader(sec section) (ResourceHeader, error) {
582	if p.resHeaderValid {
583		return p.resHeader, nil
584	}
585	if err := p.checkAdvance(sec); err != nil {
586		return ResourceHeader{}, err
587	}
588	var hdr ResourceHeader
589	off, err := hdr.unpack(p.msg, p.off)
590	if err != nil {
591		return ResourceHeader{}, err
592	}
593	p.resHeaderValid = true
594	p.resHeader = hdr
595	p.off = off
596	return hdr, nil
597}
598
599func (p *Parser) skipResource(sec section) error {
600	if p.resHeaderValid {
601		newOff := p.off + int(p.resHeader.Length)
602		if newOff > len(p.msg) {
603			return errResourceLen
604		}
605		p.off = newOff
606		p.resHeaderValid = false
607		p.index++
608		return nil
609	}
610	if err := p.checkAdvance(sec); err != nil {
611		return err
612	}
613	var err error
614	p.off, err = skipResource(p.msg, p.off)
615	if err != nil {
616		return &nestedError{"skipping: " + sectionNames[sec], err}
617	}
618	p.index++
619	return nil
620}
621
622// Question parses a single Question.
623func (p *Parser) Question() (Question, error) {
624	if err := p.checkAdvance(sectionQuestions); err != nil {
625		return Question{}, err
626	}
627	var name Name
628	off, err := name.unpack(p.msg, p.off)
629	if err != nil {
630		return Question{}, &nestedError{"unpacking Question.Name", err}
631	}
632	typ, off, err := unpackType(p.msg, off)
633	if err != nil {
634		return Question{}, &nestedError{"unpacking Question.Type", err}
635	}
636	class, off, err := unpackClass(p.msg, off)
637	if err != nil {
638		return Question{}, &nestedError{"unpacking Question.Class", err}
639	}
640	p.off = off
641	p.index++
642	return Question{name, typ, class}, nil
643}
644
645// AllQuestions parses all Questions.
646func (p *Parser) AllQuestions() ([]Question, error) {
647	// Multiple questions are valid according to the spec,
648	// but servers don't actually support them. There will
649	// be at most one question here.
650	//
651	// Do not pre-allocate based on info in p.header, since
652	// the data is untrusted.
653	qs := []Question{}
654	for {
655		q, err := p.Question()
656		if err == ErrSectionDone {
657			return qs, nil
658		}
659		if err != nil {
660			return nil, err
661		}
662		qs = append(qs, q)
663	}
664}
665
666// SkipQuestion skips a single Question.
667func (p *Parser) SkipQuestion() error {
668	if err := p.checkAdvance(sectionQuestions); err != nil {
669		return err
670	}
671	off, err := skipName(p.msg, p.off)
672	if err != nil {
673		return &nestedError{"skipping Question Name", err}
674	}
675	if off, err = skipType(p.msg, off); err != nil {
676		return &nestedError{"skipping Question Type", err}
677	}
678	if off, err = skipClass(p.msg, off); err != nil {
679		return &nestedError{"skipping Question Class", err}
680	}
681	p.off = off
682	p.index++
683	return nil
684}
685
686// SkipAllQuestions skips all Questions.
687func (p *Parser) SkipAllQuestions() error {
688	for {
689		if err := p.SkipQuestion(); err == ErrSectionDone {
690			return nil
691		} else if err != nil {
692			return err
693		}
694	}
695}
696
697// AnswerHeader parses a single Answer ResourceHeader.
698func (p *Parser) AnswerHeader() (ResourceHeader, error) {
699	return p.resourceHeader(sectionAnswers)
700}
701
702// Answer parses a single Answer Resource.
703func (p *Parser) Answer() (Resource, error) {
704	return p.resource(sectionAnswers)
705}
706
707// AllAnswers parses all Answer Resources.
708func (p *Parser) AllAnswers() ([]Resource, error) {
709	// The most common query is for A/AAAA, which usually returns
710	// a handful of IPs.
711	//
712	// Pre-allocate up to a certain limit, since p.header is
713	// untrusted data.
714	n := int(p.header.answers)
715	if n > 20 {
716		n = 20
717	}
718	as := make([]Resource, 0, n)
719	for {
720		a, err := p.Answer()
721		if err == ErrSectionDone {
722			return as, nil
723		}
724		if err != nil {
725			return nil, err
726		}
727		as = append(as, a)
728	}
729}
730
731// SkipAnswer skips a single Answer Resource.
732func (p *Parser) SkipAnswer() error {
733	return p.skipResource(sectionAnswers)
734}
735
736// SkipAllAnswers skips all Answer Resources.
737func (p *Parser) SkipAllAnswers() error {
738	for {
739		if err := p.SkipAnswer(); err == ErrSectionDone {
740			return nil
741		} else if err != nil {
742			return err
743		}
744	}
745}
746
747// AuthorityHeader parses a single Authority ResourceHeader.
748func (p *Parser) AuthorityHeader() (ResourceHeader, error) {
749	return p.resourceHeader(sectionAuthorities)
750}
751
752// Authority parses a single Authority Resource.
753func (p *Parser) Authority() (Resource, error) {
754	return p.resource(sectionAuthorities)
755}
756
757// AllAuthorities parses all Authority Resources.
758func (p *Parser) AllAuthorities() ([]Resource, error) {
759	// Authorities contains SOA in case of NXDOMAIN and friends,
760	// otherwise it is empty.
761	//
762	// Pre-allocate up to a certain limit, since p.header is
763	// untrusted data.
764	n := int(p.header.authorities)
765	if n > 10 {
766		n = 10
767	}
768	as := make([]Resource, 0, n)
769	for {
770		a, err := p.Authority()
771		if err == ErrSectionDone {
772			return as, nil
773		}
774		if err != nil {
775			return nil, err
776		}
777		as = append(as, a)
778	}
779}
780
781// SkipAuthority skips a single Authority Resource.
782func (p *Parser) SkipAuthority() error {
783	return p.skipResource(sectionAuthorities)
784}
785
786// SkipAllAuthorities skips all Authority Resources.
787func (p *Parser) SkipAllAuthorities() error {
788	for {
789		if err := p.SkipAuthority(); err == ErrSectionDone {
790			return nil
791		} else if err != nil {
792			return err
793		}
794	}
795}
796
797// AdditionalHeader parses a single Additional ResourceHeader.
798func (p *Parser) AdditionalHeader() (ResourceHeader, error) {
799	return p.resourceHeader(sectionAdditionals)
800}
801
802// Additional parses a single Additional Resource.
803func (p *Parser) Additional() (Resource, error) {
804	return p.resource(sectionAdditionals)
805}
806
807// AllAdditionals parses all Additional Resources.
808func (p *Parser) AllAdditionals() ([]Resource, error) {
809	// Additionals usually contain OPT, and sometimes A/AAAA
810	// glue records.
811	//
812	// Pre-allocate up to a certain limit, since p.header is
813	// untrusted data.
814	n := int(p.header.additionals)
815	if n > 10 {
816		n = 10
817	}
818	as := make([]Resource, 0, n)
819	for {
820		a, err := p.Additional()
821		if err == ErrSectionDone {
822			return as, nil
823		}
824		if err != nil {
825			return nil, err
826		}
827		as = append(as, a)
828	}
829}
830
831// SkipAdditional skips a single Additional Resource.
832func (p *Parser) SkipAdditional() error {
833	return p.skipResource(sectionAdditionals)
834}
835
836// SkipAllAdditionals skips all Additional Resources.
837func (p *Parser) SkipAllAdditionals() error {
838	for {
839		if err := p.SkipAdditional(); err == ErrSectionDone {
840			return nil
841		} else if err != nil {
842			return err
843		}
844	}
845}
846
847// CNAMEResource parses a single CNAMEResource.
848//
849// One of the XXXHeader methods must have been called before calling this
850// method.
851func (p *Parser) CNAMEResource() (CNAMEResource, error) {
852	if !p.resHeaderValid || p.resHeader.Type != TypeCNAME {
853		return CNAMEResource{}, ErrNotStarted
854	}
855	r, err := unpackCNAMEResource(p.msg, p.off)
856	if err != nil {
857		return CNAMEResource{}, err
858	}
859	p.off += int(p.resHeader.Length)
860	p.resHeaderValid = false
861	p.index++
862	return r, nil
863}
864
865// MXResource parses a single MXResource.
866//
867// One of the XXXHeader methods must have been called before calling this
868// method.
869func (p *Parser) MXResource() (MXResource, error) {
870	if !p.resHeaderValid || p.resHeader.Type != TypeMX {
871		return MXResource{}, ErrNotStarted
872	}
873	r, err := unpackMXResource(p.msg, p.off)
874	if err != nil {
875		return MXResource{}, err
876	}
877	p.off += int(p.resHeader.Length)
878	p.resHeaderValid = false
879	p.index++
880	return r, nil
881}
882
883// NSResource parses a single NSResource.
884//
885// One of the XXXHeader methods must have been called before calling this
886// method.
887func (p *Parser) NSResource() (NSResource, error) {
888	if !p.resHeaderValid || p.resHeader.Type != TypeNS {
889		return NSResource{}, ErrNotStarted
890	}
891	r, err := unpackNSResource(p.msg, p.off)
892	if err != nil {
893		return NSResource{}, err
894	}
895	p.off += int(p.resHeader.Length)
896	p.resHeaderValid = false
897	p.index++
898	return r, nil
899}
900
901// PTRResource parses a single PTRResource.
902//
903// One of the XXXHeader methods must have been called before calling this
904// method.
905func (p *Parser) PTRResource() (PTRResource, error) {
906	if !p.resHeaderValid || p.resHeader.Type != TypePTR {
907		return PTRResource{}, ErrNotStarted
908	}
909	r, err := unpackPTRResource(p.msg, p.off)
910	if err != nil {
911		return PTRResource{}, err
912	}
913	p.off += int(p.resHeader.Length)
914	p.resHeaderValid = false
915	p.index++
916	return r, nil
917}
918
919// SOAResource parses a single SOAResource.
920//
921// One of the XXXHeader methods must have been called before calling this
922// method.
923func (p *Parser) SOAResource() (SOAResource, error) {
924	if !p.resHeaderValid || p.resHeader.Type != TypeSOA {
925		return SOAResource{}, ErrNotStarted
926	}
927	r, err := unpackSOAResource(p.msg, p.off)
928	if err != nil {
929		return SOAResource{}, err
930	}
931	p.off += int(p.resHeader.Length)
932	p.resHeaderValid = false
933	p.index++
934	return r, nil
935}
936
937// TXTResource parses a single TXTResource.
938//
939// One of the XXXHeader methods must have been called before calling this
940// method.
941func (p *Parser) TXTResource() (TXTResource, error) {
942	if !p.resHeaderValid || p.resHeader.Type != TypeTXT {
943		return TXTResource{}, ErrNotStarted
944	}
945	r, err := unpackTXTResource(p.msg, p.off, p.resHeader.Length)
946	if err != nil {
947		return TXTResource{}, err
948	}
949	p.off += int(p.resHeader.Length)
950	p.resHeaderValid = false
951	p.index++
952	return r, nil
953}
954
955// SRVResource parses a single SRVResource.
956//
957// One of the XXXHeader methods must have been called before calling this
958// method.
959func (p *Parser) SRVResource() (SRVResource, error) {
960	if !p.resHeaderValid || p.resHeader.Type != TypeSRV {
961		return SRVResource{}, ErrNotStarted
962	}
963	r, err := unpackSRVResource(p.msg, p.off)
964	if err != nil {
965		return SRVResource{}, err
966	}
967	p.off += int(p.resHeader.Length)
968	p.resHeaderValid = false
969	p.index++
970	return r, nil
971}
972
973// AResource parses a single AResource.
974//
975// One of the XXXHeader methods must have been called before calling this
976// method.
977func (p *Parser) AResource() (AResource, error) {
978	if !p.resHeaderValid || p.resHeader.Type != TypeA {
979		return AResource{}, ErrNotStarted
980	}
981	r, err := unpackAResource(p.msg, p.off)
982	if err != nil {
983		return AResource{}, err
984	}
985	p.off += int(p.resHeader.Length)
986	p.resHeaderValid = false
987	p.index++
988	return r, nil
989}
990
991// AAAAResource parses a single AAAAResource.
992//
993// One of the XXXHeader methods must have been called before calling this
994// method.
995func (p *Parser) AAAAResource() (AAAAResource, error) {
996	if !p.resHeaderValid || p.resHeader.Type != TypeAAAA {
997		return AAAAResource{}, ErrNotStarted
998	}
999	r, err := unpackAAAAResource(p.msg, p.off)
1000	if err != nil {
1001		return AAAAResource{}, err
1002	}
1003	p.off += int(p.resHeader.Length)
1004	p.resHeaderValid = false
1005	p.index++
1006	return r, nil
1007}
1008
1009// OPTResource parses a single OPTResource.
1010//
1011// One of the XXXHeader methods must have been called before calling this
1012// method.
1013func (p *Parser) OPTResource() (OPTResource, error) {
1014	if !p.resHeaderValid || p.resHeader.Type != TypeOPT {
1015		return OPTResource{}, ErrNotStarted
1016	}
1017	r, err := unpackOPTResource(p.msg, p.off, p.resHeader.Length)
1018	if err != nil {
1019		return OPTResource{}, err
1020	}
1021	p.off += int(p.resHeader.Length)
1022	p.resHeaderValid = false
1023	p.index++
1024	return r, nil
1025}
1026
1027// Unpack parses a full Message.
1028func (m *Message) Unpack(msg []byte) error {
1029	var p Parser
1030	var err error
1031	if m.Header, err = p.Start(msg); err != nil {
1032		return err
1033	}
1034	if m.Questions, err = p.AllQuestions(); err != nil {
1035		return err
1036	}
1037	if m.Answers, err = p.AllAnswers(); err != nil {
1038		return err
1039	}
1040	if m.Authorities, err = p.AllAuthorities(); err != nil {
1041		return err
1042	}
1043	if m.Additionals, err = p.AllAdditionals(); err != nil {
1044		return err
1045	}
1046	return nil
1047}
1048
1049// Pack packs a full Message.
1050func (m *Message) Pack() ([]byte, error) {
1051	return m.AppendPack(make([]byte, 0, packStartingCap))
1052}
1053
1054// AppendPack is like Pack but appends the full Message to b and returns the
1055// extended buffer.
1056func (m *Message) AppendPack(b []byte) ([]byte, error) {
1057	// Validate the lengths. It is very unlikely that anyone will try to
1058	// pack more than 65535 of any particular type, but it is possible and
1059	// we should fail gracefully.
1060	if len(m.Questions) > int(^uint16(0)) {
1061		return nil, errTooManyQuestions
1062	}
1063	if len(m.Answers) > int(^uint16(0)) {
1064		return nil, errTooManyAnswers
1065	}
1066	if len(m.Authorities) > int(^uint16(0)) {
1067		return nil, errTooManyAuthorities
1068	}
1069	if len(m.Additionals) > int(^uint16(0)) {
1070		return nil, errTooManyAdditionals
1071	}
1072
1073	var h header
1074	h.id, h.bits = m.Header.pack()
1075
1076	h.questions = uint16(len(m.Questions))
1077	h.answers = uint16(len(m.Answers))
1078	h.authorities = uint16(len(m.Authorities))
1079	h.additionals = uint16(len(m.Additionals))
1080
1081	compressionOff := len(b)
1082	msg := h.pack(b)
1083
1084	// RFC 1035 allows (but does not require) compression for packing. RFC
1085	// 1035 requires unpacking implementations to support compression, so
1086	// unconditionally enabling it is fine.
1087	//
1088	// DNS lookups are typically done over UDP, and RFC 1035 states that UDP
1089	// DNS messages can be a maximum of 512 bytes long. Without compression,
1090	// many DNS response messages are over this limit, so enabling
1091	// compression will help ensure compliance.
1092	compression := map[string]int{}
1093
1094	for i := range m.Questions {
1095		var err error
1096		if msg, err = m.Questions[i].pack(msg, compression, compressionOff); err != nil {
1097			return nil, &nestedError{"packing Question", err}
1098		}
1099	}
1100	for i := range m.Answers {
1101		var err error
1102		if msg, err = m.Answers[i].pack(msg, compression, compressionOff); err != nil {
1103			return nil, &nestedError{"packing Answer", err}
1104		}
1105	}
1106	for i := range m.Authorities {
1107		var err error
1108		if msg, err = m.Authorities[i].pack(msg, compression, compressionOff); err != nil {
1109			return nil, &nestedError{"packing Authority", err}
1110		}
1111	}
1112	for i := range m.Additionals {
1113		var err error
1114		if msg, err = m.Additionals[i].pack(msg, compression, compressionOff); err != nil {
1115			return nil, &nestedError{"packing Additional", err}
1116		}
1117	}
1118
1119	return msg, nil
1120}
1121
1122// GoString implements fmt.GoStringer.GoString.
1123func (m *Message) GoString() string {
1124	s := "dnsmessage.Message{Header: " + m.Header.GoString() + ", " +
1125		"Questions: []dnsmessage.Question{"
1126	if len(m.Questions) > 0 {
1127		s += m.Questions[0].GoString()
1128		for _, q := range m.Questions[1:] {
1129			s += ", " + q.GoString()
1130		}
1131	}
1132	s += "}, Answers: []dnsmessage.Resource{"
1133	if len(m.Answers) > 0 {
1134		s += m.Answers[0].GoString()
1135		for _, a := range m.Answers[1:] {
1136			s += ", " + a.GoString()
1137		}
1138	}
1139	s += "}, Authorities: []dnsmessage.Resource{"
1140	if len(m.Authorities) > 0 {
1141		s += m.Authorities[0].GoString()
1142		for _, a := range m.Authorities[1:] {
1143			s += ", " + a.GoString()
1144		}
1145	}
1146	s += "}, Additionals: []dnsmessage.Resource{"
1147	if len(m.Additionals) > 0 {
1148		s += m.Additionals[0].GoString()
1149		for _, a := range m.Additionals[1:] {
1150			s += ", " + a.GoString()
1151		}
1152	}
1153	return s + "}}"
1154}
1155
1156// A Builder allows incrementally packing a DNS message.
1157//
1158// Example usage:
1159//	buf := make([]byte, 2, 514)
1160//	b := NewBuilder(buf, Header{...})
1161//	b.EnableCompression()
1162//	// Optionally start a section and add things to that section.
1163//	// Repeat adding sections as necessary.
1164//	buf, err := b.Finish()
1165//	// If err is nil, buf[2:] will contain the built bytes.
1166type Builder struct {
1167	// msg is the storage for the message being built.
1168	msg []byte
1169
1170	// section keeps track of the current section being built.
1171	section section
1172
1173	// header keeps track of what should go in the header when Finish is
1174	// called.
1175	header header
1176
1177	// start is the starting index of the bytes allocated in msg for header.
1178	start int
1179
1180	// compression is a mapping from name suffixes to their starting index
1181	// in msg.
1182	compression map[string]int
1183}
1184
1185// NewBuilder creates a new builder with compression disabled.
1186//
1187// Note: Most users will want to immediately enable compression with the
1188// EnableCompression method. See that method's comment for why you may or may
1189// not want to enable compression.
1190//
1191// The DNS message is appended to the provided initial buffer buf (which may be
1192// nil) as it is built. The final message is returned by the (*Builder).Finish
1193// method, which may return the same underlying array if there was sufficient
1194// capacity in the slice.
1195func NewBuilder(buf []byte, h Header) Builder {
1196	if buf == nil {
1197		buf = make([]byte, 0, packStartingCap)
1198	}
1199	b := Builder{msg: buf, start: len(buf)}
1200	b.header.id, b.header.bits = h.pack()
1201	var hb [headerLen]byte
1202	b.msg = append(b.msg, hb[:]...)
1203	b.section = sectionHeader
1204	return b
1205}
1206
1207// EnableCompression enables compression in the Builder.
1208//
1209// Leaving compression disabled avoids compression related allocations, but can
1210// result in larger message sizes. Be careful with this mode as it can cause
1211// messages to exceed the UDP size limit.
1212//
1213// According to RFC 1035, section 4.1.4, the use of compression is optional, but
1214// all implementations must accept both compressed and uncompressed DNS
1215// messages.
1216//
1217// Compression should be enabled before any sections are added for best results.
1218func (b *Builder) EnableCompression() {
1219	b.compression = map[string]int{}
1220}
1221
1222func (b *Builder) startCheck(s section) error {
1223	if b.section <= sectionNotStarted {
1224		return ErrNotStarted
1225	}
1226	if b.section > s {
1227		return ErrSectionDone
1228	}
1229	return nil
1230}
1231
1232// StartQuestions prepares the builder for packing Questions.
1233func (b *Builder) StartQuestions() error {
1234	if err := b.startCheck(sectionQuestions); err != nil {
1235		return err
1236	}
1237	b.section = sectionQuestions
1238	return nil
1239}
1240
1241// StartAnswers prepares the builder for packing Answers.
1242func (b *Builder) StartAnswers() error {
1243	if err := b.startCheck(sectionAnswers); err != nil {
1244		return err
1245	}
1246	b.section = sectionAnswers
1247	return nil
1248}
1249
1250// StartAuthorities prepares the builder for packing Authorities.
1251func (b *Builder) StartAuthorities() error {
1252	if err := b.startCheck(sectionAuthorities); err != nil {
1253		return err
1254	}
1255	b.section = sectionAuthorities
1256	return nil
1257}
1258
1259// StartAdditionals prepares the builder for packing Additionals.
1260func (b *Builder) StartAdditionals() error {
1261	if err := b.startCheck(sectionAdditionals); err != nil {
1262		return err
1263	}
1264	b.section = sectionAdditionals
1265	return nil
1266}
1267
1268func (b *Builder) incrementSectionCount() error {
1269	var count *uint16
1270	var err error
1271	switch b.section {
1272	case sectionQuestions:
1273		count = &b.header.questions
1274		err = errTooManyQuestions
1275	case sectionAnswers:
1276		count = &b.header.answers
1277		err = errTooManyAnswers
1278	case sectionAuthorities:
1279		count = &b.header.authorities
1280		err = errTooManyAuthorities
1281	case sectionAdditionals:
1282		count = &b.header.additionals
1283		err = errTooManyAdditionals
1284	}
1285	if *count == ^uint16(0) {
1286		return err
1287	}
1288	*count++
1289	return nil
1290}
1291
1292// Question adds a single Question.
1293func (b *Builder) Question(q Question) error {
1294	if b.section < sectionQuestions {
1295		return ErrNotStarted
1296	}
1297	if b.section > sectionQuestions {
1298		return ErrSectionDone
1299	}
1300	msg, err := q.pack(b.msg, b.compression, b.start)
1301	if err != nil {
1302		return err
1303	}
1304	if err := b.incrementSectionCount(); err != nil {
1305		return err
1306	}
1307	b.msg = msg
1308	return nil
1309}
1310
1311func (b *Builder) checkResourceSection() error {
1312	if b.section < sectionAnswers {
1313		return ErrNotStarted
1314	}
1315	if b.section > sectionAdditionals {
1316		return ErrSectionDone
1317	}
1318	return nil
1319}
1320
1321// CNAMEResource adds a single CNAMEResource.
1322func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error {
1323	if err := b.checkResourceSection(); err != nil {
1324		return err
1325	}
1326	h.Type = r.realType()
1327	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1328	if err != nil {
1329		return &nestedError{"ResourceHeader", err}
1330	}
1331	preLen := len(msg)
1332	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1333		return &nestedError{"CNAMEResource body", err}
1334	}
1335	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1336		return err
1337	}
1338	if err := b.incrementSectionCount(); err != nil {
1339		return err
1340	}
1341	b.msg = msg
1342	return nil
1343}
1344
1345// MXResource adds a single MXResource.
1346func (b *Builder) MXResource(h ResourceHeader, r MXResource) error {
1347	if err := b.checkResourceSection(); err != nil {
1348		return err
1349	}
1350	h.Type = r.realType()
1351	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1352	if err != nil {
1353		return &nestedError{"ResourceHeader", err}
1354	}
1355	preLen := len(msg)
1356	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1357		return &nestedError{"MXResource body", err}
1358	}
1359	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1360		return err
1361	}
1362	if err := b.incrementSectionCount(); err != nil {
1363		return err
1364	}
1365	b.msg = msg
1366	return nil
1367}
1368
1369// NSResource adds a single NSResource.
1370func (b *Builder) NSResource(h ResourceHeader, r NSResource) error {
1371	if err := b.checkResourceSection(); err != nil {
1372		return err
1373	}
1374	h.Type = r.realType()
1375	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1376	if err != nil {
1377		return &nestedError{"ResourceHeader", err}
1378	}
1379	preLen := len(msg)
1380	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1381		return &nestedError{"NSResource body", err}
1382	}
1383	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1384		return err
1385	}
1386	if err := b.incrementSectionCount(); err != nil {
1387		return err
1388	}
1389	b.msg = msg
1390	return nil
1391}
1392
1393// PTRResource adds a single PTRResource.
1394func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error {
1395	if err := b.checkResourceSection(); err != nil {
1396		return err
1397	}
1398	h.Type = r.realType()
1399	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1400	if err != nil {
1401		return &nestedError{"ResourceHeader", err}
1402	}
1403	preLen := len(msg)
1404	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1405		return &nestedError{"PTRResource body", err}
1406	}
1407	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1408		return err
1409	}
1410	if err := b.incrementSectionCount(); err != nil {
1411		return err
1412	}
1413	b.msg = msg
1414	return nil
1415}
1416
1417// SOAResource adds a single SOAResource.
1418func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error {
1419	if err := b.checkResourceSection(); err != nil {
1420		return err
1421	}
1422	h.Type = r.realType()
1423	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1424	if err != nil {
1425		return &nestedError{"ResourceHeader", err}
1426	}
1427	preLen := len(msg)
1428	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1429		return &nestedError{"SOAResource body", err}
1430	}
1431	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1432		return err
1433	}
1434	if err := b.incrementSectionCount(); err != nil {
1435		return err
1436	}
1437	b.msg = msg
1438	return nil
1439}
1440
1441// TXTResource adds a single TXTResource.
1442func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error {
1443	if err := b.checkResourceSection(); err != nil {
1444		return err
1445	}
1446	h.Type = r.realType()
1447	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1448	if err != nil {
1449		return &nestedError{"ResourceHeader", err}
1450	}
1451	preLen := len(msg)
1452	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1453		return &nestedError{"TXTResource body", err}
1454	}
1455	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1456		return err
1457	}
1458	if err := b.incrementSectionCount(); err != nil {
1459		return err
1460	}
1461	b.msg = msg
1462	return nil
1463}
1464
1465// SRVResource adds a single SRVResource.
1466func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error {
1467	if err := b.checkResourceSection(); err != nil {
1468		return err
1469	}
1470	h.Type = r.realType()
1471	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1472	if err != nil {
1473		return &nestedError{"ResourceHeader", err}
1474	}
1475	preLen := len(msg)
1476	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1477		return &nestedError{"SRVResource body", err}
1478	}
1479	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1480		return err
1481	}
1482	if err := b.incrementSectionCount(); err != nil {
1483		return err
1484	}
1485	b.msg = msg
1486	return nil
1487}
1488
1489// AResource adds a single AResource.
1490func (b *Builder) AResource(h ResourceHeader, r AResource) error {
1491	if err := b.checkResourceSection(); err != nil {
1492		return err
1493	}
1494	h.Type = r.realType()
1495	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1496	if err != nil {
1497		return &nestedError{"ResourceHeader", err}
1498	}
1499	preLen := len(msg)
1500	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1501		return &nestedError{"AResource body", err}
1502	}
1503	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1504		return err
1505	}
1506	if err := b.incrementSectionCount(); err != nil {
1507		return err
1508	}
1509	b.msg = msg
1510	return nil
1511}
1512
1513// AAAAResource adds a single AAAAResource.
1514func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error {
1515	if err := b.checkResourceSection(); err != nil {
1516		return err
1517	}
1518	h.Type = r.realType()
1519	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1520	if err != nil {
1521		return &nestedError{"ResourceHeader", err}
1522	}
1523	preLen := len(msg)
1524	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1525		return &nestedError{"AAAAResource body", err}
1526	}
1527	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1528		return err
1529	}
1530	if err := b.incrementSectionCount(); err != nil {
1531		return err
1532	}
1533	b.msg = msg
1534	return nil
1535}
1536
1537// OPTResource adds a single OPTResource.
1538func (b *Builder) OPTResource(h ResourceHeader, r OPTResource) error {
1539	if err := b.checkResourceSection(); err != nil {
1540		return err
1541	}
1542	h.Type = r.realType()
1543	msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1544	if err != nil {
1545		return &nestedError{"ResourceHeader", err}
1546	}
1547	preLen := len(msg)
1548	if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1549		return &nestedError{"OPTResource body", err}
1550	}
1551	if err := h.fixLen(msg, lenOff, preLen); err != nil {
1552		return err
1553	}
1554	if err := b.incrementSectionCount(); err != nil {
1555		return err
1556	}
1557	b.msg = msg
1558	return nil
1559}
1560
1561// Finish ends message building and generates a binary message.
1562func (b *Builder) Finish() ([]byte, error) {
1563	if b.section < sectionHeader {
1564		return nil, ErrNotStarted
1565	}
1566	b.section = sectionDone
1567	// Space for the header was allocated in NewBuilder.
1568	b.header.pack(b.msg[b.start:b.start])
1569	return b.msg, nil
1570}
1571
1572// A ResourceHeader is the header of a DNS resource record. There are
1573// many types of DNS resource records, but they all share the same header.
1574type ResourceHeader struct {
1575	// Name is the domain name for which this resource record pertains.
1576	Name Name
1577
1578	// Type is the type of DNS resource record.
1579	//
1580	// This field will be set automatically during packing.
1581	Type Type
1582
1583	// Class is the class of network to which this DNS resource record
1584	// pertains.
1585	Class Class
1586
1587	// TTL is the length of time (measured in seconds) which this resource
1588	// record is valid for (time to live). All Resources in a set should
1589	// have the same TTL (RFC 2181 Section 5.2).
1590	TTL uint32
1591
1592	// Length is the length of data in the resource record after the header.
1593	//
1594	// This field will be set automatically during packing.
1595	Length uint16
1596}
1597
1598// GoString implements fmt.GoStringer.GoString.
1599func (h *ResourceHeader) GoString() string {
1600	return "dnsmessage.ResourceHeader{" +
1601		"Name: " + h.Name.GoString() + ", " +
1602		"Type: " + h.Type.GoString() + ", " +
1603		"Class: " + h.Class.GoString() + ", " +
1604		"TTL: " + printUint32(h.TTL) + ", " +
1605		"Length: " + printUint16(h.Length) + "}"
1606}
1607
1608// pack appends the wire format of the ResourceHeader to oldMsg.
1609//
1610// lenOff is the offset in msg where the Length field was packed.
1611func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int, compressionOff int) (msg []byte, lenOff int, err error) {
1612	msg = oldMsg
1613	if msg, err = h.Name.pack(msg, compression, compressionOff); err != nil {
1614		return oldMsg, 0, &nestedError{"Name", err}
1615	}
1616	msg = packType(msg, h.Type)
1617	msg = packClass(msg, h.Class)
1618	msg = packUint32(msg, h.TTL)
1619	lenOff = len(msg)
1620	msg = packUint16(msg, h.Length)
1621	return msg, lenOff, nil
1622}
1623
1624func (h *ResourceHeader) unpack(msg []byte, off int) (int, error) {
1625	newOff := off
1626	var err error
1627	if newOff, err = h.Name.unpack(msg, newOff); err != nil {
1628		return off, &nestedError{"Name", err}
1629	}
1630	if h.Type, newOff, err = unpackType(msg, newOff); err != nil {
1631		return off, &nestedError{"Type", err}
1632	}
1633	if h.Class, newOff, err = unpackClass(msg, newOff); err != nil {
1634		return off, &nestedError{"Class", err}
1635	}
1636	if h.TTL, newOff, err = unpackUint32(msg, newOff); err != nil {
1637		return off, &nestedError{"TTL", err}
1638	}
1639	if h.Length, newOff, err = unpackUint16(msg, newOff); err != nil {
1640		return off, &nestedError{"Length", err}
1641	}
1642	return newOff, nil
1643}
1644
1645// fixLen updates a packed ResourceHeader to include the length of the
1646// ResourceBody.
1647//
1648// lenOff is the offset of the ResourceHeader.Length field in msg.
1649//
1650// preLen is the length that msg was before the ResourceBody was packed.
1651func (h *ResourceHeader) fixLen(msg []byte, lenOff int, preLen int) error {
1652	conLen := len(msg) - preLen
1653	if conLen > int(^uint16(0)) {
1654		return errResTooLong
1655	}
1656
1657	// Fill in the length now that we know how long the content is.
1658	packUint16(msg[lenOff:lenOff], uint16(conLen))
1659	h.Length = uint16(conLen)
1660
1661	return nil
1662}
1663
1664// EDNS(0) wire constants.
1665const (
1666	edns0Version = 0
1667
1668	edns0DNSSECOK     = 0x00008000
1669	ednsVersionMask   = 0x00ff0000
1670	edns0DNSSECOKMask = 0x00ff8000
1671)
1672
1673// SetEDNS0 configures h for EDNS(0).
1674//
1675// The provided extRCode must be an extedned RCode.
1676func (h *ResourceHeader) SetEDNS0(udpPayloadLen int, extRCode RCode, dnssecOK bool) error {
1677	h.Name = Name{Data: [nameLen]byte{'.'}, Length: 1} // RFC 6891 section 6.1.2
1678	h.Type = TypeOPT
1679	h.Class = Class(udpPayloadLen)
1680	h.TTL = uint32(extRCode) >> 4 << 24
1681	if dnssecOK {
1682		h.TTL |= edns0DNSSECOK
1683	}
1684	return nil
1685}
1686
1687// DNSSECAllowed reports whether the DNSSEC OK bit is set.
1688func (h *ResourceHeader) DNSSECAllowed() bool {
1689	return h.TTL&edns0DNSSECOKMask == edns0DNSSECOK // RFC 6891 section 6.1.3
1690}
1691
1692// ExtendedRCode returns an extended RCode.
1693//
1694// The provided rcode must be the RCode in DNS message header.
1695func (h *ResourceHeader) ExtendedRCode(rcode RCode) RCode {
1696	if h.TTL&ednsVersionMask == edns0Version { // RFC 6891 section 6.1.3
1697		return RCode(h.TTL>>24<<4) | rcode
1698	}
1699	return rcode
1700}
1701
1702func skipResource(msg []byte, off int) (int, error) {
1703	newOff, err := skipName(msg, off)
1704	if err != nil {
1705		return off, &nestedError{"Name", err}
1706	}
1707	if newOff, err = skipType(msg, newOff); err != nil {
1708		return off, &nestedError{"Type", err}
1709	}
1710	if newOff, err = skipClass(msg, newOff); err != nil {
1711		return off, &nestedError{"Class", err}
1712	}
1713	if newOff, err = skipUint32(msg, newOff); err != nil {
1714		return off, &nestedError{"TTL", err}
1715	}
1716	length, newOff, err := unpackUint16(msg, newOff)
1717	if err != nil {
1718		return off, &nestedError{"Length", err}
1719	}
1720	if newOff += int(length); newOff > len(msg) {
1721		return off, errResourceLen
1722	}
1723	return newOff, nil
1724}
1725
1726// packUint16 appends the wire format of field to msg.
1727func packUint16(msg []byte, field uint16) []byte {
1728	return append(msg, byte(field>>8), byte(field))
1729}
1730
1731func unpackUint16(msg []byte, off int) (uint16, int, error) {
1732	if off+uint16Len > len(msg) {
1733		return 0, off, errBaseLen
1734	}
1735	return uint16(msg[off])<<8 | uint16(msg[off+1]), off + uint16Len, nil
1736}
1737
1738func skipUint16(msg []byte, off int) (int, error) {
1739	if off+uint16Len > len(msg) {
1740		return off, errBaseLen
1741	}
1742	return off + uint16Len, nil
1743}
1744
1745// packType appends the wire format of field to msg.
1746func packType(msg []byte, field Type) []byte {
1747	return packUint16(msg, uint16(field))
1748}
1749
1750func unpackType(msg []byte, off int) (Type, int, error) {
1751	t, o, err := unpackUint16(msg, off)
1752	return Type(t), o, err
1753}
1754
1755func skipType(msg []byte, off int) (int, error) {
1756	return skipUint16(msg, off)
1757}
1758
1759// packClass appends the wire format of field to msg.
1760func packClass(msg []byte, field Class) []byte {
1761	return packUint16(msg, uint16(field))
1762}
1763
1764func unpackClass(msg []byte, off int) (Class, int, error) {
1765	c, o, err := unpackUint16(msg, off)
1766	return Class(c), o, err
1767}
1768
1769func skipClass(msg []byte, off int) (int, error) {
1770	return skipUint16(msg, off)
1771}
1772
1773// packUint32 appends the wire format of field to msg.
1774func packUint32(msg []byte, field uint32) []byte {
1775	return append(
1776		msg,
1777		byte(field>>24),
1778		byte(field>>16),
1779		byte(field>>8),
1780		byte(field),
1781	)
1782}
1783
1784func unpackUint32(msg []byte, off int) (uint32, int, error) {
1785	if off+uint32Len > len(msg) {
1786		return 0, off, errBaseLen
1787	}
1788	v := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
1789	return v, off + uint32Len, nil
1790}
1791
1792func skipUint32(msg []byte, off int) (int, error) {
1793	if off+uint32Len > len(msg) {
1794		return off, errBaseLen
1795	}
1796	return off + uint32Len, nil
1797}
1798
1799// packText appends the wire format of field to msg.
1800func packText(msg []byte, field string) ([]byte, error) {
1801	l := len(field)
1802	if l > 255 {
1803		return nil, errStringTooLong
1804	}
1805	msg = append(msg, byte(l))
1806	msg = append(msg, field...)
1807
1808	return msg, nil
1809}
1810
1811func unpackText(msg []byte, off int) (string, int, error) {
1812	if off >= len(msg) {
1813		return "", off, errBaseLen
1814	}
1815	beginOff := off + 1
1816	endOff := beginOff + int(msg[off])
1817	if endOff > len(msg) {
1818		return "", off, errCalcLen
1819	}
1820	return string(msg[beginOff:endOff]), endOff, nil
1821}
1822
1823// packBytes appends the wire format of field to msg.
1824func packBytes(msg []byte, field []byte) []byte {
1825	return append(msg, field...)
1826}
1827
1828func unpackBytes(msg []byte, off int, field []byte) (int, error) {
1829	newOff := off + len(field)
1830	if newOff > len(msg) {
1831		return off, errBaseLen
1832	}
1833	copy(field, msg[off:newOff])
1834	return newOff, nil
1835}
1836
1837const nameLen = 255
1838
1839// A Name is a non-encoded domain name. It is used instead of strings to avoid
1840// allocations.
1841type Name struct {
1842	Data   [nameLen]byte
1843	Length uint8
1844}
1845
1846// NewName creates a new Name from a string.
1847func NewName(name string) (Name, error) {
1848	if len([]byte(name)) > nameLen {
1849		return Name{}, errCalcLen
1850	}
1851	n := Name{Length: uint8(len(name))}
1852	copy(n.Data[:], []byte(name))
1853	return n, nil
1854}
1855
1856// MustNewName creates a new Name from a string and panics on error.
1857func MustNewName(name string) Name {
1858	n, err := NewName(name)
1859	if err != nil {
1860		panic("creating name: " + err.Error())
1861	}
1862	return n
1863}
1864
1865// String implements fmt.Stringer.String.
1866func (n Name) String() string {
1867	return string(n.Data[:n.Length])
1868}
1869
1870// GoString implements fmt.GoStringer.GoString.
1871func (n *Name) GoString() string {
1872	return `dnsmessage.MustNewName("` + printString(n.Data[:n.Length]) + `")`
1873}
1874
1875// pack appends the wire format of the Name to msg.
1876//
1877// Domain names are a sequence of counted strings split at the dots. They end
1878// with a zero-length string. Compression can be used to reuse domain suffixes.
1879//
1880// The compression map will be updated with new domain suffixes. If compression
1881// is nil, compression will not be used.
1882func (n *Name) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
1883	oldMsg := msg
1884
1885	// Add a trailing dot to canonicalize name.
1886	if n.Length == 0 || n.Data[n.Length-1] != '.' {
1887		return oldMsg, errNonCanonicalName
1888	}
1889
1890	// Allow root domain.
1891	if n.Data[0] == '.' && n.Length == 1 {
1892		return append(msg, 0), nil
1893	}
1894
1895	// Emit sequence of counted strings, chopping at dots.
1896	for i, begin := 0, 0; i < int(n.Length); i++ {
1897		// Check for the end of the segment.
1898		if n.Data[i] == '.' {
1899			// The two most significant bits have special meaning.
1900			// It isn't allowed for segments to be long enough to
1901			// need them.
1902			if i-begin >= 1<<6 {
1903				return oldMsg, errSegTooLong
1904			}
1905
1906			// Segments must have a non-zero length.
1907			if i-begin == 0 {
1908				return oldMsg, errZeroSegLen
1909			}
1910
1911			msg = append(msg, byte(i-begin))
1912
1913			for j := begin; j < i; j++ {
1914				msg = append(msg, n.Data[j])
1915			}
1916
1917			begin = i + 1
1918			continue
1919		}
1920
1921		// We can only compress domain suffixes starting with a new
1922		// segment. A pointer is two bytes with the two most significant
1923		// bits set to 1 to indicate that it is a pointer.
1924		if (i == 0 || n.Data[i-1] == '.') && compression != nil {
1925			if ptr, ok := compression[string(n.Data[i:])]; ok {
1926				// Hit. Emit a pointer instead of the rest of
1927				// the domain.
1928				return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil
1929			}
1930
1931			// Miss. Add the suffix to the compression table if the
1932			// offset can be stored in the available 14 bytes.
1933			if len(msg) <= int(^uint16(0)>>2) {
1934				compression[string(n.Data[i:])] = len(msg) - compressionOff
1935			}
1936		}
1937	}
1938	return append(msg, 0), nil
1939}
1940
1941// unpack unpacks a domain name.
1942func (n *Name) unpack(msg []byte, off int) (int, error) {
1943	return n.unpackCompressed(msg, off, true /* allowCompression */)
1944}
1945
1946func (n *Name) unpackCompressed(msg []byte, off int, allowCompression bool) (int, error) {
1947	// currOff is the current working offset.
1948	currOff := off
1949
1950	// newOff is the offset where the next record will start. Pointers lead
1951	// to data that belongs to other names and thus doesn't count towards to
1952	// the usage of this name.
1953	newOff := off
1954
1955	// ptr is the number of pointers followed.
1956	var ptr int
1957
1958	// Name is a slice representation of the name data.
1959	name := n.Data[:0]
1960
1961Loop:
1962	for {
1963		if currOff >= len(msg) {
1964			return off, errBaseLen
1965		}
1966		c := int(msg[currOff])
1967		currOff++
1968		switch c & 0xC0 {
1969		case 0x00: // String segment
1970			if c == 0x00 {
1971				// A zero length signals the end of the name.
1972				break Loop
1973			}
1974			endOff := currOff + c
1975			if endOff > len(msg) {
1976				return off, errCalcLen
1977			}
1978			name = append(name, msg[currOff:endOff]...)
1979			name = append(name, '.')
1980			currOff = endOff
1981		case 0xC0: // Pointer
1982			if !allowCompression {
1983				return off, errCompressedSRV
1984			}
1985			if currOff >= len(msg) {
1986				return off, errInvalidPtr
1987			}
1988			c1 := msg[currOff]
1989			currOff++
1990			if ptr == 0 {
1991				newOff = currOff
1992			}
1993			// Don't follow too many pointers, maybe there's a loop.
1994			if ptr++; ptr > 10 {
1995				return off, errTooManyPtr
1996			}
1997			currOff = (c^0xC0)<<8 | int(c1)
1998		default:
1999			// Prefixes 0x80 and 0x40 are reserved.
2000			return off, errReserved
2001		}
2002	}
2003	if len(name) == 0 {
2004		name = append(name, '.')
2005	}
2006	if len(name) > len(n.Data) {
2007		return off, errCalcLen
2008	}
2009	n.Length = uint8(len(name))
2010	if ptr == 0 {
2011		newOff = currOff
2012	}
2013	return newOff, nil
2014}
2015
2016func skipName(msg []byte, off int) (int, error) {
2017	// newOff is the offset where the next record will start. Pointers lead
2018	// to data that belongs to other names and thus doesn't count towards to
2019	// the usage of this name.
2020	newOff := off
2021
2022Loop:
2023	for {
2024		if newOff >= len(msg) {
2025			return off, errBaseLen
2026		}
2027		c := int(msg[newOff])
2028		newOff++
2029		switch c & 0xC0 {
2030		case 0x00:
2031			if c == 0x00 {
2032				// A zero length signals the end of the name.
2033				break Loop
2034			}
2035			// literal string
2036			newOff += c
2037			if newOff > len(msg) {
2038				return off, errCalcLen
2039			}
2040		case 0xC0:
2041			// Pointer to somewhere else in msg.
2042
2043			// Pointers are two bytes.
2044			newOff++
2045
2046			// Don't follow the pointer as the data here has ended.
2047			break Loop
2048		default:
2049			// Prefixes 0x80 and 0x40 are reserved.
2050			return off, errReserved
2051		}
2052	}
2053
2054	return newOff, nil
2055}
2056
2057// A Question is a DNS query.
2058type Question struct {
2059	Name  Name
2060	Type  Type
2061	Class Class
2062}
2063
2064// pack appends the wire format of the Question to msg.
2065func (q *Question) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2066	msg, err := q.Name.pack(msg, compression, compressionOff)
2067	if err != nil {
2068		return msg, &nestedError{"Name", err}
2069	}
2070	msg = packType(msg, q.Type)
2071	return packClass(msg, q.Class), nil
2072}
2073
2074// GoString implements fmt.GoStringer.GoString.
2075func (q *Question) GoString() string {
2076	return "dnsmessage.Question{" +
2077		"Name: " + q.Name.GoString() + ", " +
2078		"Type: " + q.Type.GoString() + ", " +
2079		"Class: " + q.Class.GoString() + "}"
2080}
2081
2082func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, int, error) {
2083	var (
2084		r    ResourceBody
2085		err  error
2086		name string
2087	)
2088	switch hdr.Type {
2089	case TypeA:
2090		var rb AResource
2091		rb, err = unpackAResource(msg, off)
2092		r = &rb
2093		name = "A"
2094	case TypeNS:
2095		var rb NSResource
2096		rb, err = unpackNSResource(msg, off)
2097		r = &rb
2098		name = "NS"
2099	case TypeCNAME:
2100		var rb CNAMEResource
2101		rb, err = unpackCNAMEResource(msg, off)
2102		r = &rb
2103		name = "CNAME"
2104	case TypeSOA:
2105		var rb SOAResource
2106		rb, err = unpackSOAResource(msg, off)
2107		r = &rb
2108		name = "SOA"
2109	case TypePTR:
2110		var rb PTRResource
2111		rb, err = unpackPTRResource(msg, off)
2112		r = &rb
2113		name = "PTR"
2114	case TypeMX:
2115		var rb MXResource
2116		rb, err = unpackMXResource(msg, off)
2117		r = &rb
2118		name = "MX"
2119	case TypeTXT:
2120		var rb TXTResource
2121		rb, err = unpackTXTResource(msg, off, hdr.Length)
2122		r = &rb
2123		name = "TXT"
2124	case TypeAAAA:
2125		var rb AAAAResource
2126		rb, err = unpackAAAAResource(msg, off)
2127		r = &rb
2128		name = "AAAA"
2129	case TypeSRV:
2130		var rb SRVResource
2131		rb, err = unpackSRVResource(msg, off)
2132		r = &rb
2133		name = "SRV"
2134	case TypeOPT:
2135		var rb OPTResource
2136		rb, err = unpackOPTResource(msg, off, hdr.Length)
2137		r = &rb
2138		name = "OPT"
2139	}
2140	if err != nil {
2141		return nil, off, &nestedError{name + " record", err}
2142	}
2143	if r == nil {
2144		return nil, off, fmt.Errorf("invalid resource type: %d", hdr.Type)
2145	}
2146	return r, off + int(hdr.Length), nil
2147}
2148
2149// A CNAMEResource is a CNAME Resource record.
2150type CNAMEResource struct {
2151	CNAME Name
2152}
2153
2154func (r *CNAMEResource) realType() Type {
2155	return TypeCNAME
2156}
2157
2158// pack appends the wire format of the CNAMEResource to msg.
2159func (r *CNAMEResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2160	return r.CNAME.pack(msg, compression, compressionOff)
2161}
2162
2163// GoString implements fmt.GoStringer.GoString.
2164func (r *CNAMEResource) GoString() string {
2165	return "dnsmessage.CNAMEResource{CNAME: " + r.CNAME.GoString() + "}"
2166}
2167
2168func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) {
2169	var cname Name
2170	if _, err := cname.unpack(msg, off); err != nil {
2171		return CNAMEResource{}, err
2172	}
2173	return CNAMEResource{cname}, nil
2174}
2175
2176// An MXResource is an MX Resource record.
2177type MXResource struct {
2178	Pref uint16
2179	MX   Name
2180}
2181
2182func (r *MXResource) realType() Type {
2183	return TypeMX
2184}
2185
2186// pack appends the wire format of the MXResource to msg.
2187func (r *MXResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2188	oldMsg := msg
2189	msg = packUint16(msg, r.Pref)
2190	msg, err := r.MX.pack(msg, compression, compressionOff)
2191	if err != nil {
2192		return oldMsg, &nestedError{"MXResource.MX", err}
2193	}
2194	return msg, nil
2195}
2196
2197// GoString implements fmt.GoStringer.GoString.
2198func (r *MXResource) GoString() string {
2199	return "dnsmessage.MXResource{" +
2200		"Pref: " + printUint16(r.Pref) + ", " +
2201		"MX: " + r.MX.GoString() + "}"
2202}
2203
2204func unpackMXResource(msg []byte, off int) (MXResource, error) {
2205	pref, off, err := unpackUint16(msg, off)
2206	if err != nil {
2207		return MXResource{}, &nestedError{"Pref", err}
2208	}
2209	var mx Name
2210	if _, err := mx.unpack(msg, off); err != nil {
2211		return MXResource{}, &nestedError{"MX", err}
2212	}
2213	return MXResource{pref, mx}, nil
2214}
2215
2216// An NSResource is an NS Resource record.
2217type NSResource struct {
2218	NS Name
2219}
2220
2221func (r *NSResource) realType() Type {
2222	return TypeNS
2223}
2224
2225// pack appends the wire format of the NSResource to msg.
2226func (r *NSResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2227	return r.NS.pack(msg, compression, compressionOff)
2228}
2229
2230// GoString implements fmt.GoStringer.GoString.
2231func (r *NSResource) GoString() string {
2232	return "dnsmessage.NSResource{NS: " + r.NS.GoString() + "}"
2233}
2234
2235func unpackNSResource(msg []byte, off int) (NSResource, error) {
2236	var ns Name
2237	if _, err := ns.unpack(msg, off); err != nil {
2238		return NSResource{}, err
2239	}
2240	return NSResource{ns}, nil
2241}
2242
2243// A PTRResource is a PTR Resource record.
2244type PTRResource struct {
2245	PTR Name
2246}
2247
2248func (r *PTRResource) realType() Type {
2249	return TypePTR
2250}
2251
2252// pack appends the wire format of the PTRResource to msg.
2253func (r *PTRResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2254	return r.PTR.pack(msg, compression, compressionOff)
2255}
2256
2257// GoString implements fmt.GoStringer.GoString.
2258func (r *PTRResource) GoString() string {
2259	return "dnsmessage.PTRResource{PTR: " + r.PTR.GoString() + "}"
2260}
2261
2262func unpackPTRResource(msg []byte, off int) (PTRResource, error) {
2263	var ptr Name
2264	if _, err := ptr.unpack(msg, off); err != nil {
2265		return PTRResource{}, err
2266	}
2267	return PTRResource{ptr}, nil
2268}
2269
2270// An SOAResource is an SOA Resource record.
2271type SOAResource struct {
2272	NS      Name
2273	MBox    Name
2274	Serial  uint32
2275	Refresh uint32
2276	Retry   uint32
2277	Expire  uint32
2278
2279	// MinTTL the is the default TTL of Resources records which did not
2280	// contain a TTL value and the TTL of negative responses. (RFC 2308
2281	// Section 4)
2282	MinTTL uint32
2283}
2284
2285func (r *SOAResource) realType() Type {
2286	return TypeSOA
2287}
2288
2289// pack appends the wire format of the SOAResource to msg.
2290func (r *SOAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2291	oldMsg := msg
2292	msg, err := r.NS.pack(msg, compression, compressionOff)
2293	if err != nil {
2294		return oldMsg, &nestedError{"SOAResource.NS", err}
2295	}
2296	msg, err = r.MBox.pack(msg, compression, compressionOff)
2297	if err != nil {
2298		return oldMsg, &nestedError{"SOAResource.MBox", err}
2299	}
2300	msg = packUint32(msg, r.Serial)
2301	msg = packUint32(msg, r.Refresh)
2302	msg = packUint32(msg, r.Retry)
2303	msg = packUint32(msg, r.Expire)
2304	return packUint32(msg, r.MinTTL), nil
2305}
2306
2307// GoString implements fmt.GoStringer.GoString.
2308func (r *SOAResource) GoString() string {
2309	return "dnsmessage.SOAResource{" +
2310		"NS: " + r.NS.GoString() + ", " +
2311		"MBox: " + r.MBox.GoString() + ", " +
2312		"Serial: " + printUint32(r.Serial) + ", " +
2313		"Refresh: " + printUint32(r.Refresh) + ", " +
2314		"Retry: " + printUint32(r.Retry) + ", " +
2315		"Expire: " + printUint32(r.Expire) + ", " +
2316		"MinTTL: " + printUint32(r.MinTTL) + "}"
2317}
2318
2319func unpackSOAResource(msg []byte, off int) (SOAResource, error) {
2320	var ns Name
2321	off, err := ns.unpack(msg, off)
2322	if err != nil {
2323		return SOAResource{}, &nestedError{"NS", err}
2324	}
2325	var mbox Name
2326	if off, err = mbox.unpack(msg, off); err != nil {
2327		return SOAResource{}, &nestedError{"MBox", err}
2328	}
2329	serial, off, err := unpackUint32(msg, off)
2330	if err != nil {
2331		return SOAResource{}, &nestedError{"Serial", err}
2332	}
2333	refresh, off, err := unpackUint32(msg, off)
2334	if err != nil {
2335		return SOAResource{}, &nestedError{"Refresh", err}
2336	}
2337	retry, off, err := unpackUint32(msg, off)
2338	if err != nil {
2339		return SOAResource{}, &nestedError{"Retry", err}
2340	}
2341	expire, off, err := unpackUint32(msg, off)
2342	if err != nil {
2343		return SOAResource{}, &nestedError{"Expire", err}
2344	}
2345	minTTL, _, err := unpackUint32(msg, off)
2346	if err != nil {
2347		return SOAResource{}, &nestedError{"MinTTL", err}
2348	}
2349	return SOAResource{ns, mbox, serial, refresh, retry, expire, minTTL}, nil
2350}
2351
2352// A TXTResource is a TXT Resource record.
2353type TXTResource struct {
2354	TXT []string
2355}
2356
2357func (r *TXTResource) realType() Type {
2358	return TypeTXT
2359}
2360
2361// pack appends the wire format of the TXTResource to msg.
2362func (r *TXTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2363	oldMsg := msg
2364	for _, s := range r.TXT {
2365		var err error
2366		msg, err = packText(msg, s)
2367		if err != nil {
2368			return oldMsg, err
2369		}
2370	}
2371	return msg, nil
2372}
2373
2374// GoString implements fmt.GoStringer.GoString.
2375func (r *TXTResource) GoString() string {
2376	s := "dnsmessage.TXTResource{TXT: []string{"
2377	if len(r.TXT) == 0 {
2378		return s + "}}"
2379	}
2380	s += `"` + printString([]byte(r.TXT[0]))
2381	for _, t := range r.TXT[1:] {
2382		s += `", "` + printString([]byte(t))
2383	}
2384	return s + `"}}`
2385}
2386
2387func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) {
2388	txts := make([]string, 0, 1)
2389	for n := uint16(0); n < length; {
2390		var t string
2391		var err error
2392		if t, off, err = unpackText(msg, off); err != nil {
2393			return TXTResource{}, &nestedError{"text", err}
2394		}
2395		// Check if we got too many bytes.
2396		if length-n < uint16(len(t))+1 {
2397			return TXTResource{}, errCalcLen
2398		}
2399		n += uint16(len(t)) + 1
2400		txts = append(txts, t)
2401	}
2402	return TXTResource{txts}, nil
2403}
2404
2405// An SRVResource is an SRV Resource record.
2406type SRVResource struct {
2407	Priority uint16
2408	Weight   uint16
2409	Port     uint16
2410	Target   Name // Not compressed as per RFC 2782.
2411}
2412
2413func (r *SRVResource) realType() Type {
2414	return TypeSRV
2415}
2416
2417// pack appends the wire format of the SRVResource to msg.
2418func (r *SRVResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2419	oldMsg := msg
2420	msg = packUint16(msg, r.Priority)
2421	msg = packUint16(msg, r.Weight)
2422	msg = packUint16(msg, r.Port)
2423	msg, err := r.Target.pack(msg, nil, compressionOff)
2424	if err != nil {
2425		return oldMsg, &nestedError{"SRVResource.Target", err}
2426	}
2427	return msg, nil
2428}
2429
2430// GoString implements fmt.GoStringer.GoString.
2431func (r *SRVResource) GoString() string {
2432	return "dnsmessage.SRVResource{" +
2433		"Priority: " + printUint16(r.Priority) + ", " +
2434		"Weight: " + printUint16(r.Weight) + ", " +
2435		"Port: " + printUint16(r.Port) + ", " +
2436		"Target: " + r.Target.GoString() + "}"
2437}
2438
2439func unpackSRVResource(msg []byte, off int) (SRVResource, error) {
2440	priority, off, err := unpackUint16(msg, off)
2441	if err != nil {
2442		return SRVResource{}, &nestedError{"Priority", err}
2443	}
2444	weight, off, err := unpackUint16(msg, off)
2445	if err != nil {
2446		return SRVResource{}, &nestedError{"Weight", err}
2447	}
2448	port, off, err := unpackUint16(msg, off)
2449	if err != nil {
2450		return SRVResource{}, &nestedError{"Port", err}
2451	}
2452	var target Name
2453	if _, err := target.unpackCompressed(msg, off, false /* allowCompression */); err != nil {
2454		return SRVResource{}, &nestedError{"Target", err}
2455	}
2456	return SRVResource{priority, weight, port, target}, nil
2457}
2458
2459// An AResource is an A Resource record.
2460type AResource struct {
2461	A [4]byte
2462}
2463
2464func (r *AResource) realType() Type {
2465	return TypeA
2466}
2467
2468// pack appends the wire format of the AResource to msg.
2469func (r *AResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2470	return packBytes(msg, r.A[:]), nil
2471}
2472
2473// GoString implements fmt.GoStringer.GoString.
2474func (r *AResource) GoString() string {
2475	return "dnsmessage.AResource{" +
2476		"A: [4]byte{" + printByteSlice(r.A[:]) + "}}"
2477}
2478
2479func unpackAResource(msg []byte, off int) (AResource, error) {
2480	var a [4]byte
2481	if _, err := unpackBytes(msg, off, a[:]); err != nil {
2482		return AResource{}, err
2483	}
2484	return AResource{a}, nil
2485}
2486
2487// An AAAAResource is an AAAA Resource record.
2488type AAAAResource struct {
2489	AAAA [16]byte
2490}
2491
2492func (r *AAAAResource) realType() Type {
2493	return TypeAAAA
2494}
2495
2496// GoString implements fmt.GoStringer.GoString.
2497func (r *AAAAResource) GoString() string {
2498	return "dnsmessage.AAAAResource{" +
2499		"AAAA: [16]byte{" + printByteSlice(r.AAAA[:]) + "}}"
2500}
2501
2502// pack appends the wire format of the AAAAResource to msg.
2503func (r *AAAAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2504	return packBytes(msg, r.AAAA[:]), nil
2505}
2506
2507func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) {
2508	var aaaa [16]byte
2509	if _, err := unpackBytes(msg, off, aaaa[:]); err != nil {
2510		return AAAAResource{}, err
2511	}
2512	return AAAAResource{aaaa}, nil
2513}
2514
2515// An OPTResource is an OPT pseudo Resource record.
2516//
2517// The pseudo resource record is part of the extension mechanisms for DNS
2518// as defined in RFC 6891.
2519type OPTResource struct {
2520	Options []Option
2521}
2522
2523// An Option represents a DNS message option within OPTResource.
2524//
2525// The message option is part of the extension mechanisms for DNS as
2526// defined in RFC 6891.
2527type Option struct {
2528	Code uint16 // option code
2529	Data []byte
2530}
2531
2532// GoString implements fmt.GoStringer.GoString.
2533func (o *Option) GoString() string {
2534	return "dnsmessage.Option{" +
2535		"Code: " + printUint16(o.Code) + ", " +
2536		"Data: []byte{" + printByteSlice(o.Data) + "}}"
2537}
2538
2539func (r *OPTResource) realType() Type {
2540	return TypeOPT
2541}
2542
2543func (r *OPTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2544	for _, opt := range r.Options {
2545		msg = packUint16(msg, opt.Code)
2546		l := uint16(len(opt.Data))
2547		msg = packUint16(msg, l)
2548		msg = packBytes(msg, opt.Data)
2549	}
2550	return msg, nil
2551}
2552
2553// GoString implements fmt.GoStringer.GoString.
2554func (r *OPTResource) GoString() string {
2555	s := "dnsmessage.OPTResource{Options: []dnsmessage.Option{"
2556	if len(r.Options) == 0 {
2557		return s + "}}"
2558	}
2559	s += r.Options[0].GoString()
2560	for _, o := range r.Options[1:] {
2561		s += ", " + o.GoString()
2562	}
2563	return s + "}}"
2564}
2565
2566func unpackOPTResource(msg []byte, off int, length uint16) (OPTResource, error) {
2567	var opts []Option
2568	for oldOff := off; off < oldOff+int(length); {
2569		var err error
2570		var o Option
2571		o.Code, off, err = unpackUint16(msg, off)
2572		if err != nil {
2573			return OPTResource{}, &nestedError{"Code", err}
2574		}
2575		var l uint16
2576		l, off, err = unpackUint16(msg, off)
2577		if err != nil {
2578			return OPTResource{}, &nestedError{"Data", err}
2579		}
2580		o.Data = make([]byte, l)
2581		if copy(o.Data, msg[off:]) != int(l) {
2582			return OPTResource{}, &nestedError{"Data", errCalcLen}
2583		}
2584		off += int(l)
2585		opts = append(opts, o)
2586	}
2587	return OPTResource{opts}, nil
2588}
2589