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