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