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