Source file src/pkg/vendor/golang.org/x/net/dns/dnsmessage/message.go
1
2
3
4
5
6
7
8
9
10
11
12
13 package dnsmessage
14
15 import (
16 "errors"
17 )
18
19
20
21
22 type Type uint16
23
24 const (
25
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
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
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
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
80 type Class uint16
81
82 const (
83
84 ClassINET Class = 1
85 ClassCSNET Class = 2
86 ClassCHAOS Class = 3
87 ClassHESIOD Class = 4
88
89
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
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
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
118 type OpCode uint16
119
120
121 func (o OpCode) GoString() string {
122 return printUint16(uint16(o))
123 }
124
125
126 type RCode uint16
127
128 const (
129
130 RCodeSuccess RCode = 0
131 RCodeFormatError RCode = 1
132 RCodeServerFailure RCode = 2
133 RCodeNameError RCode = 3
134 RCodeNotImplemented RCode = 4
135 RCodeRefused RCode = 5
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
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
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 := make([]byte, 0, 5*len(b))
188 buf = printUint8Bytes(buf, uint8(b[0]))
189 for _, n := range b[1:] {
190 buf = append(buf, ',', ' ')
191 buf = printUint8Bytes(buf, uint8(n))
192 }
193 return string(buf)
194 }
195
196 const hexDigits = "0123456789abcdef"
197
198 func printString(str []byte) string {
199 buf := make([]byte, 0, len(str))
200 for i := 0; i < len(str); i++ {
201 c := str[i]
202 if c == '.' || c == '-' || c == ' ' ||
203 'A' <= c && c <= 'Z' ||
204 'a' <= c && c <= 'z' ||
205 '0' <= c && c <= '9' {
206 buf = append(buf, c)
207 continue
208 }
209
210 upper := c >> 4
211 lower := (c << 4) >> 4
212 buf = append(
213 buf,
214 '\\',
215 'x',
216 hexDigits[upper],
217 hexDigits[lower],
218 )
219 }
220 return string(buf)
221 }
222
223 func printUint16(i uint16) string {
224 return printUint32(uint32(i))
225 }
226
227 func printUint32(i uint32) string {
228
229 buf := make([]byte, 10)
230 for b, d := buf, uint32(1000000000); d > 0; d /= 10 {
231 b[0] = byte(i/d%10 + '0')
232 if b[0] == '0' && len(b) == len(buf) && len(buf) > 1 {
233 buf = buf[1:]
234 }
235 b = b[1:]
236 i %= d
237 }
238 return string(buf)
239 }
240
241 func printBool(b bool) string {
242 if b {
243 return "true"
244 }
245 return "false"
246 }
247
248 var (
249
250
251
252 ErrNotStarted = errors.New("parsing/packing of this type isn't available yet")
253
254
255
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 errNilResouceBody = errors.New("nil resource body")
264 errResourceLen = errors.New("insufficient data for resource body length")
265 errSegTooLong = errors.New("segment length too long")
266 errZeroSegLen = errors.New("zero length segment")
267 errResTooLong = errors.New("resource length too long")
268 errTooManyQuestions = errors.New("too many Questions to pack (>65535)")
269 errTooManyAnswers = errors.New("too many Answers to pack (>65535)")
270 errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
271 errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
272 errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)")
273 errStringTooLong = errors.New("character string exceeds maximum length (255)")
274 errCompressedSRV = errors.New("compressed name in SRV resource data")
275 )
276
277
278 const (
279
280
281
282
283
284 packStartingCap = 512
285
286
287 uint16Len = 2
288
289
290 uint32Len = 4
291
292
293
294
295 headerLen = 6 * uint16Len
296 )
297
298 type nestedError struct {
299
300 s string
301
302
303 err error
304 }
305
306
307 func (e *nestedError) Error() string {
308 return e.s + ": " + e.err.Error()
309 }
310
311
312 type Header struct {
313 ID uint16
314 Response bool
315 OpCode OpCode
316 Authoritative bool
317 Truncated bool
318 RecursionDesired bool
319 RecursionAvailable bool
320 RCode RCode
321 }
322
323 func (m *Header) pack() (id uint16, bits uint16) {
324 id = m.ID
325 bits = uint16(m.OpCode)<<11 | uint16(m.RCode)
326 if m.RecursionAvailable {
327 bits |= headerBitRA
328 }
329 if m.RecursionDesired {
330 bits |= headerBitRD
331 }
332 if m.Truncated {
333 bits |= headerBitTC
334 }
335 if m.Authoritative {
336 bits |= headerBitAA
337 }
338 if m.Response {
339 bits |= headerBitQR
340 }
341 return
342 }
343
344
345 func (m *Header) GoString() string {
346 return "dnsmessage.Header{" +
347 "ID: " + printUint16(m.ID) + ", " +
348 "Response: " + printBool(m.Response) + ", " +
349 "OpCode: " + m.OpCode.GoString() + ", " +
350 "Authoritative: " + printBool(m.Authoritative) + ", " +
351 "Truncated: " + printBool(m.Truncated) + ", " +
352 "RecursionDesired: " + printBool(m.RecursionDesired) + ", " +
353 "RecursionAvailable: " + printBool(m.RecursionAvailable) + ", " +
354 "RCode: " + m.RCode.GoString() + "}"
355 }
356
357
358 type Message struct {
359 Header
360 Questions []Question
361 Answers []Resource
362 Authorities []Resource
363 Additionals []Resource
364 }
365
366 type section uint8
367
368 const (
369 sectionNotStarted section = iota
370 sectionHeader
371 sectionQuestions
372 sectionAnswers
373 sectionAuthorities
374 sectionAdditionals
375 sectionDone
376
377 headerBitQR = 1 << 15
378 headerBitAA = 1 << 10
379 headerBitTC = 1 << 9
380 headerBitRD = 1 << 8
381 headerBitRA = 1 << 7
382 )
383
384 var sectionNames = map[section]string{
385 sectionHeader: "header",
386 sectionQuestions: "Question",
387 sectionAnswers: "Answer",
388 sectionAuthorities: "Authority",
389 sectionAdditionals: "Additional",
390 }
391
392
393 type header struct {
394 id uint16
395 bits uint16
396 questions uint16
397 answers uint16
398 authorities uint16
399 additionals uint16
400 }
401
402 func (h *header) count(sec section) uint16 {
403 switch sec {
404 case sectionQuestions:
405 return h.questions
406 case sectionAnswers:
407 return h.answers
408 case sectionAuthorities:
409 return h.authorities
410 case sectionAdditionals:
411 return h.additionals
412 }
413 return 0
414 }
415
416
417 func (h *header) pack(msg []byte) []byte {
418 msg = packUint16(msg, h.id)
419 msg = packUint16(msg, h.bits)
420 msg = packUint16(msg, h.questions)
421 msg = packUint16(msg, h.answers)
422 msg = packUint16(msg, h.authorities)
423 return packUint16(msg, h.additionals)
424 }
425
426 func (h *header) unpack(msg []byte, off int) (int, error) {
427 newOff := off
428 var err error
429 if h.id, newOff, err = unpackUint16(msg, newOff); err != nil {
430 return off, &nestedError{"id", err}
431 }
432 if h.bits, newOff, err = unpackUint16(msg, newOff); err != nil {
433 return off, &nestedError{"bits", err}
434 }
435 if h.questions, newOff, err = unpackUint16(msg, newOff); err != nil {
436 return off, &nestedError{"questions", err}
437 }
438 if h.answers, newOff, err = unpackUint16(msg, newOff); err != nil {
439 return off, &nestedError{"answers", err}
440 }
441 if h.authorities, newOff, err = unpackUint16(msg, newOff); err != nil {
442 return off, &nestedError{"authorities", err}
443 }
444 if h.additionals, newOff, err = unpackUint16(msg, newOff); err != nil {
445 return off, &nestedError{"additionals", err}
446 }
447 return newOff, nil
448 }
449
450 func (h *header) header() Header {
451 return Header{
452 ID: h.id,
453 Response: (h.bits & headerBitQR) != 0,
454 OpCode: OpCode(h.bits>>11) & 0xF,
455 Authoritative: (h.bits & headerBitAA) != 0,
456 Truncated: (h.bits & headerBitTC) != 0,
457 RecursionDesired: (h.bits & headerBitRD) != 0,
458 RecursionAvailable: (h.bits & headerBitRA) != 0,
459 RCode: RCode(h.bits & 0xF),
460 }
461 }
462
463
464 type Resource struct {
465 Header ResourceHeader
466 Body ResourceBody
467 }
468
469 func (r *Resource) GoString() string {
470 return "dnsmessage.Resource{" +
471 "Header: " + r.Header.GoString() +
472 ", Body: &" + r.Body.GoString() +
473 "}"
474 }
475
476
477 type ResourceBody interface {
478
479 pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error)
480
481
482
483 realType() Type
484
485
486 GoString() string
487 }
488
489
490 func (r *Resource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
491 if r.Body == nil {
492 return msg, errNilResouceBody
493 }
494 oldMsg := msg
495 r.Header.Type = r.Body.realType()
496 msg, lenOff, err := r.Header.pack(msg, compression, compressionOff)
497 if err != nil {
498 return msg, &nestedError{"ResourceHeader", err}
499 }
500 preLen := len(msg)
501 msg, err = r.Body.pack(msg, compression, compressionOff)
502 if err != nil {
503 return msg, &nestedError{"content", err}
504 }
505 if err := r.Header.fixLen(msg, lenOff, preLen); err != nil {
506 return oldMsg, err
507 }
508 return msg, nil
509 }
510
511
512
513
514
515
516
517
518
519
520
521
522
523 type Parser struct {
524 msg []byte
525 header header
526
527 section section
528 off int
529 index int
530 resHeaderValid bool
531 resHeader ResourceHeader
532 }
533
534
535 func (p *Parser) Start(msg []byte) (Header, error) {
536 if p.msg != nil {
537 *p = Parser{}
538 }
539 p.msg = msg
540 var err error
541 if p.off, err = p.header.unpack(msg, 0); err != nil {
542 return Header{}, &nestedError{"unpacking header", err}
543 }
544 p.section = sectionQuestions
545 return p.header.header(), nil
546 }
547
548 func (p *Parser) checkAdvance(sec section) error {
549 if p.section < sec {
550 return ErrNotStarted
551 }
552 if p.section > sec {
553 return ErrSectionDone
554 }
555 p.resHeaderValid = false
556 if p.index == int(p.header.count(sec)) {
557 p.index = 0
558 p.section++
559 return ErrSectionDone
560 }
561 return nil
562 }
563
564 func (p *Parser) resource(sec section) (Resource, error) {
565 var r Resource
566 var err error
567 r.Header, err = p.resourceHeader(sec)
568 if err != nil {
569 return r, err
570 }
571 p.resHeaderValid = false
572 r.Body, p.off, err = unpackResourceBody(p.msg, p.off, r.Header)
573 if err != nil {
574 return Resource{}, &nestedError{"unpacking " + sectionNames[sec], err}
575 }
576 p.index++
577 return r, nil
578 }
579
580 func (p *Parser) resourceHeader(sec section) (ResourceHeader, error) {
581 if p.resHeaderValid {
582 return p.resHeader, nil
583 }
584 if err := p.checkAdvance(sec); err != nil {
585 return ResourceHeader{}, err
586 }
587 var hdr ResourceHeader
588 off, err := hdr.unpack(p.msg, p.off)
589 if err != nil {
590 return ResourceHeader{}, err
591 }
592 p.resHeaderValid = true
593 p.resHeader = hdr
594 p.off = off
595 return hdr, nil
596 }
597
598 func (p *Parser) skipResource(sec section) error {
599 if p.resHeaderValid {
600 newOff := p.off + int(p.resHeader.Length)
601 if newOff > len(p.msg) {
602 return errResourceLen
603 }
604 p.off = newOff
605 p.resHeaderValid = false
606 p.index++
607 return nil
608 }
609 if err := p.checkAdvance(sec); err != nil {
610 return err
611 }
612 var err error
613 p.off, err = skipResource(p.msg, p.off)
614 if err != nil {
615 return &nestedError{"skipping: " + sectionNames[sec], err}
616 }
617 p.index++
618 return nil
619 }
620
621
622 func (p *Parser) Question() (Question, error) {
623 if err := p.checkAdvance(sectionQuestions); err != nil {
624 return Question{}, err
625 }
626 var name Name
627 off, err := name.unpack(p.msg, p.off)
628 if err != nil {
629 return Question{}, &nestedError{"unpacking Question.Name", err}
630 }
631 typ, off, err := unpackType(p.msg, off)
632 if err != nil {
633 return Question{}, &nestedError{"unpacking Question.Type", err}
634 }
635 class, off, err := unpackClass(p.msg, off)
636 if err != nil {
637 return Question{}, &nestedError{"unpacking Question.Class", err}
638 }
639 p.off = off
640 p.index++
641 return Question{name, typ, class}, nil
642 }
643
644
645 func (p *Parser) AllQuestions() ([]Question, error) {
646
647
648
649
650
651
652 qs := []Question{}
653 for {
654 q, err := p.Question()
655 if err == ErrSectionDone {
656 return qs, nil
657 }
658 if err != nil {
659 return nil, err
660 }
661 qs = append(qs, q)
662 }
663 }
664
665
666 func (p *Parser) SkipQuestion() error {
667 if err := p.checkAdvance(sectionQuestions); err != nil {
668 return err
669 }
670 off, err := skipName(p.msg, p.off)
671 if err != nil {
672 return &nestedError{"skipping Question Name", err}
673 }
674 if off, err = skipType(p.msg, off); err != nil {
675 return &nestedError{"skipping Question Type", err}
676 }
677 if off, err = skipClass(p.msg, off); err != nil {
678 return &nestedError{"skipping Question Class", err}
679 }
680 p.off = off
681 p.index++
682 return nil
683 }
684
685
686 func (p *Parser) SkipAllQuestions() error {
687 for {
688 if err := p.SkipQuestion(); err == ErrSectionDone {
689 return nil
690 } else if err != nil {
691 return err
692 }
693 }
694 }
695
696
697 func (p *Parser) AnswerHeader() (ResourceHeader, error) {
698 return p.resourceHeader(sectionAnswers)
699 }
700
701
702 func (p *Parser) Answer() (Resource, error) {
703 return p.resource(sectionAnswers)
704 }
705
706
707 func (p *Parser) AllAnswers() ([]Resource, error) {
708
709
710
711
712
713 n := int(p.header.answers)
714 if n > 20 {
715 n = 20
716 }
717 as := make([]Resource, 0, n)
718 for {
719 a, err := p.Answer()
720 if err == ErrSectionDone {
721 return as, nil
722 }
723 if err != nil {
724 return nil, err
725 }
726 as = append(as, a)
727 }
728 }
729
730
731 func (p *Parser) SkipAnswer() error {
732 return p.skipResource(sectionAnswers)
733 }
734
735
736 func (p *Parser) SkipAllAnswers() error {
737 for {
738 if err := p.SkipAnswer(); err == ErrSectionDone {
739 return nil
740 } else if err != nil {
741 return err
742 }
743 }
744 }
745
746
747 func (p *Parser) AuthorityHeader() (ResourceHeader, error) {
748 return p.resourceHeader(sectionAuthorities)
749 }
750
751
752 func (p *Parser) Authority() (Resource, error) {
753 return p.resource(sectionAuthorities)
754 }
755
756
757 func (p *Parser) AllAuthorities() ([]Resource, error) {
758
759
760
761
762
763 n := int(p.header.authorities)
764 if n > 10 {
765 n = 10
766 }
767 as := make([]Resource, 0, n)
768 for {
769 a, err := p.Authority()
770 if err == ErrSectionDone {
771 return as, nil
772 }
773 if err != nil {
774 return nil, err
775 }
776 as = append(as, a)
777 }
778 }
779
780
781 func (p *Parser) SkipAuthority() error {
782 return p.skipResource(sectionAuthorities)
783 }
784
785
786 func (p *Parser) SkipAllAuthorities() error {
787 for {
788 if err := p.SkipAuthority(); err == ErrSectionDone {
789 return nil
790 } else if err != nil {
791 return err
792 }
793 }
794 }
795
796
797 func (p *Parser) AdditionalHeader() (ResourceHeader, error) {
798 return p.resourceHeader(sectionAdditionals)
799 }
800
801
802 func (p *Parser) Additional() (Resource, error) {
803 return p.resource(sectionAdditionals)
804 }
805
806
807 func (p *Parser) AllAdditionals() ([]Resource, error) {
808
809
810
811
812
813 n := int(p.header.additionals)
814 if n > 10 {
815 n = 10
816 }
817 as := make([]Resource, 0, n)
818 for {
819 a, err := p.Additional()
820 if err == ErrSectionDone {
821 return as, nil
822 }
823 if err != nil {
824 return nil, err
825 }
826 as = append(as, a)
827 }
828 }
829
830
831 func (p *Parser) SkipAdditional() error {
832 return p.skipResource(sectionAdditionals)
833 }
834
835
836 func (p *Parser) SkipAllAdditionals() error {
837 for {
838 if err := p.SkipAdditional(); err == ErrSectionDone {
839 return nil
840 } else if err != nil {
841 return err
842 }
843 }
844 }
845
846
847
848
849
850 func (p *Parser) CNAMEResource() (CNAMEResource, error) {
851 if !p.resHeaderValid || p.resHeader.Type != TypeCNAME {
852 return CNAMEResource{}, ErrNotStarted
853 }
854 r, err := unpackCNAMEResource(p.msg, p.off)
855 if err != nil {
856 return CNAMEResource{}, err
857 }
858 p.off += int(p.resHeader.Length)
859 p.resHeaderValid = false
860 p.index++
861 return r, nil
862 }
863
864
865
866
867
868 func (p *Parser) MXResource() (MXResource, error) {
869 if !p.resHeaderValid || p.resHeader.Type != TypeMX {
870 return MXResource{}, ErrNotStarted
871 }
872 r, err := unpackMXResource(p.msg, p.off)
873 if err != nil {
874 return MXResource{}, err
875 }
876 p.off += int(p.resHeader.Length)
877 p.resHeaderValid = false
878 p.index++
879 return r, nil
880 }
881
882
883
884
885
886 func (p *Parser) NSResource() (NSResource, error) {
887 if !p.resHeaderValid || p.resHeader.Type != TypeNS {
888 return NSResource{}, ErrNotStarted
889 }
890 r, err := unpackNSResource(p.msg, p.off)
891 if err != nil {
892 return NSResource{}, err
893 }
894 p.off += int(p.resHeader.Length)
895 p.resHeaderValid = false
896 p.index++
897 return r, nil
898 }
899
900
901
902
903
904 func (p *Parser) PTRResource() (PTRResource, error) {
905 if !p.resHeaderValid || p.resHeader.Type != TypePTR {
906 return PTRResource{}, ErrNotStarted
907 }
908 r, err := unpackPTRResource(p.msg, p.off)
909 if err != nil {
910 return PTRResource{}, err
911 }
912 p.off += int(p.resHeader.Length)
913 p.resHeaderValid = false
914 p.index++
915 return r, nil
916 }
917
918
919
920
921
922 func (p *Parser) SOAResource() (SOAResource, error) {
923 if !p.resHeaderValid || p.resHeader.Type != TypeSOA {
924 return SOAResource{}, ErrNotStarted
925 }
926 r, err := unpackSOAResource(p.msg, p.off)
927 if err != nil {
928 return SOAResource{}, err
929 }
930 p.off += int(p.resHeader.Length)
931 p.resHeaderValid = false
932 p.index++
933 return r, nil
934 }
935
936
937
938
939
940 func (p *Parser) TXTResource() (TXTResource, error) {
941 if !p.resHeaderValid || p.resHeader.Type != TypeTXT {
942 return TXTResource{}, ErrNotStarted
943 }
944 r, err := unpackTXTResource(p.msg, p.off, p.resHeader.Length)
945 if err != nil {
946 return TXTResource{}, err
947 }
948 p.off += int(p.resHeader.Length)
949 p.resHeaderValid = false
950 p.index++
951 return r, nil
952 }
953
954
955
956
957
958 func (p *Parser) SRVResource() (SRVResource, error) {
959 if !p.resHeaderValid || p.resHeader.Type != TypeSRV {
960 return SRVResource{}, ErrNotStarted
961 }
962 r, err := unpackSRVResource(p.msg, p.off)
963 if err != nil {
964 return SRVResource{}, err
965 }
966 p.off += int(p.resHeader.Length)
967 p.resHeaderValid = false
968 p.index++
969 return r, nil
970 }
971
972
973
974
975
976 func (p *Parser) AResource() (AResource, error) {
977 if !p.resHeaderValid || p.resHeader.Type != TypeA {
978 return AResource{}, ErrNotStarted
979 }
980 r, err := unpackAResource(p.msg, p.off)
981 if err != nil {
982 return AResource{}, err
983 }
984 p.off += int(p.resHeader.Length)
985 p.resHeaderValid = false
986 p.index++
987 return r, nil
988 }
989
990
991
992
993
994 func (p *Parser) AAAAResource() (AAAAResource, error) {
995 if !p.resHeaderValid || p.resHeader.Type != TypeAAAA {
996 return AAAAResource{}, ErrNotStarted
997 }
998 r, err := unpackAAAAResource(p.msg, p.off)
999 if err != nil {
1000 return AAAAResource{}, err
1001 }
1002 p.off += int(p.resHeader.Length)
1003 p.resHeaderValid = false
1004 p.index++
1005 return r, nil
1006 }
1007
1008
1009
1010
1011
1012 func (p *Parser) OPTResource() (OPTResource, error) {
1013 if !p.resHeaderValid || p.resHeader.Type != TypeOPT {
1014 return OPTResource{}, ErrNotStarted
1015 }
1016 r, err := unpackOPTResource(p.msg, p.off, p.resHeader.Length)
1017 if err != nil {
1018 return OPTResource{}, err
1019 }
1020 p.off += int(p.resHeader.Length)
1021 p.resHeaderValid = false
1022 p.index++
1023 return r, nil
1024 }
1025
1026
1027 func (m *Message) Unpack(msg []byte) error {
1028 var p Parser
1029 var err error
1030 if m.Header, err = p.Start(msg); err != nil {
1031 return err
1032 }
1033 if m.Questions, err = p.AllQuestions(); err != nil {
1034 return err
1035 }
1036 if m.Answers, err = p.AllAnswers(); err != nil {
1037 return err
1038 }
1039 if m.Authorities, err = p.AllAuthorities(); err != nil {
1040 return err
1041 }
1042 if m.Additionals, err = p.AllAdditionals(); err != nil {
1043 return err
1044 }
1045 return nil
1046 }
1047
1048
1049 func (m *Message) Pack() ([]byte, error) {
1050 return m.AppendPack(make([]byte, 0, packStartingCap))
1051 }
1052
1053
1054
1055 func (m *Message) AppendPack(b []byte) ([]byte, error) {
1056
1057
1058
1059 if len(m.Questions) > int(^uint16(0)) {
1060 return nil, errTooManyQuestions
1061 }
1062 if len(m.Answers) > int(^uint16(0)) {
1063 return nil, errTooManyAnswers
1064 }
1065 if len(m.Authorities) > int(^uint16(0)) {
1066 return nil, errTooManyAuthorities
1067 }
1068 if len(m.Additionals) > int(^uint16(0)) {
1069 return nil, errTooManyAdditionals
1070 }
1071
1072 var h header
1073 h.id, h.bits = m.Header.pack()
1074
1075 h.questions = uint16(len(m.Questions))
1076 h.answers = uint16(len(m.Answers))
1077 h.authorities = uint16(len(m.Authorities))
1078 h.additionals = uint16(len(m.Additionals))
1079
1080 compressionOff := len(b)
1081 msg := h.pack(b)
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091 compression := map[string]int{}
1092
1093 for i := range m.Questions {
1094 var err error
1095 if msg, err = m.Questions[i].pack(msg, compression, compressionOff); err != nil {
1096 return nil, &nestedError{"packing Question", err}
1097 }
1098 }
1099 for i := range m.Answers {
1100 var err error
1101 if msg, err = m.Answers[i].pack(msg, compression, compressionOff); err != nil {
1102 return nil, &nestedError{"packing Answer", err}
1103 }
1104 }
1105 for i := range m.Authorities {
1106 var err error
1107 if msg, err = m.Authorities[i].pack(msg, compression, compressionOff); err != nil {
1108 return nil, &nestedError{"packing Authority", err}
1109 }
1110 }
1111 for i := range m.Additionals {
1112 var err error
1113 if msg, err = m.Additionals[i].pack(msg, compression, compressionOff); err != nil {
1114 return nil, &nestedError{"packing Additional", err}
1115 }
1116 }
1117
1118 return msg, nil
1119 }
1120
1121
1122 func (m *Message) GoString() string {
1123 s := "dnsmessage.Message{Header: " + m.Header.GoString() + ", " +
1124 "Questions: []dnsmessage.Question{"
1125 if len(m.Questions) > 0 {
1126 s += m.Questions[0].GoString()
1127 for _, q := range m.Questions[1:] {
1128 s += ", " + q.GoString()
1129 }
1130 }
1131 s += "}, Answers: []dnsmessage.Resource{"
1132 if len(m.Answers) > 0 {
1133 s += m.Answers[0].GoString()
1134 for _, a := range m.Answers[1:] {
1135 s += ", " + a.GoString()
1136 }
1137 }
1138 s += "}, Authorities: []dnsmessage.Resource{"
1139 if len(m.Authorities) > 0 {
1140 s += m.Authorities[0].GoString()
1141 for _, a := range m.Authorities[1:] {
1142 s += ", " + a.GoString()
1143 }
1144 }
1145 s += "}, Additionals: []dnsmessage.Resource{"
1146 if len(m.Additionals) > 0 {
1147 s += m.Additionals[0].GoString()
1148 for _, a := range m.Additionals[1:] {
1149 s += ", " + a.GoString()
1150 }
1151 }
1152 return s + "}}"
1153 }
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165 type Builder struct {
1166
1167 msg []byte
1168
1169
1170 section section
1171
1172
1173
1174 header header
1175
1176
1177 start int
1178
1179
1180
1181 compression map[string]int
1182 }
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194 func NewBuilder(buf []byte, h Header) Builder {
1195 if buf == nil {
1196 buf = make([]byte, 0, packStartingCap)
1197 }
1198 b := Builder{msg: buf, start: len(buf)}
1199 b.header.id, b.header.bits = h.pack()
1200 var hb [headerLen]byte
1201 b.msg = append(b.msg, hb[:]...)
1202 b.section = sectionHeader
1203 return b
1204 }
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217 func (b *Builder) EnableCompression() {
1218 b.compression = map[string]int{}
1219 }
1220
1221 func (b *Builder) startCheck(s section) error {
1222 if b.section <= sectionNotStarted {
1223 return ErrNotStarted
1224 }
1225 if b.section > s {
1226 return ErrSectionDone
1227 }
1228 return nil
1229 }
1230
1231
1232 func (b *Builder) StartQuestions() error {
1233 if err := b.startCheck(sectionQuestions); err != nil {
1234 return err
1235 }
1236 b.section = sectionQuestions
1237 return nil
1238 }
1239
1240
1241 func (b *Builder) StartAnswers() error {
1242 if err := b.startCheck(sectionAnswers); err != nil {
1243 return err
1244 }
1245 b.section = sectionAnswers
1246 return nil
1247 }
1248
1249
1250 func (b *Builder) StartAuthorities() error {
1251 if err := b.startCheck(sectionAuthorities); err != nil {
1252 return err
1253 }
1254 b.section = sectionAuthorities
1255 return nil
1256 }
1257
1258
1259 func (b *Builder) StartAdditionals() error {
1260 if err := b.startCheck(sectionAdditionals); err != nil {
1261 return err
1262 }
1263 b.section = sectionAdditionals
1264 return nil
1265 }
1266
1267 func (b *Builder) incrementSectionCount() error {
1268 var count *uint16
1269 var err error
1270 switch b.section {
1271 case sectionQuestions:
1272 count = &b.header.questions
1273 err = errTooManyQuestions
1274 case sectionAnswers:
1275 count = &b.header.answers
1276 err = errTooManyAnswers
1277 case sectionAuthorities:
1278 count = &b.header.authorities
1279 err = errTooManyAuthorities
1280 case sectionAdditionals:
1281 count = &b.header.additionals
1282 err = errTooManyAdditionals
1283 }
1284 if *count == ^uint16(0) {
1285 return err
1286 }
1287 *count++
1288 return nil
1289 }
1290
1291
1292 func (b *Builder) Question(q Question) error {
1293 if b.section < sectionQuestions {
1294 return ErrNotStarted
1295 }
1296 if b.section > sectionQuestions {
1297 return ErrSectionDone
1298 }
1299 msg, err := q.pack(b.msg, b.compression, b.start)
1300 if err != nil {
1301 return err
1302 }
1303 if err := b.incrementSectionCount(); err != nil {
1304 return err
1305 }
1306 b.msg = msg
1307 return nil
1308 }
1309
1310 func (b *Builder) checkResourceSection() error {
1311 if b.section < sectionAnswers {
1312 return ErrNotStarted
1313 }
1314 if b.section > sectionAdditionals {
1315 return ErrSectionDone
1316 }
1317 return nil
1318 }
1319
1320
1321 func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error {
1322 if err := b.checkResourceSection(); err != nil {
1323 return err
1324 }
1325 h.Type = r.realType()
1326 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1327 if err != nil {
1328 return &nestedError{"ResourceHeader", err}
1329 }
1330 preLen := len(msg)
1331 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1332 return &nestedError{"CNAMEResource body", err}
1333 }
1334 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1335 return err
1336 }
1337 if err := b.incrementSectionCount(); err != nil {
1338 return err
1339 }
1340 b.msg = msg
1341 return nil
1342 }
1343
1344
1345 func (b *Builder) MXResource(h ResourceHeader, r MXResource) error {
1346 if err := b.checkResourceSection(); err != nil {
1347 return err
1348 }
1349 h.Type = r.realType()
1350 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1351 if err != nil {
1352 return &nestedError{"ResourceHeader", err}
1353 }
1354 preLen := len(msg)
1355 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1356 return &nestedError{"MXResource body", err}
1357 }
1358 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1359 return err
1360 }
1361 if err := b.incrementSectionCount(); err != nil {
1362 return err
1363 }
1364 b.msg = msg
1365 return nil
1366 }
1367
1368
1369 func (b *Builder) NSResource(h ResourceHeader, r NSResource) error {
1370 if err := b.checkResourceSection(); err != nil {
1371 return err
1372 }
1373 h.Type = r.realType()
1374 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1375 if err != nil {
1376 return &nestedError{"ResourceHeader", err}
1377 }
1378 preLen := len(msg)
1379 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1380 return &nestedError{"NSResource body", err}
1381 }
1382 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1383 return err
1384 }
1385 if err := b.incrementSectionCount(); err != nil {
1386 return err
1387 }
1388 b.msg = msg
1389 return nil
1390 }
1391
1392
1393 func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error {
1394 if err := b.checkResourceSection(); err != nil {
1395 return err
1396 }
1397 h.Type = r.realType()
1398 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1399 if err != nil {
1400 return &nestedError{"ResourceHeader", err}
1401 }
1402 preLen := len(msg)
1403 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1404 return &nestedError{"PTRResource body", err}
1405 }
1406 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1407 return err
1408 }
1409 if err := b.incrementSectionCount(); err != nil {
1410 return err
1411 }
1412 b.msg = msg
1413 return nil
1414 }
1415
1416
1417 func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error {
1418 if err := b.checkResourceSection(); err != nil {
1419 return err
1420 }
1421 h.Type = r.realType()
1422 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1423 if err != nil {
1424 return &nestedError{"ResourceHeader", err}
1425 }
1426 preLen := len(msg)
1427 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1428 return &nestedError{"SOAResource body", err}
1429 }
1430 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1431 return err
1432 }
1433 if err := b.incrementSectionCount(); err != nil {
1434 return err
1435 }
1436 b.msg = msg
1437 return nil
1438 }
1439
1440
1441 func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error {
1442 if err := b.checkResourceSection(); err != nil {
1443 return err
1444 }
1445 h.Type = r.realType()
1446 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1447 if err != nil {
1448 return &nestedError{"ResourceHeader", err}
1449 }
1450 preLen := len(msg)
1451 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1452 return &nestedError{"TXTResource body", err}
1453 }
1454 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1455 return err
1456 }
1457 if err := b.incrementSectionCount(); err != nil {
1458 return err
1459 }
1460 b.msg = msg
1461 return nil
1462 }
1463
1464
1465 func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error {
1466 if err := b.checkResourceSection(); err != nil {
1467 return err
1468 }
1469 h.Type = r.realType()
1470 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1471 if err != nil {
1472 return &nestedError{"ResourceHeader", err}
1473 }
1474 preLen := len(msg)
1475 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1476 return &nestedError{"SRVResource body", err}
1477 }
1478 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1479 return err
1480 }
1481 if err := b.incrementSectionCount(); err != nil {
1482 return err
1483 }
1484 b.msg = msg
1485 return nil
1486 }
1487
1488
1489 func (b *Builder) AResource(h ResourceHeader, r AResource) error {
1490 if err := b.checkResourceSection(); err != nil {
1491 return err
1492 }
1493 h.Type = r.realType()
1494 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1495 if err != nil {
1496 return &nestedError{"ResourceHeader", err}
1497 }
1498 preLen := len(msg)
1499 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1500 return &nestedError{"AResource body", err}
1501 }
1502 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1503 return err
1504 }
1505 if err := b.incrementSectionCount(); err != nil {
1506 return err
1507 }
1508 b.msg = msg
1509 return nil
1510 }
1511
1512
1513 func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error {
1514 if err := b.checkResourceSection(); err != nil {
1515 return err
1516 }
1517 h.Type = r.realType()
1518 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1519 if err != nil {
1520 return &nestedError{"ResourceHeader", err}
1521 }
1522 preLen := len(msg)
1523 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1524 return &nestedError{"AAAAResource body", err}
1525 }
1526 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1527 return err
1528 }
1529 if err := b.incrementSectionCount(); err != nil {
1530 return err
1531 }
1532 b.msg = msg
1533 return nil
1534 }
1535
1536
1537 func (b *Builder) OPTResource(h ResourceHeader, r OPTResource) error {
1538 if err := b.checkResourceSection(); err != nil {
1539 return err
1540 }
1541 h.Type = r.realType()
1542 msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
1543 if err != nil {
1544 return &nestedError{"ResourceHeader", err}
1545 }
1546 preLen := len(msg)
1547 if msg, err = r.pack(msg, b.compression, b.start); err != nil {
1548 return &nestedError{"OPTResource body", err}
1549 }
1550 if err := h.fixLen(msg, lenOff, preLen); err != nil {
1551 return err
1552 }
1553 if err := b.incrementSectionCount(); err != nil {
1554 return err
1555 }
1556 b.msg = msg
1557 return nil
1558 }
1559
1560
1561 func (b *Builder) Finish() ([]byte, error) {
1562 if b.section < sectionHeader {
1563 return nil, ErrNotStarted
1564 }
1565 b.section = sectionDone
1566
1567 b.header.pack(b.msg[b.start:b.start])
1568 return b.msg, nil
1569 }
1570
1571
1572
1573 type ResourceHeader struct {
1574
1575 Name Name
1576
1577
1578
1579
1580 Type Type
1581
1582
1583
1584 Class Class
1585
1586
1587
1588
1589 TTL uint32
1590
1591
1592
1593
1594 Length uint16
1595 }
1596
1597
1598 func (h *ResourceHeader) GoString() string {
1599 return "dnsmessage.ResourceHeader{" +
1600 "Name: " + h.Name.GoString() + ", " +
1601 "Type: " + h.Type.GoString() + ", " +
1602 "Class: " + h.Class.GoString() + ", " +
1603 "TTL: " + printUint32(h.TTL) + ", " +
1604 "Length: " + printUint16(h.Length) + "}"
1605 }
1606
1607
1608
1609
1610 func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int, compressionOff int) (msg []byte, lenOff int, err error) {
1611 msg = oldMsg
1612 if msg, err = h.Name.pack(msg, compression, compressionOff); err != nil {
1613 return oldMsg, 0, &nestedError{"Name", err}
1614 }
1615 msg = packType(msg, h.Type)
1616 msg = packClass(msg, h.Class)
1617 msg = packUint32(msg, h.TTL)
1618 lenOff = len(msg)
1619 msg = packUint16(msg, h.Length)
1620 return msg, lenOff, nil
1621 }
1622
1623 func (h *ResourceHeader) unpack(msg []byte, off int) (int, error) {
1624 newOff := off
1625 var err error
1626 if newOff, err = h.Name.unpack(msg, newOff); err != nil {
1627 return off, &nestedError{"Name", err}
1628 }
1629 if h.Type, newOff, err = unpackType(msg, newOff); err != nil {
1630 return off, &nestedError{"Type", err}
1631 }
1632 if h.Class, newOff, err = unpackClass(msg, newOff); err != nil {
1633 return off, &nestedError{"Class", err}
1634 }
1635 if h.TTL, newOff, err = unpackUint32(msg, newOff); err != nil {
1636 return off, &nestedError{"TTL", err}
1637 }
1638 if h.Length, newOff, err = unpackUint16(msg, newOff); err != nil {
1639 return off, &nestedError{"Length", err}
1640 }
1641 return newOff, nil
1642 }
1643
1644
1645
1646
1647
1648
1649
1650 func (h *ResourceHeader) fixLen(msg []byte, lenOff int, preLen int) error {
1651 conLen := len(msg) - preLen
1652 if conLen > int(^uint16(0)) {
1653 return errResTooLong
1654 }
1655
1656
1657 packUint16(msg[lenOff:lenOff], uint16(conLen))
1658 h.Length = uint16(conLen)
1659
1660 return nil
1661 }
1662
1663
1664 const (
1665 edns0Version = 0
1666
1667 edns0DNSSECOK = 0x00008000
1668 ednsVersionMask = 0x00ff0000
1669 edns0DNSSECOKMask = 0x00ff8000
1670 )
1671
1672
1673
1674
1675 func (h *ResourceHeader) SetEDNS0(udpPayloadLen int, extRCode RCode, dnssecOK bool) error {
1676 h.Name = Name{Data: [nameLen]byte{'.'}, Length: 1}
1677 h.Type = TypeOPT
1678 h.Class = Class(udpPayloadLen)
1679 h.TTL = uint32(extRCode) >> 4 << 24
1680 if dnssecOK {
1681 h.TTL |= edns0DNSSECOK
1682 }
1683 return nil
1684 }
1685
1686
1687 func (h *ResourceHeader) DNSSECAllowed() bool {
1688 return h.TTL&edns0DNSSECOKMask == edns0DNSSECOK
1689 }
1690
1691
1692
1693
1694 func (h *ResourceHeader) ExtendedRCode(rcode RCode) RCode {
1695 if h.TTL&ednsVersionMask == edns0Version {
1696 return RCode(h.TTL>>24<<4) | rcode
1697 }
1698 return rcode
1699 }
1700
1701 func skipResource(msg []byte, off int) (int, error) {
1702 newOff, err := skipName(msg, off)
1703 if err != nil {
1704 return off, &nestedError{"Name", err}
1705 }
1706 if newOff, err = skipType(msg, newOff); err != nil {
1707 return off, &nestedError{"Type", err}
1708 }
1709 if newOff, err = skipClass(msg, newOff); err != nil {
1710 return off, &nestedError{"Class", err}
1711 }
1712 if newOff, err = skipUint32(msg, newOff); err != nil {
1713 return off, &nestedError{"TTL", err}
1714 }
1715 length, newOff, err := unpackUint16(msg, newOff)
1716 if err != nil {
1717 return off, &nestedError{"Length", err}
1718 }
1719 if newOff += int(length); newOff > len(msg) {
1720 return off, errResourceLen
1721 }
1722 return newOff, nil
1723 }
1724
1725
1726 func packUint16(msg []byte, field uint16) []byte {
1727 return append(msg, byte(field>>8), byte(field))
1728 }
1729
1730 func unpackUint16(msg []byte, off int) (uint16, int, error) {
1731 if off+uint16Len > len(msg) {
1732 return 0, off, errBaseLen
1733 }
1734 return uint16(msg[off])<<8 | uint16(msg[off+1]), off + uint16Len, nil
1735 }
1736
1737 func skipUint16(msg []byte, off int) (int, error) {
1738 if off+uint16Len > len(msg) {
1739 return off, errBaseLen
1740 }
1741 return off + uint16Len, nil
1742 }
1743
1744
1745 func packType(msg []byte, field Type) []byte {
1746 return packUint16(msg, uint16(field))
1747 }
1748
1749 func unpackType(msg []byte, off int) (Type, int, error) {
1750 t, o, err := unpackUint16(msg, off)
1751 return Type(t), o, err
1752 }
1753
1754 func skipType(msg []byte, off int) (int, error) {
1755 return skipUint16(msg, off)
1756 }
1757
1758
1759 func packClass(msg []byte, field Class) []byte {
1760 return packUint16(msg, uint16(field))
1761 }
1762
1763 func unpackClass(msg []byte, off int) (Class, int, error) {
1764 c, o, err := unpackUint16(msg, off)
1765 return Class(c), o, err
1766 }
1767
1768 func skipClass(msg []byte, off int) (int, error) {
1769 return skipUint16(msg, off)
1770 }
1771
1772
1773 func packUint32(msg []byte, field uint32) []byte {
1774 return append(
1775 msg,
1776 byte(field>>24),
1777 byte(field>>16),
1778 byte(field>>8),
1779 byte(field),
1780 )
1781 }
1782
1783 func unpackUint32(msg []byte, off int) (uint32, int, error) {
1784 if off+uint32Len > len(msg) {
1785 return 0, off, errBaseLen
1786 }
1787 v := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
1788 return v, off + uint32Len, nil
1789 }
1790
1791 func skipUint32(msg []byte, off int) (int, error) {
1792 if off+uint32Len > len(msg) {
1793 return off, errBaseLen
1794 }
1795 return off + uint32Len, nil
1796 }
1797
1798
1799 func packText(msg []byte, field string) ([]byte, error) {
1800 l := len(field)
1801 if l > 255 {
1802 return nil, errStringTooLong
1803 }
1804 msg = append(msg, byte(l))
1805 msg = append(msg, field...)
1806
1807 return msg, nil
1808 }
1809
1810 func unpackText(msg []byte, off int) (string, int, error) {
1811 if off >= len(msg) {
1812 return "", off, errBaseLen
1813 }
1814 beginOff := off + 1
1815 endOff := beginOff + int(msg[off])
1816 if endOff > len(msg) {
1817 return "", off, errCalcLen
1818 }
1819 return string(msg[beginOff:endOff]), endOff, nil
1820 }
1821
1822 func skipText(msg []byte, off int) (int, error) {
1823 if off >= len(msg) {
1824 return off, errBaseLen
1825 }
1826 endOff := off + 1 + int(msg[off])
1827 if endOff > len(msg) {
1828 return off, errCalcLen
1829 }
1830 return endOff, nil
1831 }
1832
1833
1834 func packBytes(msg []byte, field []byte) []byte {
1835 return append(msg, field...)
1836 }
1837
1838 func unpackBytes(msg []byte, off int, field []byte) (int, error) {
1839 newOff := off + len(field)
1840 if newOff > len(msg) {
1841 return off, errBaseLen
1842 }
1843 copy(field, msg[off:newOff])
1844 return newOff, nil
1845 }
1846
1847 func skipBytes(msg []byte, off int, field []byte) (int, error) {
1848 newOff := off + len(field)
1849 if newOff > len(msg) {
1850 return off, errBaseLen
1851 }
1852 return newOff, nil
1853 }
1854
1855 const nameLen = 255
1856
1857
1858
1859 type Name struct {
1860 Data [nameLen]byte
1861 Length uint8
1862 }
1863
1864
1865 func NewName(name string) (Name, error) {
1866 if len([]byte(name)) > nameLen {
1867 return Name{}, errCalcLen
1868 }
1869 n := Name{Length: uint8(len(name))}
1870 copy(n.Data[:], []byte(name))
1871 return n, nil
1872 }
1873
1874
1875 func MustNewName(name string) Name {
1876 n, err := NewName(name)
1877 if err != nil {
1878 panic("creating name: " + err.Error())
1879 }
1880 return n
1881 }
1882
1883
1884 func (n Name) String() string {
1885 return string(n.Data[:n.Length])
1886 }
1887
1888
1889 func (n *Name) GoString() string {
1890 return `dnsmessage.MustNewName("` + printString(n.Data[:n.Length]) + `")`
1891 }
1892
1893
1894
1895
1896
1897
1898
1899
1900 func (n *Name) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
1901 oldMsg := msg
1902
1903
1904 if n.Length == 0 || n.Data[n.Length-1] != '.' {
1905 return oldMsg, errNonCanonicalName
1906 }
1907
1908
1909 if n.Data[0] == '.' && n.Length == 1 {
1910 return append(msg, 0), nil
1911 }
1912
1913
1914 for i, begin := 0, 0; i < int(n.Length); i++ {
1915
1916 if n.Data[i] == '.' {
1917
1918
1919
1920 if i-begin >= 1<<6 {
1921 return oldMsg, errSegTooLong
1922 }
1923
1924
1925 if i-begin == 0 {
1926 return oldMsg, errZeroSegLen
1927 }
1928
1929 msg = append(msg, byte(i-begin))
1930
1931 for j := begin; j < i; j++ {
1932 msg = append(msg, n.Data[j])
1933 }
1934
1935 begin = i + 1
1936 continue
1937 }
1938
1939
1940
1941
1942 if (i == 0 || n.Data[i-1] == '.') && compression != nil {
1943 if ptr, ok := compression[string(n.Data[i:])]; ok {
1944
1945
1946 return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil
1947 }
1948
1949
1950
1951 if len(msg) <= int(^uint16(0)>>2) {
1952 compression[string(n.Data[i:])] = len(msg) - compressionOff
1953 }
1954 }
1955 }
1956 return append(msg, 0), nil
1957 }
1958
1959
1960 func (n *Name) unpack(msg []byte, off int) (int, error) {
1961 return n.unpackCompressed(msg, off, true )
1962 }
1963
1964 func (n *Name) unpackCompressed(msg []byte, off int, allowCompression bool) (int, error) {
1965
1966 currOff := off
1967
1968
1969
1970
1971 newOff := off
1972
1973
1974 var ptr int
1975
1976
1977 name := n.Data[:0]
1978
1979 Loop:
1980 for {
1981 if currOff >= len(msg) {
1982 return off, errBaseLen
1983 }
1984 c := int(msg[currOff])
1985 currOff++
1986 switch c & 0xC0 {
1987 case 0x00:
1988 if c == 0x00 {
1989
1990 break Loop
1991 }
1992 endOff := currOff + c
1993 if endOff > len(msg) {
1994 return off, errCalcLen
1995 }
1996 name = append(name, msg[currOff:endOff]...)
1997 name = append(name, '.')
1998 currOff = endOff
1999 case 0xC0:
2000 if !allowCompression {
2001 return off, errCompressedSRV
2002 }
2003 if currOff >= len(msg) {
2004 return off, errInvalidPtr
2005 }
2006 c1 := msg[currOff]
2007 currOff++
2008 if ptr == 0 {
2009 newOff = currOff
2010 }
2011
2012 if ptr++; ptr > 10 {
2013 return off, errTooManyPtr
2014 }
2015 currOff = (c^0xC0)<<8 | int(c1)
2016 default:
2017
2018 return off, errReserved
2019 }
2020 }
2021 if len(name) == 0 {
2022 name = append(name, '.')
2023 }
2024 if len(name) > len(n.Data) {
2025 return off, errCalcLen
2026 }
2027 n.Length = uint8(len(name))
2028 if ptr == 0 {
2029 newOff = currOff
2030 }
2031 return newOff, nil
2032 }
2033
2034 func skipName(msg []byte, off int) (int, error) {
2035
2036
2037
2038 newOff := off
2039
2040 Loop:
2041 for {
2042 if newOff >= len(msg) {
2043 return off, errBaseLen
2044 }
2045 c := int(msg[newOff])
2046 newOff++
2047 switch c & 0xC0 {
2048 case 0x00:
2049 if c == 0x00 {
2050
2051 break Loop
2052 }
2053
2054 newOff += c
2055 if newOff > len(msg) {
2056 return off, errCalcLen
2057 }
2058 case 0xC0:
2059
2060
2061
2062 newOff++
2063
2064
2065 break Loop
2066 default:
2067
2068 return off, errReserved
2069 }
2070 }
2071
2072 return newOff, nil
2073 }
2074
2075
2076 type Question struct {
2077 Name Name
2078 Type Type
2079 Class Class
2080 }
2081
2082
2083 func (q *Question) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2084 msg, err := q.Name.pack(msg, compression, compressionOff)
2085 if err != nil {
2086 return msg, &nestedError{"Name", err}
2087 }
2088 msg = packType(msg, q.Type)
2089 return packClass(msg, q.Class), nil
2090 }
2091
2092
2093 func (q *Question) GoString() string {
2094 return "dnsmessage.Question{" +
2095 "Name: " + q.Name.GoString() + ", " +
2096 "Type: " + q.Type.GoString() + ", " +
2097 "Class: " + q.Class.GoString() + "}"
2098 }
2099
2100 func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, int, error) {
2101 var (
2102 r ResourceBody
2103 err error
2104 name string
2105 )
2106 switch hdr.Type {
2107 case TypeA:
2108 var rb AResource
2109 rb, err = unpackAResource(msg, off)
2110 r = &rb
2111 name = "A"
2112 case TypeNS:
2113 var rb NSResource
2114 rb, err = unpackNSResource(msg, off)
2115 r = &rb
2116 name = "NS"
2117 case TypeCNAME:
2118 var rb CNAMEResource
2119 rb, err = unpackCNAMEResource(msg, off)
2120 r = &rb
2121 name = "CNAME"
2122 case TypeSOA:
2123 var rb SOAResource
2124 rb, err = unpackSOAResource(msg, off)
2125 r = &rb
2126 name = "SOA"
2127 case TypePTR:
2128 var rb PTRResource
2129 rb, err = unpackPTRResource(msg, off)
2130 r = &rb
2131 name = "PTR"
2132 case TypeMX:
2133 var rb MXResource
2134 rb, err = unpackMXResource(msg, off)
2135 r = &rb
2136 name = "MX"
2137 case TypeTXT:
2138 var rb TXTResource
2139 rb, err = unpackTXTResource(msg, off, hdr.Length)
2140 r = &rb
2141 name = "TXT"
2142 case TypeAAAA:
2143 var rb AAAAResource
2144 rb, err = unpackAAAAResource(msg, off)
2145 r = &rb
2146 name = "AAAA"
2147 case TypeSRV:
2148 var rb SRVResource
2149 rb, err = unpackSRVResource(msg, off)
2150 r = &rb
2151 name = "SRV"
2152 case TypeOPT:
2153 var rb OPTResource
2154 rb, err = unpackOPTResource(msg, off, hdr.Length)
2155 r = &rb
2156 name = "OPT"
2157 }
2158 if err != nil {
2159 return nil, off, &nestedError{name + " record", err}
2160 }
2161 if r == nil {
2162 return nil, off, errors.New("invalid resource type: " + string(hdr.Type+'0'))
2163 }
2164 return r, off + int(hdr.Length), nil
2165 }
2166
2167
2168 type CNAMEResource struct {
2169 CNAME Name
2170 }
2171
2172 func (r *CNAMEResource) realType() Type {
2173 return TypeCNAME
2174 }
2175
2176
2177 func (r *CNAMEResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2178 return r.CNAME.pack(msg, compression, compressionOff)
2179 }
2180
2181
2182 func (r *CNAMEResource) GoString() string {
2183 return "dnsmessage.CNAMEResource{CNAME: " + r.CNAME.GoString() + "}"
2184 }
2185
2186 func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) {
2187 var cname Name
2188 if _, err := cname.unpack(msg, off); err != nil {
2189 return CNAMEResource{}, err
2190 }
2191 return CNAMEResource{cname}, nil
2192 }
2193
2194
2195 type MXResource struct {
2196 Pref uint16
2197 MX Name
2198 }
2199
2200 func (r *MXResource) realType() Type {
2201 return TypeMX
2202 }
2203
2204
2205 func (r *MXResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2206 oldMsg := msg
2207 msg = packUint16(msg, r.Pref)
2208 msg, err := r.MX.pack(msg, compression, compressionOff)
2209 if err != nil {
2210 return oldMsg, &nestedError{"MXResource.MX", err}
2211 }
2212 return msg, nil
2213 }
2214
2215
2216 func (r *MXResource) GoString() string {
2217 return "dnsmessage.MXResource{" +
2218 "Pref: " + printUint16(r.Pref) + ", " +
2219 "MX: " + r.MX.GoString() + "}"
2220 }
2221
2222 func unpackMXResource(msg []byte, off int) (MXResource, error) {
2223 pref, off, err := unpackUint16(msg, off)
2224 if err != nil {
2225 return MXResource{}, &nestedError{"Pref", err}
2226 }
2227 var mx Name
2228 if _, err := mx.unpack(msg, off); err != nil {
2229 return MXResource{}, &nestedError{"MX", err}
2230 }
2231 return MXResource{pref, mx}, nil
2232 }
2233
2234
2235 type NSResource struct {
2236 NS Name
2237 }
2238
2239 func (r *NSResource) realType() Type {
2240 return TypeNS
2241 }
2242
2243
2244 func (r *NSResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2245 return r.NS.pack(msg, compression, compressionOff)
2246 }
2247
2248
2249 func (r *NSResource) GoString() string {
2250 return "dnsmessage.NSResource{NS: " + r.NS.GoString() + "}"
2251 }
2252
2253 func unpackNSResource(msg []byte, off int) (NSResource, error) {
2254 var ns Name
2255 if _, err := ns.unpack(msg, off); err != nil {
2256 return NSResource{}, err
2257 }
2258 return NSResource{ns}, nil
2259 }
2260
2261
2262 type PTRResource struct {
2263 PTR Name
2264 }
2265
2266 func (r *PTRResource) realType() Type {
2267 return TypePTR
2268 }
2269
2270
2271 func (r *PTRResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2272 return r.PTR.pack(msg, compression, compressionOff)
2273 }
2274
2275
2276 func (r *PTRResource) GoString() string {
2277 return "dnsmessage.PTRResource{PTR: " + r.PTR.GoString() + "}"
2278 }
2279
2280 func unpackPTRResource(msg []byte, off int) (PTRResource, error) {
2281 var ptr Name
2282 if _, err := ptr.unpack(msg, off); err != nil {
2283 return PTRResource{}, err
2284 }
2285 return PTRResource{ptr}, nil
2286 }
2287
2288
2289 type SOAResource struct {
2290 NS Name
2291 MBox Name
2292 Serial uint32
2293 Refresh uint32
2294 Retry uint32
2295 Expire uint32
2296
2297
2298
2299
2300 MinTTL uint32
2301 }
2302
2303 func (r *SOAResource) realType() Type {
2304 return TypeSOA
2305 }
2306
2307
2308 func (r *SOAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2309 oldMsg := msg
2310 msg, err := r.NS.pack(msg, compression, compressionOff)
2311 if err != nil {
2312 return oldMsg, &nestedError{"SOAResource.NS", err}
2313 }
2314 msg, err = r.MBox.pack(msg, compression, compressionOff)
2315 if err != nil {
2316 return oldMsg, &nestedError{"SOAResource.MBox", err}
2317 }
2318 msg = packUint32(msg, r.Serial)
2319 msg = packUint32(msg, r.Refresh)
2320 msg = packUint32(msg, r.Retry)
2321 msg = packUint32(msg, r.Expire)
2322 return packUint32(msg, r.MinTTL), nil
2323 }
2324
2325
2326 func (r *SOAResource) GoString() string {
2327 return "dnsmessage.SOAResource{" +
2328 "NS: " + r.NS.GoString() + ", " +
2329 "MBox: " + r.MBox.GoString() + ", " +
2330 "Serial: " + printUint32(r.Serial) + ", " +
2331 "Refresh: " + printUint32(r.Refresh) + ", " +
2332 "Retry: " + printUint32(r.Retry) + ", " +
2333 "Expire: " + printUint32(r.Expire) + ", " +
2334 "MinTTL: " + printUint32(r.MinTTL) + "}"
2335 }
2336
2337 func unpackSOAResource(msg []byte, off int) (SOAResource, error) {
2338 var ns Name
2339 off, err := ns.unpack(msg, off)
2340 if err != nil {
2341 return SOAResource{}, &nestedError{"NS", err}
2342 }
2343 var mbox Name
2344 if off, err = mbox.unpack(msg, off); err != nil {
2345 return SOAResource{}, &nestedError{"MBox", err}
2346 }
2347 serial, off, err := unpackUint32(msg, off)
2348 if err != nil {
2349 return SOAResource{}, &nestedError{"Serial", err}
2350 }
2351 refresh, off, err := unpackUint32(msg, off)
2352 if err != nil {
2353 return SOAResource{}, &nestedError{"Refresh", err}
2354 }
2355 retry, off, err := unpackUint32(msg, off)
2356 if err != nil {
2357 return SOAResource{}, &nestedError{"Retry", err}
2358 }
2359 expire, off, err := unpackUint32(msg, off)
2360 if err != nil {
2361 return SOAResource{}, &nestedError{"Expire", err}
2362 }
2363 minTTL, _, err := unpackUint32(msg, off)
2364 if err != nil {
2365 return SOAResource{}, &nestedError{"MinTTL", err}
2366 }
2367 return SOAResource{ns, mbox, serial, refresh, retry, expire, minTTL}, nil
2368 }
2369
2370
2371 type TXTResource struct {
2372 TXT []string
2373 }
2374
2375 func (r *TXTResource) realType() Type {
2376 return TypeTXT
2377 }
2378
2379
2380 func (r *TXTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2381 oldMsg := msg
2382 for _, s := range r.TXT {
2383 var err error
2384 msg, err = packText(msg, s)
2385 if err != nil {
2386 return oldMsg, err
2387 }
2388 }
2389 return msg, nil
2390 }
2391
2392
2393 func (r *TXTResource) GoString() string {
2394 s := "dnsmessage.TXTResource{TXT: []string{"
2395 if len(r.TXT) == 0 {
2396 return s + "}}"
2397 }
2398 s += `"` + printString([]byte(r.TXT[0]))
2399 for _, t := range r.TXT[1:] {
2400 s += `", "` + printString([]byte(t))
2401 }
2402 return s + `"}}`
2403 }
2404
2405 func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) {
2406 txts := make([]string, 0, 1)
2407 for n := uint16(0); n < length; {
2408 var t string
2409 var err error
2410 if t, off, err = unpackText(msg, off); err != nil {
2411 return TXTResource{}, &nestedError{"text", err}
2412 }
2413
2414 if length-n < uint16(len(t))+1 {
2415 return TXTResource{}, errCalcLen
2416 }
2417 n += uint16(len(t)) + 1
2418 txts = append(txts, t)
2419 }
2420 return TXTResource{txts}, nil
2421 }
2422
2423
2424 type SRVResource struct {
2425 Priority uint16
2426 Weight uint16
2427 Port uint16
2428 Target Name
2429 }
2430
2431 func (r *SRVResource) realType() Type {
2432 return TypeSRV
2433 }
2434
2435
2436 func (r *SRVResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2437 oldMsg := msg
2438 msg = packUint16(msg, r.Priority)
2439 msg = packUint16(msg, r.Weight)
2440 msg = packUint16(msg, r.Port)
2441 msg, err := r.Target.pack(msg, nil, compressionOff)
2442 if err != nil {
2443 return oldMsg, &nestedError{"SRVResource.Target", err}
2444 }
2445 return msg, nil
2446 }
2447
2448
2449 func (r *SRVResource) GoString() string {
2450 return "dnsmessage.SRVResource{" +
2451 "Priority: " + printUint16(r.Priority) + ", " +
2452 "Weight: " + printUint16(r.Weight) + ", " +
2453 "Port: " + printUint16(r.Port) + ", " +
2454 "Target: " + r.Target.GoString() + "}"
2455 }
2456
2457 func unpackSRVResource(msg []byte, off int) (SRVResource, error) {
2458 priority, off, err := unpackUint16(msg, off)
2459 if err != nil {
2460 return SRVResource{}, &nestedError{"Priority", err}
2461 }
2462 weight, off, err := unpackUint16(msg, off)
2463 if err != nil {
2464 return SRVResource{}, &nestedError{"Weight", err}
2465 }
2466 port, off, err := unpackUint16(msg, off)
2467 if err != nil {
2468 return SRVResource{}, &nestedError{"Port", err}
2469 }
2470 var target Name
2471 if _, err := target.unpackCompressed(msg, off, false ); err != nil {
2472 return SRVResource{}, &nestedError{"Target", err}
2473 }
2474 return SRVResource{priority, weight, port, target}, nil
2475 }
2476
2477
2478 type AResource struct {
2479 A [4]byte
2480 }
2481
2482 func (r *AResource) realType() Type {
2483 return TypeA
2484 }
2485
2486
2487 func (r *AResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2488 return packBytes(msg, r.A[:]), nil
2489 }
2490
2491
2492 func (r *AResource) GoString() string {
2493 return "dnsmessage.AResource{" +
2494 "A: [4]byte{" + printByteSlice(r.A[:]) + "}}"
2495 }
2496
2497 func unpackAResource(msg []byte, off int) (AResource, error) {
2498 var a [4]byte
2499 if _, err := unpackBytes(msg, off, a[:]); err != nil {
2500 return AResource{}, err
2501 }
2502 return AResource{a}, nil
2503 }
2504
2505
2506 type AAAAResource struct {
2507 AAAA [16]byte
2508 }
2509
2510 func (r *AAAAResource) realType() Type {
2511 return TypeAAAA
2512 }
2513
2514
2515 func (r *AAAAResource) GoString() string {
2516 return "dnsmessage.AAAAResource{" +
2517 "AAAA: [16]byte{" + printByteSlice(r.AAAA[:]) + "}}"
2518 }
2519
2520
2521 func (r *AAAAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2522 return packBytes(msg, r.AAAA[:]), nil
2523 }
2524
2525 func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) {
2526 var aaaa [16]byte
2527 if _, err := unpackBytes(msg, off, aaaa[:]); err != nil {
2528 return AAAAResource{}, err
2529 }
2530 return AAAAResource{aaaa}, nil
2531 }
2532
2533
2534
2535
2536
2537 type OPTResource struct {
2538 Options []Option
2539 }
2540
2541
2542
2543
2544
2545 type Option struct {
2546 Code uint16
2547 Data []byte
2548 }
2549
2550
2551 func (o *Option) GoString() string {
2552 return "dnsmessage.Option{" +
2553 "Code: " + printUint16(o.Code) + ", " +
2554 "Data: []byte{" + printByteSlice(o.Data) + "}}"
2555 }
2556
2557 func (r *OPTResource) realType() Type {
2558 return TypeOPT
2559 }
2560
2561 func (r *OPTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
2562 for _, opt := range r.Options {
2563 msg = packUint16(msg, opt.Code)
2564 l := uint16(len(opt.Data))
2565 msg = packUint16(msg, l)
2566 msg = packBytes(msg, opt.Data)
2567 }
2568 return msg, nil
2569 }
2570
2571
2572 func (r *OPTResource) GoString() string {
2573 s := "dnsmessage.OPTResource{Options: []dnsmessage.Option{"
2574 if len(r.Options) == 0 {
2575 return s + "}}"
2576 }
2577 s += r.Options[0].GoString()
2578 for _, o := range r.Options[1:] {
2579 s += ", " + o.GoString()
2580 }
2581 return s + "}}"
2582 }
2583
2584 func unpackOPTResource(msg []byte, off int, length uint16) (OPTResource, error) {
2585 var opts []Option
2586 for oldOff := off; off < oldOff+int(length); {
2587 var err error
2588 var o Option
2589 o.Code, off, err = unpackUint16(msg, off)
2590 if err != nil {
2591 return OPTResource{}, &nestedError{"Code", err}
2592 }
2593 var l uint16
2594 l, off, err = unpackUint16(msg, off)
2595 if err != nil {
2596 return OPTResource{}, &nestedError{"Data", err}
2597 }
2598 o.Data = make([]byte, l)
2599 if copy(o.Data, msg[off:]) != int(l) {
2600 return OPTResource{}, &nestedError{"Data", errCalcLen}
2601 }
2602 off += int(l)
2603 opts = append(opts, o)
2604 }
2605 return OPTResource{opts}, nil
2606 }
2607
View as plain text