blob: 19b260dea04ebfbf80669ef5866f099698156ece [file] [log] [blame]
David K. Bainbridge215e0242017-09-05 23:18:24 -07001// 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// This implementation is designed to minimize heap allocations and avoid
9// unnecessary packing and unpacking as much as possible.
10package dnsmessage
11
12import (
13 "errors"
14)
15
16// Packet formats
17
18// A Type is a type of DNS request and response.
19type Type uint16
20
21// A Class is a type of network.
22type Class uint16
23
24// An OpCode is a DNS operation code.
25type OpCode uint16
26
27// An RCode is a DNS response status code.
28type RCode uint16
29
30// Wire constants.
31const (
32 // ResourceHeader.Type and Question.Type
33 TypeA Type = 1
34 TypeNS Type = 2
35 TypeCNAME Type = 5
36 TypeSOA Type = 6
37 TypePTR Type = 12
38 TypeMX Type = 15
39 TypeTXT Type = 16
40 TypeAAAA Type = 28
41 TypeSRV Type = 33
42
43 // Question.Type
44 TypeWKS Type = 11
45 TypeHINFO Type = 13
46 TypeMINFO Type = 14
47 TypeAXFR Type = 252
48 TypeALL Type = 255
49
50 // ResourceHeader.Class and Question.Class
51 ClassINET Class = 1
52 ClassCSNET Class = 2
53 ClassCHAOS Class = 3
54 ClassHESIOD Class = 4
55
56 // Question.Class
57 ClassANY Class = 255
58
59 // Message.Rcode
60 RCodeSuccess RCode = 0
61 RCodeFormatError RCode = 1
62 RCodeServerFailure RCode = 2
63 RCodeNameError RCode = 3
64 RCodeNotImplemented RCode = 4
65 RCodeRefused RCode = 5
66)
67
68var (
69 // ErrNotStarted indicates that the prerequisite information isn't
70 // available yet because the previous records haven't been appropriately
71 // parsed, skipped or finished.
72 ErrNotStarted = errors.New("parsing/packing of this type isn't available yet")
73
74 // ErrSectionDone indicated that all records in the section have been
75 // parsed or finished.
76 ErrSectionDone = errors.New("parsing/packing of this section has completed")
77
78 errBaseLen = errors.New("insufficient data for base length type")
79 errCalcLen = errors.New("insufficient data for calculated length type")
80 errReserved = errors.New("segment prefix is reserved")
81 errTooManyPtr = errors.New("too many pointers (>10)")
82 errInvalidPtr = errors.New("invalid pointer")
83 errNilResouceBody = errors.New("nil resource body")
84 errResourceLen = errors.New("insufficient data for resource body length")
85 errSegTooLong = errors.New("segment length too long")
86 errZeroSegLen = errors.New("zero length segment")
87 errResTooLong = errors.New("resource length too long")
88 errTooManyQuestions = errors.New("too many Questions to pack (>65535)")
89 errTooManyAnswers = errors.New("too many Answers to pack (>65535)")
90 errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
91 errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
92 errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)")
93)
94
95// Internal constants.
96const (
97 // packStartingCap is the default initial buffer size allocated during
98 // packing.
99 //
100 // The starting capacity doesn't matter too much, but most DNS responses
101 // Will be <= 512 bytes as it is the limit for DNS over UDP.
102 packStartingCap = 512
103
104 // uint16Len is the length (in bytes) of a uint16.
105 uint16Len = 2
106
107 // uint32Len is the length (in bytes) of a uint32.
108 uint32Len = 4
109
110 // headerLen is the length (in bytes) of a DNS header.
111 //
112 // A header is comprised of 6 uint16s and no padding.
113 headerLen = 6 * uint16Len
114)
115
116type nestedError struct {
117 // s is the current level's error message.
118 s string
119
120 // err is the nested error.
121 err error
122}
123
124// nestedError implements error.Error.
125func (e *nestedError) Error() string {
126 return e.s + ": " + e.err.Error()
127}
128
129// Header is a representation of a DNS message header.
130type Header struct {
131 ID uint16
132 Response bool
133 OpCode OpCode
134 Authoritative bool
135 Truncated bool
136 RecursionDesired bool
137 RecursionAvailable bool
138 RCode RCode
139}
140
141func (m *Header) pack() (id uint16, bits uint16) {
142 id = m.ID
143 bits = uint16(m.OpCode)<<11 | uint16(m.RCode)
144 if m.RecursionAvailable {
145 bits |= headerBitRA
146 }
147 if m.RecursionDesired {
148 bits |= headerBitRD
149 }
150 if m.Truncated {
151 bits |= headerBitTC
152 }
153 if m.Authoritative {
154 bits |= headerBitAA
155 }
156 if m.Response {
157 bits |= headerBitQR
158 }
159 return
160}
161
162// Message is a representation of a DNS message.
163type Message struct {
164 Header
165 Questions []Question
166 Answers []Resource
167 Authorities []Resource
168 Additionals []Resource
169}
170
171type section uint8
172
173const (
174 sectionNotStarted section = iota
175 sectionHeader
176 sectionQuestions
177 sectionAnswers
178 sectionAuthorities
179 sectionAdditionals
180 sectionDone
181
182 headerBitQR = 1 << 15 // query/response (response=1)
183 headerBitAA = 1 << 10 // authoritative
184 headerBitTC = 1 << 9 // truncated
185 headerBitRD = 1 << 8 // recursion desired
186 headerBitRA = 1 << 7 // recursion available
187)
188
189var sectionNames = map[section]string{
190 sectionHeader: "header",
191 sectionQuestions: "Question",
192 sectionAnswers: "Answer",
193 sectionAuthorities: "Authority",
194 sectionAdditionals: "Additional",
195}
196
197// header is the wire format for a DNS message header.
198type header struct {
199 id uint16
200 bits uint16
201 questions uint16
202 answers uint16
203 authorities uint16
204 additionals uint16
205}
206
207func (h *header) count(sec section) uint16 {
208 switch sec {
209 case sectionQuestions:
210 return h.questions
211 case sectionAnswers:
212 return h.answers
213 case sectionAuthorities:
214 return h.authorities
215 case sectionAdditionals:
216 return h.additionals
217 }
218 return 0
219}
220
221func (h *header) pack(msg []byte) []byte {
222 msg = packUint16(msg, h.id)
223 msg = packUint16(msg, h.bits)
224 msg = packUint16(msg, h.questions)
225 msg = packUint16(msg, h.answers)
226 msg = packUint16(msg, h.authorities)
227 return packUint16(msg, h.additionals)
228}
229
230func (h *header) unpack(msg []byte, off int) (int, error) {
231 newOff := off
232 var err error
233 if h.id, newOff, err = unpackUint16(msg, newOff); err != nil {
234 return off, &nestedError{"id", err}
235 }
236 if h.bits, newOff, err = unpackUint16(msg, newOff); err != nil {
237 return off, &nestedError{"bits", err}
238 }
239 if h.questions, newOff, err = unpackUint16(msg, newOff); err != nil {
240 return off, &nestedError{"questions", err}
241 }
242 if h.answers, newOff, err = unpackUint16(msg, newOff); err != nil {
243 return off, &nestedError{"answers", err}
244 }
245 if h.authorities, newOff, err = unpackUint16(msg, newOff); err != nil {
246 return off, &nestedError{"authorities", err}
247 }
248 if h.additionals, newOff, err = unpackUint16(msg, newOff); err != nil {
249 return off, &nestedError{"additionals", err}
250 }
251 return newOff, nil
252}
253
254func (h *header) header() Header {
255 return Header{
256 ID: h.id,
257 Response: (h.bits & headerBitQR) != 0,
258 OpCode: OpCode(h.bits>>11) & 0xF,
259 Authoritative: (h.bits & headerBitAA) != 0,
260 Truncated: (h.bits & headerBitTC) != 0,
261 RecursionDesired: (h.bits & headerBitRD) != 0,
262 RecursionAvailable: (h.bits & headerBitRA) != 0,
263 RCode: RCode(h.bits & 0xF),
264 }
265}
266
267// A Resource is a DNS resource record.
268type Resource struct {
269 Header ResourceHeader
270 Body ResourceBody
271}
272
273// A ResourceBody is a DNS resource record minus the header.
274type ResourceBody interface {
275 // pack packs a Resource except for its header.
276 pack(msg []byte, compression map[string]int) ([]byte, error)
277
278 // realType returns the actual type of the Resource. This is used to
279 // fill in the header Type field.
280 realType() Type
281}
282
283func (r *Resource) pack(msg []byte, compression map[string]int) ([]byte, error) {
284 if r.Body == nil {
285 return msg, errNilResouceBody
286 }
287 oldMsg := msg
288 r.Header.Type = r.Body.realType()
289 msg, length, err := r.Header.pack(msg, compression)
290 if err != nil {
291 return msg, &nestedError{"ResourceHeader", err}
292 }
293 preLen := len(msg)
294 msg, err = r.Body.pack(msg, compression)
295 if err != nil {
296 return msg, &nestedError{"content", err}
297 }
298 if err := r.Header.fixLen(msg, length, preLen); err != nil {
299 return oldMsg, err
300 }
301 return msg, nil
302}
303
304// A Parser allows incrementally parsing a DNS message.
305//
306// When parsing is started, the Header is parsed. Next, each Question can be
307// either parsed or skipped. Alternatively, all Questions can be skipped at
308// once. When all Questions have been parsed, attempting to parse Questions
309// will return (nil, nil) and attempting to skip Questions will return
310// (true, nil). After all Questions have been either parsed or skipped, all
311// Answers, Authorities and Additionals can be either parsed or skipped in the
312// same way, and each type of Resource must be fully parsed or skipped before
313// proceeding to the next type of Resource.
314//
315// Note that there is no requirement to fully skip or parse the message.
316type Parser struct {
317 msg []byte
318 header header
319
320 section section
321 off int
322 index int
323 resHeaderValid bool
324 resHeader ResourceHeader
325}
326
327// Start parses the header and enables the parsing of Questions.
328func (p *Parser) Start(msg []byte) (Header, error) {
329 if p.msg != nil {
330 *p = Parser{}
331 }
332 p.msg = msg
333 var err error
334 if p.off, err = p.header.unpack(msg, 0); err != nil {
335 return Header{}, &nestedError{"unpacking header", err}
336 }
337 p.section = sectionQuestions
338 return p.header.header(), nil
339}
340
341func (p *Parser) checkAdvance(sec section) error {
342 if p.section < sec {
343 return ErrNotStarted
344 }
345 if p.section > sec {
346 return ErrSectionDone
347 }
348 p.resHeaderValid = false
349 if p.index == int(p.header.count(sec)) {
350 p.index = 0
351 p.section++
352 return ErrSectionDone
353 }
354 return nil
355}
356
357func (p *Parser) resource(sec section) (Resource, error) {
358 var r Resource
359 var err error
360 r.Header, err = p.resourceHeader(sec)
361 if err != nil {
362 return r, err
363 }
364 p.resHeaderValid = false
365 r.Body, p.off, err = unpackResourceBody(p.msg, p.off, r.Header)
366 if err != nil {
367 return Resource{}, &nestedError{"unpacking " + sectionNames[sec], err}
368 }
369 p.index++
370 return r, nil
371}
372
373func (p *Parser) resourceHeader(sec section) (ResourceHeader, error) {
374 if p.resHeaderValid {
375 return p.resHeader, nil
376 }
377 if err := p.checkAdvance(sec); err != nil {
378 return ResourceHeader{}, err
379 }
380 var hdr ResourceHeader
381 off, err := hdr.unpack(p.msg, p.off)
382 if err != nil {
383 return ResourceHeader{}, err
384 }
385 p.resHeaderValid = true
386 p.resHeader = hdr
387 p.off = off
388 return hdr, nil
389}
390
391func (p *Parser) skipResource(sec section) error {
392 if p.resHeaderValid {
393 newOff := p.off + int(p.resHeader.Length)
394 if newOff > len(p.msg) {
395 return errResourceLen
396 }
397 p.off = newOff
398 p.resHeaderValid = false
399 p.index++
400 return nil
401 }
402 if err := p.checkAdvance(sec); err != nil {
403 return err
404 }
405 var err error
406 p.off, err = skipResource(p.msg, p.off)
407 if err != nil {
408 return &nestedError{"skipping: " + sectionNames[sec], err}
409 }
410 p.index++
411 return nil
412}
413
414// Question parses a single Question.
415func (p *Parser) Question() (Question, error) {
416 if err := p.checkAdvance(sectionQuestions); err != nil {
417 return Question{}, err
418 }
419 var name Name
420 off, err := name.unpack(p.msg, p.off)
421 if err != nil {
422 return Question{}, &nestedError{"unpacking Question.Name", err}
423 }
424 typ, off, err := unpackType(p.msg, off)
425 if err != nil {
426 return Question{}, &nestedError{"unpacking Question.Type", err}
427 }
428 class, off, err := unpackClass(p.msg, off)
429 if err != nil {
430 return Question{}, &nestedError{"unpacking Question.Class", err}
431 }
432 p.off = off
433 p.index++
434 return Question{name, typ, class}, nil
435}
436
437// AllQuestions parses all Questions.
438func (p *Parser) AllQuestions() ([]Question, error) {
439 qs := make([]Question, 0, p.header.questions)
440 for {
441 q, err := p.Question()
442 if err == ErrSectionDone {
443 return qs, nil
444 }
445 if err != nil {
446 return nil, err
447 }
448 qs = append(qs, q)
449 }
450}
451
452// SkipQuestion skips a single Question.
453func (p *Parser) SkipQuestion() error {
454 if err := p.checkAdvance(sectionQuestions); err != nil {
455 return err
456 }
457 off, err := skipName(p.msg, p.off)
458 if err != nil {
459 return &nestedError{"skipping Question Name", err}
460 }
461 if off, err = skipType(p.msg, off); err != nil {
462 return &nestedError{"skipping Question Type", err}
463 }
464 if off, err = skipClass(p.msg, off); err != nil {
465 return &nestedError{"skipping Question Class", err}
466 }
467 p.off = off
468 p.index++
469 return nil
470}
471
472// SkipAllQuestions skips all Questions.
473func (p *Parser) SkipAllQuestions() error {
474 for {
475 if err := p.SkipQuestion(); err == ErrSectionDone {
476 return nil
477 } else if err != nil {
478 return err
479 }
480 }
481}
482
483// AnswerHeader parses a single Answer ResourceHeader.
484func (p *Parser) AnswerHeader() (ResourceHeader, error) {
485 return p.resourceHeader(sectionAnswers)
486}
487
488// Answer parses a single Answer Resource.
489func (p *Parser) Answer() (Resource, error) {
490 return p.resource(sectionAnswers)
491}
492
493// AllAnswers parses all Answer Resources.
494func (p *Parser) AllAnswers() ([]Resource, error) {
495 as := make([]Resource, 0, p.header.answers)
496 for {
497 a, err := p.Answer()
498 if err == ErrSectionDone {
499 return as, nil
500 }
501 if err != nil {
502 return nil, err
503 }
504 as = append(as, a)
505 }
506}
507
508// SkipAnswer skips a single Answer Resource.
509func (p *Parser) SkipAnswer() error {
510 return p.skipResource(sectionAnswers)
511}
512
513// SkipAllAnswers skips all Answer Resources.
514func (p *Parser) SkipAllAnswers() error {
515 for {
516 if err := p.SkipAnswer(); err == ErrSectionDone {
517 return nil
518 } else if err != nil {
519 return err
520 }
521 }
522}
523
524// AuthorityHeader parses a single Authority ResourceHeader.
525func (p *Parser) AuthorityHeader() (ResourceHeader, error) {
526 return p.resourceHeader(sectionAuthorities)
527}
528
529// Authority parses a single Authority Resource.
530func (p *Parser) Authority() (Resource, error) {
531 return p.resource(sectionAuthorities)
532}
533
534// AllAuthorities parses all Authority Resources.
535func (p *Parser) AllAuthorities() ([]Resource, error) {
536 as := make([]Resource, 0, p.header.authorities)
537 for {
538 a, err := p.Authority()
539 if err == ErrSectionDone {
540 return as, nil
541 }
542 if err != nil {
543 return nil, err
544 }
545 as = append(as, a)
546 }
547}
548
549// SkipAuthority skips a single Authority Resource.
550func (p *Parser) SkipAuthority() error {
551 return p.skipResource(sectionAuthorities)
552}
553
554// SkipAllAuthorities skips all Authority Resources.
555func (p *Parser) SkipAllAuthorities() error {
556 for {
557 if err := p.SkipAuthority(); err == ErrSectionDone {
558 return nil
559 } else if err != nil {
560 return err
561 }
562 }
563}
564
565// AdditionalHeader parses a single Additional ResourceHeader.
566func (p *Parser) AdditionalHeader() (ResourceHeader, error) {
567 return p.resourceHeader(sectionAdditionals)
568}
569
570// Additional parses a single Additional Resource.
571func (p *Parser) Additional() (Resource, error) {
572 return p.resource(sectionAdditionals)
573}
574
575// AllAdditionals parses all Additional Resources.
576func (p *Parser) AllAdditionals() ([]Resource, error) {
577 as := make([]Resource, 0, p.header.additionals)
578 for {
579 a, err := p.Additional()
580 if err == ErrSectionDone {
581 return as, nil
582 }
583 if err != nil {
584 return nil, err
585 }
586 as = append(as, a)
587 }
588}
589
590// SkipAdditional skips a single Additional Resource.
591func (p *Parser) SkipAdditional() error {
592 return p.skipResource(sectionAdditionals)
593}
594
595// SkipAllAdditionals skips all Additional Resources.
596func (p *Parser) SkipAllAdditionals() error {
597 for {
598 if err := p.SkipAdditional(); err == ErrSectionDone {
599 return nil
600 } else if err != nil {
601 return err
602 }
603 }
604}
605
606// CNAMEResource parses a single CNAMEResource.
607//
608// One of the XXXHeader methods must have been called before calling this
609// method.
610func (p *Parser) CNAMEResource() (CNAMEResource, error) {
611 if !p.resHeaderValid || p.resHeader.Type != TypeCNAME {
612 return CNAMEResource{}, ErrNotStarted
613 }
614 r, err := unpackCNAMEResource(p.msg, p.off)
615 if err != nil {
616 return CNAMEResource{}, err
617 }
618 p.off += int(p.resHeader.Length)
619 p.resHeaderValid = false
620 p.index++
621 return r, nil
622}
623
624// MXResource parses a single MXResource.
625//
626// One of the XXXHeader methods must have been called before calling this
627// method.
628func (p *Parser) MXResource() (MXResource, error) {
629 if !p.resHeaderValid || p.resHeader.Type != TypeMX {
630 return MXResource{}, ErrNotStarted
631 }
632 r, err := unpackMXResource(p.msg, p.off)
633 if err != nil {
634 return MXResource{}, err
635 }
636 p.off += int(p.resHeader.Length)
637 p.resHeaderValid = false
638 p.index++
639 return r, nil
640}
641
642// NSResource parses a single NSResource.
643//
644// One of the XXXHeader methods must have been called before calling this
645// method.
646func (p *Parser) NSResource() (NSResource, error) {
647 if !p.resHeaderValid || p.resHeader.Type != TypeNS {
648 return NSResource{}, ErrNotStarted
649 }
650 r, err := unpackNSResource(p.msg, p.off)
651 if err != nil {
652 return NSResource{}, err
653 }
654 p.off += int(p.resHeader.Length)
655 p.resHeaderValid = false
656 p.index++
657 return r, nil
658}
659
660// PTRResource parses a single PTRResource.
661//
662// One of the XXXHeader methods must have been called before calling this
663// method.
664func (p *Parser) PTRResource() (PTRResource, error) {
665 if !p.resHeaderValid || p.resHeader.Type != TypePTR {
666 return PTRResource{}, ErrNotStarted
667 }
668 r, err := unpackPTRResource(p.msg, p.off)
669 if err != nil {
670 return PTRResource{}, err
671 }
672 p.off += int(p.resHeader.Length)
673 p.resHeaderValid = false
674 p.index++
675 return r, nil
676}
677
678// SOAResource parses a single SOAResource.
679//
680// One of the XXXHeader methods must have been called before calling this
681// method.
682func (p *Parser) SOAResource() (SOAResource, error) {
683 if !p.resHeaderValid || p.resHeader.Type != TypeSOA {
684 return SOAResource{}, ErrNotStarted
685 }
686 r, err := unpackSOAResource(p.msg, p.off)
687 if err != nil {
688 return SOAResource{}, err
689 }
690 p.off += int(p.resHeader.Length)
691 p.resHeaderValid = false
692 p.index++
693 return r, nil
694}
695
696// TXTResource parses a single TXTResource.
697//
698// One of the XXXHeader methods must have been called before calling this
699// method.
700func (p *Parser) TXTResource() (TXTResource, error) {
701 if !p.resHeaderValid || p.resHeader.Type != TypeTXT {
702 return TXTResource{}, ErrNotStarted
703 }
704 r, err := unpackTXTResource(p.msg, p.off, p.resHeader.Length)
705 if err != nil {
706 return TXTResource{}, err
707 }
708 p.off += int(p.resHeader.Length)
709 p.resHeaderValid = false
710 p.index++
711 return r, nil
712}
713
714// SRVResource parses a single SRVResource.
715//
716// One of the XXXHeader methods must have been called before calling this
717// method.
718func (p *Parser) SRVResource() (SRVResource, error) {
719 if !p.resHeaderValid || p.resHeader.Type != TypeSRV {
720 return SRVResource{}, ErrNotStarted
721 }
722 r, err := unpackSRVResource(p.msg, p.off)
723 if err != nil {
724 return SRVResource{}, err
725 }
726 p.off += int(p.resHeader.Length)
727 p.resHeaderValid = false
728 p.index++
729 return r, nil
730}
731
732// AResource parses a single AResource.
733//
734// One of the XXXHeader methods must have been called before calling this
735// method.
736func (p *Parser) AResource() (AResource, error) {
737 if !p.resHeaderValid || p.resHeader.Type != TypeA {
738 return AResource{}, ErrNotStarted
739 }
740 r, err := unpackAResource(p.msg, p.off)
741 if err != nil {
742 return AResource{}, err
743 }
744 p.off += int(p.resHeader.Length)
745 p.resHeaderValid = false
746 p.index++
747 return r, nil
748}
749
750// AAAAResource parses a single AAAAResource.
751//
752// One of the XXXHeader methods must have been called before calling this
753// method.
754func (p *Parser) AAAAResource() (AAAAResource, error) {
755 if !p.resHeaderValid || p.resHeader.Type != TypeAAAA {
756 return AAAAResource{}, ErrNotStarted
757 }
758 r, err := unpackAAAAResource(p.msg, p.off)
759 if err != nil {
760 return AAAAResource{}, err
761 }
762 p.off += int(p.resHeader.Length)
763 p.resHeaderValid = false
764 p.index++
765 return r, nil
766}
767
768// Unpack parses a full Message.
769func (m *Message) Unpack(msg []byte) error {
770 var p Parser
771 var err error
772 if m.Header, err = p.Start(msg); err != nil {
773 return err
774 }
775 if m.Questions, err = p.AllQuestions(); err != nil {
776 return err
777 }
778 if m.Answers, err = p.AllAnswers(); err != nil {
779 return err
780 }
781 if m.Authorities, err = p.AllAuthorities(); err != nil {
782 return err
783 }
784 if m.Additionals, err = p.AllAdditionals(); err != nil {
785 return err
786 }
787 return nil
788}
789
790// Pack packs a full Message.
791func (m *Message) Pack() ([]byte, error) {
792 // Validate the lengths. It is very unlikely that anyone will try to
793 // pack more than 65535 of any particular type, but it is possible and
794 // we should fail gracefully.
795 if len(m.Questions) > int(^uint16(0)) {
796 return nil, errTooManyQuestions
797 }
798 if len(m.Answers) > int(^uint16(0)) {
799 return nil, errTooManyAnswers
800 }
801 if len(m.Authorities) > int(^uint16(0)) {
802 return nil, errTooManyAuthorities
803 }
804 if len(m.Additionals) > int(^uint16(0)) {
805 return nil, errTooManyAdditionals
806 }
807
808 var h header
809 h.id, h.bits = m.Header.pack()
810
811 h.questions = uint16(len(m.Questions))
812 h.answers = uint16(len(m.Answers))
813 h.authorities = uint16(len(m.Authorities))
814 h.additionals = uint16(len(m.Additionals))
815
816 msg := make([]byte, 0, packStartingCap)
817
818 msg = h.pack(msg)
819
820 // RFC 1035 allows (but does not require) compression for packing. RFC
821 // 1035 requires unpacking implementations to support compression, so
822 // unconditionally enabling it is fine.
823 //
824 // DNS lookups are typically done over UDP, and RFC 1035 states that UDP
825 // DNS packets can be a maximum of 512 bytes long. Without compression,
826 // many DNS response packets are over this limit, so enabling
827 // compression will help ensure compliance.
828 compression := map[string]int{}
829
830 for i := range m.Questions {
831 var err error
832 if msg, err = m.Questions[i].pack(msg, compression); err != nil {
833 return nil, &nestedError{"packing Question", err}
834 }
835 }
836 for i := range m.Answers {
837 var err error
838 if msg, err = m.Answers[i].pack(msg, compression); err != nil {
839 return nil, &nestedError{"packing Answer", err}
840 }
841 }
842 for i := range m.Authorities {
843 var err error
844 if msg, err = m.Authorities[i].pack(msg, compression); err != nil {
845 return nil, &nestedError{"packing Authority", err}
846 }
847 }
848 for i := range m.Additionals {
849 var err error
850 if msg, err = m.Additionals[i].pack(msg, compression); err != nil {
851 return nil, &nestedError{"packing Additional", err}
852 }
853 }
854
855 return msg, nil
856}
857
858// A Builder allows incrementally packing a DNS message.
859type Builder struct {
860 msg []byte
861 header header
862 section section
863 compression map[string]int
864}
865
866// Start initializes the builder.
867//
868// buf is optional (nil is fine), but if provided, Start takes ownership of buf.
869func (b *Builder) Start(buf []byte, h Header) {
870 b.StartWithoutCompression(buf, h)
871 b.compression = map[string]int{}
872}
873
874// StartWithoutCompression initializes the builder with compression disabled.
875//
876// This avoids compression related allocations, but can result in larger message
877// sizes. Be careful with this mode as it can cause messages to exceed the UDP
878// size limit.
879//
880// buf is optional (nil is fine), but if provided, Start takes ownership of buf.
881func (b *Builder) StartWithoutCompression(buf []byte, h Header) {
882 *b = Builder{msg: buf}
883 b.header.id, b.header.bits = h.pack()
884 if cap(b.msg) < headerLen {
885 b.msg = make([]byte, 0, packStartingCap)
886 }
887 b.msg = b.msg[:headerLen]
888 b.section = sectionHeader
889}
890
891func (b *Builder) startCheck(s section) error {
892 if b.section <= sectionNotStarted {
893 return ErrNotStarted
894 }
895 if b.section > s {
896 return ErrSectionDone
897 }
898 return nil
899}
900
901// StartQuestions prepares the builder for packing Questions.
902func (b *Builder) StartQuestions() error {
903 if err := b.startCheck(sectionQuestions); err != nil {
904 return err
905 }
906 b.section = sectionQuestions
907 return nil
908}
909
910// StartAnswers prepares the builder for packing Answers.
911func (b *Builder) StartAnswers() error {
912 if err := b.startCheck(sectionAnswers); err != nil {
913 return err
914 }
915 b.section = sectionAnswers
916 return nil
917}
918
919// StartAuthorities prepares the builder for packing Authorities.
920func (b *Builder) StartAuthorities() error {
921 if err := b.startCheck(sectionAuthorities); err != nil {
922 return err
923 }
924 b.section = sectionAuthorities
925 return nil
926}
927
928// StartAdditionals prepares the builder for packing Additionals.
929func (b *Builder) StartAdditionals() error {
930 if err := b.startCheck(sectionAdditionals); err != nil {
931 return err
932 }
933 b.section = sectionAdditionals
934 return nil
935}
936
937func (b *Builder) incrementSectionCount() error {
938 var count *uint16
939 var err error
940 switch b.section {
941 case sectionQuestions:
942 count = &b.header.questions
943 err = errTooManyQuestions
944 case sectionAnswers:
945 count = &b.header.answers
946 err = errTooManyAnswers
947 case sectionAuthorities:
948 count = &b.header.authorities
949 err = errTooManyAuthorities
950 case sectionAdditionals:
951 count = &b.header.additionals
952 err = errTooManyAdditionals
953 }
954 if *count == ^uint16(0) {
955 return err
956 }
957 *count++
958 return nil
959}
960
961// Question adds a single Question.
962func (b *Builder) Question(q Question) error {
963 if b.section < sectionQuestions {
964 return ErrNotStarted
965 }
966 if b.section > sectionQuestions {
967 return ErrSectionDone
968 }
969 msg, err := q.pack(b.msg, b.compression)
970 if err != nil {
971 return err
972 }
973 if err := b.incrementSectionCount(); err != nil {
974 return err
975 }
976 b.msg = msg
977 return nil
978}
979
980func (b *Builder) checkResourceSection() error {
981 if b.section < sectionAnswers {
982 return ErrNotStarted
983 }
984 if b.section > sectionAdditionals {
985 return ErrSectionDone
986 }
987 return nil
988}
989
990// CNAMEResource adds a single CNAMEResource.
991func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error {
992 if err := b.checkResourceSection(); err != nil {
993 return err
994 }
995 h.Type = r.realType()
996 msg, length, err := h.pack(b.msg, b.compression)
997 if err != nil {
998 return &nestedError{"ResourceHeader", err}
999 }
1000 preLen := len(msg)
1001 if msg, err = r.pack(msg, b.compression); err != nil {
1002 return &nestedError{"CNAMEResource body", err}
1003 }
1004 if err := h.fixLen(msg, length, preLen); err != nil {
1005 return err
1006 }
1007 if err := b.incrementSectionCount(); err != nil {
1008 return err
1009 }
1010 b.msg = msg
1011 return nil
1012}
1013
1014// MXResource adds a single MXResource.
1015func (b *Builder) MXResource(h ResourceHeader, r MXResource) error {
1016 if err := b.checkResourceSection(); err != nil {
1017 return err
1018 }
1019 h.Type = r.realType()
1020 msg, length, err := h.pack(b.msg, b.compression)
1021 if err != nil {
1022 return &nestedError{"ResourceHeader", err}
1023 }
1024 preLen := len(msg)
1025 if msg, err = r.pack(msg, b.compression); err != nil {
1026 return &nestedError{"MXResource body", err}
1027 }
1028 if err := h.fixLen(msg, length, preLen); err != nil {
1029 return err
1030 }
1031 if err := b.incrementSectionCount(); err != nil {
1032 return err
1033 }
1034 b.msg = msg
1035 return nil
1036}
1037
1038// NSResource adds a single NSResource.
1039func (b *Builder) NSResource(h ResourceHeader, r NSResource) error {
1040 if err := b.checkResourceSection(); err != nil {
1041 return err
1042 }
1043 h.Type = r.realType()
1044 msg, length, err := h.pack(b.msg, b.compression)
1045 if err != nil {
1046 return &nestedError{"ResourceHeader", err}
1047 }
1048 preLen := len(msg)
1049 if msg, err = r.pack(msg, b.compression); err != nil {
1050 return &nestedError{"NSResource body", err}
1051 }
1052 if err := h.fixLen(msg, length, preLen); err != nil {
1053 return err
1054 }
1055 if err := b.incrementSectionCount(); err != nil {
1056 return err
1057 }
1058 b.msg = msg
1059 return nil
1060}
1061
1062// PTRResource adds a single PTRResource.
1063func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error {
1064 if err := b.checkResourceSection(); err != nil {
1065 return err
1066 }
1067 h.Type = r.realType()
1068 msg, length, err := h.pack(b.msg, b.compression)
1069 if err != nil {
1070 return &nestedError{"ResourceHeader", err}
1071 }
1072 preLen := len(msg)
1073 if msg, err = r.pack(msg, b.compression); err != nil {
1074 return &nestedError{"PTRResource body", err}
1075 }
1076 if err := h.fixLen(msg, length, preLen); err != nil {
1077 return err
1078 }
1079 if err := b.incrementSectionCount(); err != nil {
1080 return err
1081 }
1082 b.msg = msg
1083 return nil
1084}
1085
1086// SOAResource adds a single SOAResource.
1087func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error {
1088 if err := b.checkResourceSection(); err != nil {
1089 return err
1090 }
1091 h.Type = r.realType()
1092 msg, length, err := h.pack(b.msg, b.compression)
1093 if err != nil {
1094 return &nestedError{"ResourceHeader", err}
1095 }
1096 preLen := len(msg)
1097 if msg, err = r.pack(msg, b.compression); err != nil {
1098 return &nestedError{"SOAResource body", err}
1099 }
1100 if err := h.fixLen(msg, length, preLen); err != nil {
1101 return err
1102 }
1103 if err := b.incrementSectionCount(); err != nil {
1104 return err
1105 }
1106 b.msg = msg
1107 return nil
1108}
1109
1110// TXTResource adds a single TXTResource.
1111func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error {
1112 if err := b.checkResourceSection(); err != nil {
1113 return err
1114 }
1115 h.Type = r.realType()
1116 msg, length, err := h.pack(b.msg, b.compression)
1117 if err != nil {
1118 return &nestedError{"ResourceHeader", err}
1119 }
1120 preLen := len(msg)
1121 if msg, err = r.pack(msg, b.compression); err != nil {
1122 return &nestedError{"TXTResource body", err}
1123 }
1124 if err := h.fixLen(msg, length, preLen); err != nil {
1125 return err
1126 }
1127 if err := b.incrementSectionCount(); err != nil {
1128 return err
1129 }
1130 b.msg = msg
1131 return nil
1132}
1133
1134// SRVResource adds a single SRVResource.
1135func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error {
1136 if err := b.checkResourceSection(); err != nil {
1137 return err
1138 }
1139 h.Type = r.realType()
1140 msg, length, err := h.pack(b.msg, b.compression)
1141 if err != nil {
1142 return &nestedError{"ResourceHeader", err}
1143 }
1144 preLen := len(msg)
1145 if msg, err = r.pack(msg, b.compression); err != nil {
1146 return &nestedError{"SRVResource body", err}
1147 }
1148 if err := h.fixLen(msg, length, preLen); err != nil {
1149 return err
1150 }
1151 if err := b.incrementSectionCount(); err != nil {
1152 return err
1153 }
1154 b.msg = msg
1155 return nil
1156}
1157
1158// AResource adds a single AResource.
1159func (b *Builder) AResource(h ResourceHeader, r AResource) error {
1160 if err := b.checkResourceSection(); err != nil {
1161 return err
1162 }
1163 h.Type = r.realType()
1164 msg, length, err := h.pack(b.msg, b.compression)
1165 if err != nil {
1166 return &nestedError{"ResourceHeader", err}
1167 }
1168 preLen := len(msg)
1169 if msg, err = r.pack(msg, b.compression); err != nil {
1170 return &nestedError{"AResource body", err}
1171 }
1172 if err := h.fixLen(msg, length, preLen); err != nil {
1173 return err
1174 }
1175 if err := b.incrementSectionCount(); err != nil {
1176 return err
1177 }
1178 b.msg = msg
1179 return nil
1180}
1181
1182// AAAAResource adds a single AAAAResource.
1183func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error {
1184 if err := b.checkResourceSection(); err != nil {
1185 return err
1186 }
1187 h.Type = r.realType()
1188 msg, length, err := h.pack(b.msg, b.compression)
1189 if err != nil {
1190 return &nestedError{"ResourceHeader", err}
1191 }
1192 preLen := len(msg)
1193 if msg, err = r.pack(msg, b.compression); err != nil {
1194 return &nestedError{"AAAAResource body", err}
1195 }
1196 if err := h.fixLen(msg, length, preLen); err != nil {
1197 return err
1198 }
1199 if err := b.incrementSectionCount(); err != nil {
1200 return err
1201 }
1202 b.msg = msg
1203 return nil
1204}
1205
1206// Finish ends message building and generates a binary packet.
1207func (b *Builder) Finish() ([]byte, error) {
1208 if b.section < sectionHeader {
1209 return nil, ErrNotStarted
1210 }
1211 b.section = sectionDone
1212 b.header.pack(b.msg[:0])
1213 return b.msg, nil
1214}
1215
1216// A ResourceHeader is the header of a DNS resource record. There are
1217// many types of DNS resource records, but they all share the same header.
1218type ResourceHeader struct {
1219 // Name is the domain name for which this resource record pertains.
1220 Name Name
1221
1222 // Type is the type of DNS resource record.
1223 //
1224 // This field will be set automatically during packing.
1225 Type Type
1226
1227 // Class is the class of network to which this DNS resource record
1228 // pertains.
1229 Class Class
1230
1231 // TTL is the length of time (measured in seconds) which this resource
1232 // record is valid for (time to live). All Resources in a set should
1233 // have the same TTL (RFC 2181 Section 5.2).
1234 TTL uint32
1235
1236 // Length is the length of data in the resource record after the header.
1237 //
1238 // This field will be set automatically during packing.
1239 Length uint16
1240}
1241
1242// pack packs all of the fields in a ResourceHeader except for the length. The
1243// length bytes are returned as a slice so they can be filled in after the rest
1244// of the Resource has been packed.
1245func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int) (msg []byte, length []byte, err error) {
1246 msg = oldMsg
1247 if msg, err = h.Name.pack(msg, compression); err != nil {
1248 return oldMsg, nil, &nestedError{"Name", err}
1249 }
1250 msg = packType(msg, h.Type)
1251 msg = packClass(msg, h.Class)
1252 msg = packUint32(msg, h.TTL)
1253 lenBegin := len(msg)
1254 msg = packUint16(msg, h.Length)
1255 return msg, msg[lenBegin : lenBegin+uint16Len], nil
1256}
1257
1258func (h *ResourceHeader) unpack(msg []byte, off int) (int, error) {
1259 newOff := off
1260 var err error
1261 if newOff, err = h.Name.unpack(msg, newOff); err != nil {
1262 return off, &nestedError{"Name", err}
1263 }
1264 if h.Type, newOff, err = unpackType(msg, newOff); err != nil {
1265 return off, &nestedError{"Type", err}
1266 }
1267 if h.Class, newOff, err = unpackClass(msg, newOff); err != nil {
1268 return off, &nestedError{"Class", err}
1269 }
1270 if h.TTL, newOff, err = unpackUint32(msg, newOff); err != nil {
1271 return off, &nestedError{"TTL", err}
1272 }
1273 if h.Length, newOff, err = unpackUint16(msg, newOff); err != nil {
1274 return off, &nestedError{"Length", err}
1275 }
1276 return newOff, nil
1277}
1278
1279func (h *ResourceHeader) fixLen(msg []byte, length []byte, preLen int) error {
1280 conLen := len(msg) - preLen
1281 if conLen > int(^uint16(0)) {
1282 return errResTooLong
1283 }
1284
1285 // Fill in the length now that we know how long the content is.
1286 packUint16(length[:0], uint16(conLen))
1287 h.Length = uint16(conLen)
1288
1289 return nil
1290}
1291
1292func skipResource(msg []byte, off int) (int, error) {
1293 newOff, err := skipName(msg, off)
1294 if err != nil {
1295 return off, &nestedError{"Name", err}
1296 }
1297 if newOff, err = skipType(msg, newOff); err != nil {
1298 return off, &nestedError{"Type", err}
1299 }
1300 if newOff, err = skipClass(msg, newOff); err != nil {
1301 return off, &nestedError{"Class", err}
1302 }
1303 if newOff, err = skipUint32(msg, newOff); err != nil {
1304 return off, &nestedError{"TTL", err}
1305 }
1306 length, newOff, err := unpackUint16(msg, newOff)
1307 if err != nil {
1308 return off, &nestedError{"Length", err}
1309 }
1310 if newOff += int(length); newOff > len(msg) {
1311 return off, errResourceLen
1312 }
1313 return newOff, nil
1314}
1315
1316func packUint16(msg []byte, field uint16) []byte {
1317 return append(msg, byte(field>>8), byte(field))
1318}
1319
1320func unpackUint16(msg []byte, off int) (uint16, int, error) {
1321 if off+uint16Len > len(msg) {
1322 return 0, off, errBaseLen
1323 }
1324 return uint16(msg[off])<<8 | uint16(msg[off+1]), off + uint16Len, nil
1325}
1326
1327func skipUint16(msg []byte, off int) (int, error) {
1328 if off+uint16Len > len(msg) {
1329 return off, errBaseLen
1330 }
1331 return off + uint16Len, nil
1332}
1333
1334func packType(msg []byte, field Type) []byte {
1335 return packUint16(msg, uint16(field))
1336}
1337
1338func unpackType(msg []byte, off int) (Type, int, error) {
1339 t, o, err := unpackUint16(msg, off)
1340 return Type(t), o, err
1341}
1342
1343func skipType(msg []byte, off int) (int, error) {
1344 return skipUint16(msg, off)
1345}
1346
1347func packClass(msg []byte, field Class) []byte {
1348 return packUint16(msg, uint16(field))
1349}
1350
1351func unpackClass(msg []byte, off int) (Class, int, error) {
1352 c, o, err := unpackUint16(msg, off)
1353 return Class(c), o, err
1354}
1355
1356func skipClass(msg []byte, off int) (int, error) {
1357 return skipUint16(msg, off)
1358}
1359
1360func packUint32(msg []byte, field uint32) []byte {
1361 return append(
1362 msg,
1363 byte(field>>24),
1364 byte(field>>16),
1365 byte(field>>8),
1366 byte(field),
1367 )
1368}
1369
1370func unpackUint32(msg []byte, off int) (uint32, int, error) {
1371 if off+uint32Len > len(msg) {
1372 return 0, off, errBaseLen
1373 }
1374 v := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
1375 return v, off + uint32Len, nil
1376}
1377
1378func skipUint32(msg []byte, off int) (int, error) {
1379 if off+uint32Len > len(msg) {
1380 return off, errBaseLen
1381 }
1382 return off + uint32Len, nil
1383}
1384
1385func packText(msg []byte, field string) []byte {
1386 for len(field) > 0 {
1387 l := len(field)
1388 if l > 255 {
1389 l = 255
1390 }
1391 msg = append(msg, byte(l))
1392 msg = append(msg, field[:l]...)
1393 field = field[l:]
1394 }
1395 return msg
1396}
1397
1398func unpackText(msg []byte, off int) (string, int, error) {
1399 if off >= len(msg) {
1400 return "", off, errBaseLen
1401 }
1402 beginOff := off + 1
1403 endOff := beginOff + int(msg[off])
1404 if endOff > len(msg) {
1405 return "", off, errCalcLen
1406 }
1407 return string(msg[beginOff:endOff]), endOff, nil
1408}
1409
1410func skipText(msg []byte, off int) (int, error) {
1411 if off >= len(msg) {
1412 return off, errBaseLen
1413 }
1414 endOff := off + 1 + int(msg[off])
1415 if endOff > len(msg) {
1416 return off, errCalcLen
1417 }
1418 return endOff, nil
1419}
1420
1421func packBytes(msg []byte, field []byte) []byte {
1422 return append(msg, field...)
1423}
1424
1425func unpackBytes(msg []byte, off int, field []byte) (int, error) {
1426 newOff := off + len(field)
1427 if newOff > len(msg) {
1428 return off, errBaseLen
1429 }
1430 copy(field, msg[off:newOff])
1431 return newOff, nil
1432}
1433
1434func skipBytes(msg []byte, off int, field []byte) (int, error) {
1435 newOff := off + len(field)
1436 if newOff > len(msg) {
1437 return off, errBaseLen
1438 }
1439 return newOff, nil
1440}
1441
1442const nameLen = 255
1443
1444// A Name is a non-encoded domain name. It is used instead of strings to avoid
1445// allocations.
1446type Name struct {
1447 Data [nameLen]byte
1448 Length uint8
1449}
1450
1451// NewName creates a new Name from a string.
1452func NewName(name string) (Name, error) {
1453 if len([]byte(name)) > nameLen {
1454 return Name{}, errCalcLen
1455 }
1456 n := Name{Length: uint8(len(name))}
1457 copy(n.Data[:], []byte(name))
1458 return n, nil
1459}
1460
1461func (n Name) String() string {
1462 return string(n.Data[:n.Length])
1463}
1464
1465// pack packs a domain name.
1466//
1467// Domain names are a sequence of counted strings split at the dots. They end
1468// with a zero-length string. Compression can be used to reuse domain suffixes.
1469//
1470// The compression map will be updated with new domain suffixes. If compression
1471// is nil, compression will not be used.
1472func (n *Name) pack(msg []byte, compression map[string]int) ([]byte, error) {
1473 oldMsg := msg
1474
1475 // Add a trailing dot to canonicalize name.
1476 if n.Length == 0 || n.Data[n.Length-1] != '.' {
1477 return oldMsg, errNonCanonicalName
1478 }
1479
1480 // Allow root domain.
1481 if n.Data[0] == '.' && n.Length == 1 {
1482 return append(msg, 0), nil
1483 }
1484
1485 // Emit sequence of counted strings, chopping at dots.
1486 for i, begin := 0, 0; i < int(n.Length); i++ {
1487 // Check for the end of the segment.
1488 if n.Data[i] == '.' {
1489 // The two most significant bits have special meaning.
1490 // It isn't allowed for segments to be long enough to
1491 // need them.
1492 if i-begin >= 1<<6 {
1493 return oldMsg, errSegTooLong
1494 }
1495
1496 // Segments must have a non-zero length.
1497 if i-begin == 0 {
1498 return oldMsg, errZeroSegLen
1499 }
1500
1501 msg = append(msg, byte(i-begin))
1502
1503 for j := begin; j < i; j++ {
1504 msg = append(msg, n.Data[j])
1505 }
1506
1507 begin = i + 1
1508 continue
1509 }
1510
1511 // We can only compress domain suffixes starting with a new
1512 // segment. A pointer is two bytes with the two most significant
1513 // bits set to 1 to indicate that it is a pointer.
1514 if (i == 0 || n.Data[i-1] == '.') && compression != nil {
1515 if ptr, ok := compression[string(n.Data[i:])]; ok {
1516 // Hit. Emit a pointer instead of the rest of
1517 // the domain.
1518 return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil
1519 }
1520
1521 // Miss. Add the suffix to the compression table if the
1522 // offset can be stored in the available 14 bytes.
1523 if len(msg) <= int(^uint16(0)>>2) {
1524 compression[string(n.Data[i:])] = len(msg)
1525 }
1526 }
1527 }
1528 return append(msg, 0), nil
1529}
1530
1531// unpack unpacks a domain name.
1532func (n *Name) unpack(msg []byte, off int) (int, error) {
1533 // currOff is the current working offset.
1534 currOff := off
1535
1536 // newOff is the offset where the next record will start. Pointers lead
1537 // to data that belongs to other names and thus doesn't count towards to
1538 // the usage of this name.
1539 newOff := off
1540
1541 // ptr is the number of pointers followed.
1542 var ptr int
1543
1544 // Name is a slice representation of the name data.
1545 name := n.Data[:0]
1546
1547Loop:
1548 for {
1549 if currOff >= len(msg) {
1550 return off, errBaseLen
1551 }
1552 c := int(msg[currOff])
1553 currOff++
1554 switch c & 0xC0 {
1555 case 0x00: // String segment
1556 if c == 0x00 {
1557 // A zero length signals the end of the name.
1558 break Loop
1559 }
1560 endOff := currOff + c
1561 if endOff > len(msg) {
1562 return off, errCalcLen
1563 }
1564 name = append(name, msg[currOff:endOff]...)
1565 name = append(name, '.')
1566 currOff = endOff
1567 case 0xC0: // Pointer
1568 if currOff >= len(msg) {
1569 return off, errInvalidPtr
1570 }
1571 c1 := msg[currOff]
1572 currOff++
1573 if ptr == 0 {
1574 newOff = currOff
1575 }
1576 // Don't follow too many pointers, maybe there's a loop.
1577 if ptr++; ptr > 10 {
1578 return off, errTooManyPtr
1579 }
1580 currOff = (c^0xC0)<<8 | int(c1)
1581 default:
1582 // Prefixes 0x80 and 0x40 are reserved.
1583 return off, errReserved
1584 }
1585 }
1586 if len(name) == 0 {
1587 name = append(name, '.')
1588 }
1589 if len(name) > len(n.Data) {
1590 return off, errCalcLen
1591 }
1592 n.Length = uint8(len(name))
1593 if ptr == 0 {
1594 newOff = currOff
1595 }
1596 return newOff, nil
1597}
1598
1599func skipName(msg []byte, off int) (int, error) {
1600 // newOff is the offset where the next record will start. Pointers lead
1601 // to data that belongs to other names and thus doesn't count towards to
1602 // the usage of this name.
1603 newOff := off
1604
1605Loop:
1606 for {
1607 if newOff >= len(msg) {
1608 return off, errBaseLen
1609 }
1610 c := int(msg[newOff])
1611 newOff++
1612 switch c & 0xC0 {
1613 case 0x00:
1614 if c == 0x00 {
1615 // A zero length signals the end of the name.
1616 break Loop
1617 }
1618 // literal string
1619 newOff += c
1620 if newOff > len(msg) {
1621 return off, errCalcLen
1622 }
1623 case 0xC0:
1624 // Pointer to somewhere else in msg.
1625
1626 // Pointers are two bytes.
1627 newOff++
1628
1629 // Don't follow the pointer as the data here has ended.
1630 break Loop
1631 default:
1632 // Prefixes 0x80 and 0x40 are reserved.
1633 return off, errReserved
1634 }
1635 }
1636
1637 return newOff, nil
1638}
1639
1640// A Question is a DNS query.
1641type Question struct {
1642 Name Name
1643 Type Type
1644 Class Class
1645}
1646
1647func (q *Question) pack(msg []byte, compression map[string]int) ([]byte, error) {
1648 msg, err := q.Name.pack(msg, compression)
1649 if err != nil {
1650 return msg, &nestedError{"Name", err}
1651 }
1652 msg = packType(msg, q.Type)
1653 return packClass(msg, q.Class), nil
1654}
1655
1656func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, int, error) {
1657 var (
1658 r ResourceBody
1659 err error
1660 name string
1661 )
1662 switch hdr.Type {
1663 case TypeA:
1664 var rb AResource
1665 rb, err = unpackAResource(msg, off)
1666 r = &rb
1667 name = "A"
1668 case TypeNS:
1669 var rb NSResource
1670 rb, err = unpackNSResource(msg, off)
1671 r = &rb
1672 name = "NS"
1673 case TypeCNAME:
1674 var rb CNAMEResource
1675 rb, err = unpackCNAMEResource(msg, off)
1676 r = &rb
1677 name = "CNAME"
1678 case TypeSOA:
1679 var rb SOAResource
1680 rb, err = unpackSOAResource(msg, off)
1681 r = &rb
1682 name = "SOA"
1683 case TypePTR:
1684 var rb PTRResource
1685 rb, err = unpackPTRResource(msg, off)
1686 r = &rb
1687 name = "PTR"
1688 case TypeMX:
1689 var rb MXResource
1690 rb, err = unpackMXResource(msg, off)
1691 r = &rb
1692 name = "MX"
1693 case TypeTXT:
1694 var rb TXTResource
1695 rb, err = unpackTXTResource(msg, off, hdr.Length)
1696 r = &rb
1697 name = "TXT"
1698 case TypeAAAA:
1699 var rb AAAAResource
1700 rb, err = unpackAAAAResource(msg, off)
1701 r = &rb
1702 name = "AAAA"
1703 case TypeSRV:
1704 var rb SRVResource
1705 rb, err = unpackSRVResource(msg, off)
1706 r = &rb
1707 name = "SRV"
1708 }
1709 if err != nil {
1710 return nil, off, &nestedError{name + " record", err}
1711 }
1712 if r == nil {
1713 return nil, off, errors.New("invalid resource type: " + string(hdr.Type+'0'))
1714 }
1715 return r, off + int(hdr.Length), nil
1716}
1717
1718// A CNAMEResource is a CNAME Resource record.
1719type CNAMEResource struct {
1720 CNAME Name
1721}
1722
1723func (r *CNAMEResource) realType() Type {
1724 return TypeCNAME
1725}
1726
1727func (r *CNAMEResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1728 return r.CNAME.pack(msg, compression)
1729}
1730
1731func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) {
1732 var cname Name
1733 if _, err := cname.unpack(msg, off); err != nil {
1734 return CNAMEResource{}, err
1735 }
1736 return CNAMEResource{cname}, nil
1737}
1738
1739// An MXResource is an MX Resource record.
1740type MXResource struct {
1741 Pref uint16
1742 MX Name
1743}
1744
1745func (r *MXResource) realType() Type {
1746 return TypeMX
1747}
1748
1749func (r *MXResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1750 oldMsg := msg
1751 msg = packUint16(msg, r.Pref)
1752 msg, err := r.MX.pack(msg, compression)
1753 if err != nil {
1754 return oldMsg, &nestedError{"MXResource.MX", err}
1755 }
1756 return msg, nil
1757}
1758
1759func unpackMXResource(msg []byte, off int) (MXResource, error) {
1760 pref, off, err := unpackUint16(msg, off)
1761 if err != nil {
1762 return MXResource{}, &nestedError{"Pref", err}
1763 }
1764 var mx Name
1765 if _, err := mx.unpack(msg, off); err != nil {
1766 return MXResource{}, &nestedError{"MX", err}
1767 }
1768 return MXResource{pref, mx}, nil
1769}
1770
1771// An NSResource is an NS Resource record.
1772type NSResource struct {
1773 NS Name
1774}
1775
1776func (r *NSResource) realType() Type {
1777 return TypeNS
1778}
1779
1780func (r *NSResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1781 return r.NS.pack(msg, compression)
1782}
1783
1784func unpackNSResource(msg []byte, off int) (NSResource, error) {
1785 var ns Name
1786 if _, err := ns.unpack(msg, off); err != nil {
1787 return NSResource{}, err
1788 }
1789 return NSResource{ns}, nil
1790}
1791
1792// A PTRResource is a PTR Resource record.
1793type PTRResource struct {
1794 PTR Name
1795}
1796
1797func (r *PTRResource) realType() Type {
1798 return TypePTR
1799}
1800
1801func (r *PTRResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1802 return r.PTR.pack(msg, compression)
1803}
1804
1805func unpackPTRResource(msg []byte, off int) (PTRResource, error) {
1806 var ptr Name
1807 if _, err := ptr.unpack(msg, off); err != nil {
1808 return PTRResource{}, err
1809 }
1810 return PTRResource{ptr}, nil
1811}
1812
1813// An SOAResource is an SOA Resource record.
1814type SOAResource struct {
1815 NS Name
1816 MBox Name
1817 Serial uint32
1818 Refresh uint32
1819 Retry uint32
1820 Expire uint32
1821
1822 // MinTTL the is the default TTL of Resources records which did not
1823 // contain a TTL value and the TTL of negative responses. (RFC 2308
1824 // Section 4)
1825 MinTTL uint32
1826}
1827
1828func (r *SOAResource) realType() Type {
1829 return TypeSOA
1830}
1831
1832func (r *SOAResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1833 oldMsg := msg
1834 msg, err := r.NS.pack(msg, compression)
1835 if err != nil {
1836 return oldMsg, &nestedError{"SOAResource.NS", err}
1837 }
1838 msg, err = r.MBox.pack(msg, compression)
1839 if err != nil {
1840 return oldMsg, &nestedError{"SOAResource.MBox", err}
1841 }
1842 msg = packUint32(msg, r.Serial)
1843 msg = packUint32(msg, r.Refresh)
1844 msg = packUint32(msg, r.Retry)
1845 msg = packUint32(msg, r.Expire)
1846 return packUint32(msg, r.MinTTL), nil
1847}
1848
1849func unpackSOAResource(msg []byte, off int) (SOAResource, error) {
1850 var ns Name
1851 off, err := ns.unpack(msg, off)
1852 if err != nil {
1853 return SOAResource{}, &nestedError{"NS", err}
1854 }
1855 var mbox Name
1856 if off, err = mbox.unpack(msg, off); err != nil {
1857 return SOAResource{}, &nestedError{"MBox", err}
1858 }
1859 serial, off, err := unpackUint32(msg, off)
1860 if err != nil {
1861 return SOAResource{}, &nestedError{"Serial", err}
1862 }
1863 refresh, off, err := unpackUint32(msg, off)
1864 if err != nil {
1865 return SOAResource{}, &nestedError{"Refresh", err}
1866 }
1867 retry, off, err := unpackUint32(msg, off)
1868 if err != nil {
1869 return SOAResource{}, &nestedError{"Retry", err}
1870 }
1871 expire, off, err := unpackUint32(msg, off)
1872 if err != nil {
1873 return SOAResource{}, &nestedError{"Expire", err}
1874 }
1875 minTTL, _, err := unpackUint32(msg, off)
1876 if err != nil {
1877 return SOAResource{}, &nestedError{"MinTTL", err}
1878 }
1879 return SOAResource{ns, mbox, serial, refresh, retry, expire, minTTL}, nil
1880}
1881
1882// A TXTResource is a TXT Resource record.
1883type TXTResource struct {
1884 Txt string // Not a domain name.
1885}
1886
1887func (r *TXTResource) realType() Type {
1888 return TypeTXT
1889}
1890
1891func (r *TXTResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1892 return packText(msg, r.Txt), nil
1893}
1894
1895func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) {
1896 var txt string
1897 for n := uint16(0); n < length; {
1898 var t string
1899 var err error
1900 if t, off, err = unpackText(msg, off); err != nil {
1901 return TXTResource{}, &nestedError{"text", err}
1902 }
1903 // Check if we got too many bytes.
1904 if length-n < uint16(len(t))+1 {
1905 return TXTResource{}, errCalcLen
1906 }
1907 n += uint16(len(t)) + 1
1908 txt += t
1909 }
1910 return TXTResource{txt}, nil
1911}
1912
1913// An SRVResource is an SRV Resource record.
1914type SRVResource struct {
1915 Priority uint16
1916 Weight uint16
1917 Port uint16
1918 Target Name // Not compressed as per RFC 2782.
1919}
1920
1921func (r *SRVResource) realType() Type {
1922 return TypeSRV
1923}
1924
1925func (r *SRVResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1926 oldMsg := msg
1927 msg = packUint16(msg, r.Priority)
1928 msg = packUint16(msg, r.Weight)
1929 msg = packUint16(msg, r.Port)
1930 msg, err := r.Target.pack(msg, nil)
1931 if err != nil {
1932 return oldMsg, &nestedError{"SRVResource.Target", err}
1933 }
1934 return msg, nil
1935}
1936
1937func unpackSRVResource(msg []byte, off int) (SRVResource, error) {
1938 priority, off, err := unpackUint16(msg, off)
1939 if err != nil {
1940 return SRVResource{}, &nestedError{"Priority", err}
1941 }
1942 weight, off, err := unpackUint16(msg, off)
1943 if err != nil {
1944 return SRVResource{}, &nestedError{"Weight", err}
1945 }
1946 port, off, err := unpackUint16(msg, off)
1947 if err != nil {
1948 return SRVResource{}, &nestedError{"Port", err}
1949 }
1950 var target Name
1951 if _, err := target.unpack(msg, off); err != nil {
1952 return SRVResource{}, &nestedError{"Target", err}
1953 }
1954 return SRVResource{priority, weight, port, target}, nil
1955}
1956
1957// An AResource is an A Resource record.
1958type AResource struct {
1959 A [4]byte
1960}
1961
1962func (r *AResource) realType() Type {
1963 return TypeA
1964}
1965
1966func (r *AResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1967 return packBytes(msg, r.A[:]), nil
1968}
1969
1970func unpackAResource(msg []byte, off int) (AResource, error) {
1971 var a [4]byte
1972 if _, err := unpackBytes(msg, off, a[:]); err != nil {
1973 return AResource{}, err
1974 }
1975 return AResource{a}, nil
1976}
1977
1978// An AAAAResource is an AAAA Resource record.
1979type AAAAResource struct {
1980 AAAA [16]byte
1981}
1982
1983func (r *AAAAResource) realType() Type {
1984 return TypeAAAA
1985}
1986
1987func (r *AAAAResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
1988 return packBytes(msg, r.AAAA[:]), nil
1989}
1990
1991func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) {
1992 var aaaa [16]byte
1993 if _, err := unpackBytes(msg, off, aaaa[:]); err != nil {
1994 return AAAAResource{}, err
1995 }
1996 return AAAAResource{aaaa}, nil
1997}