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