github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/net/dns/dnsmessage/message.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package dnsmessage provides a mostly RFC 1035 compliant implementation of 6 // DNS message packing and unpacking. 7 // 8 // The package also supports messages with Extension Mechanisms for DNS 9 // (EDNS(0)) as defined in RFC 6891. 10 // 11 // This implementation is designed to minimize heap allocations and avoid 12 // unnecessary packing and unpacking as much as possible. 13 package dnsmessage 14 15 import ( 16 "errors" 17 ) 18 19 // Message formats 20 21 // A Type is a type of DNS request and response. 22 type Type uint16 23 24 const ( 25 // ResourceHeader.Type and Question.Type 26 TypeA Type = 1 27 TypeNS Type = 2 28 TypeCNAME Type = 5 29 TypeSOA Type = 6 30 TypePTR Type = 12 31 TypeMX Type = 15 32 TypeTXT Type = 16 33 TypeAAAA Type = 28 34 TypeSRV Type = 33 35 TypeOPT Type = 41 36 37 // Question.Type 38 TypeWKS Type = 11 39 TypeHINFO Type = 13 40 TypeMINFO Type = 14 41 TypeAXFR Type = 252 42 TypeALL Type = 255 43 ) 44 45 var typeNames = map[Type]string{ 46 TypeA: "TypeA", 47 TypeNS: "TypeNS", 48 TypeCNAME: "TypeCNAME", 49 TypeSOA: "TypeSOA", 50 TypePTR: "TypePTR", 51 TypeMX: "TypeMX", 52 TypeTXT: "TypeTXT", 53 TypeAAAA: "TypeAAAA", 54 TypeSRV: "TypeSRV", 55 TypeOPT: "TypeOPT", 56 TypeWKS: "TypeWKS", 57 TypeHINFO: "TypeHINFO", 58 TypeMINFO: "TypeMINFO", 59 TypeAXFR: "TypeAXFR", 60 TypeALL: "TypeALL", 61 } 62 63 // String implements fmt.Stringer.String. 64 func (t Type) String() string { 65 if n, ok := typeNames[t]; ok { 66 return n 67 } 68 return printUint16(uint16(t)) 69 } 70 71 // GoString implements fmt.GoStringer.GoString. 72 func (t Type) GoString() string { 73 if n, ok := typeNames[t]; ok { 74 return "dnsmessage." + n 75 } 76 return printUint16(uint16(t)) 77 } 78 79 // A Class is a type of network. 80 type Class uint16 81 82 const ( 83 // ResourceHeader.Class and Question.Class 84 ClassINET Class = 1 85 ClassCSNET Class = 2 86 ClassCHAOS Class = 3 87 ClassHESIOD Class = 4 88 89 // Question.Class 90 ClassANY Class = 255 91 ) 92 93 var classNames = map[Class]string{ 94 ClassINET: "ClassINET", 95 ClassCSNET: "ClassCSNET", 96 ClassCHAOS: "ClassCHAOS", 97 ClassHESIOD: "ClassHESIOD", 98 ClassANY: "ClassANY", 99 } 100 101 // String implements fmt.Stringer.String. 102 func (c Class) String() string { 103 if n, ok := classNames[c]; ok { 104 return n 105 } 106 return printUint16(uint16(c)) 107 } 108 109 // GoString implements fmt.GoStringer.GoString. 110 func (c Class) GoString() string { 111 if n, ok := classNames[c]; ok { 112 return "dnsmessage." + n 113 } 114 return printUint16(uint16(c)) 115 } 116 117 // An OpCode is a DNS operation code. 118 type OpCode uint16 119 120 // GoString implements fmt.GoStringer.GoString. 121 func (o OpCode) GoString() string { 122 return printUint16(uint16(o)) 123 } 124 125 // An RCode is a DNS response status code. 126 type RCode uint16 127 128 // Header.RCode values. 129 const ( 130 RCodeSuccess RCode = 0 // NoError 131 RCodeFormatError RCode = 1 // FormErr 132 RCodeServerFailure RCode = 2 // ServFail 133 RCodeNameError RCode = 3 // NXDomain 134 RCodeNotImplemented RCode = 4 // NotImp 135 RCodeRefused RCode = 5 // Refused 136 ) 137 138 var rCodeNames = map[RCode]string{ 139 RCodeSuccess: "RCodeSuccess", 140 RCodeFormatError: "RCodeFormatError", 141 RCodeServerFailure: "RCodeServerFailure", 142 RCodeNameError: "RCodeNameError", 143 RCodeNotImplemented: "RCodeNotImplemented", 144 RCodeRefused: "RCodeRefused", 145 } 146 147 // String implements fmt.Stringer.String. 148 func (r RCode) String() string { 149 if n, ok := rCodeNames[r]; ok { 150 return n 151 } 152 return printUint16(uint16(r)) 153 } 154 155 // GoString implements fmt.GoStringer.GoString. 156 func (r RCode) GoString() string { 157 if n, ok := rCodeNames[r]; ok { 158 return "dnsmessage." + n 159 } 160 return printUint16(uint16(r)) 161 } 162 163 func printPaddedUint8(i uint8) string { 164 b := byte(i) 165 return string([]byte{ 166 b/100 + '0', 167 b/10%10 + '0', 168 b%10 + '0', 169 }) 170 } 171 172 func printUint8Bytes(buf []byte, i uint8) []byte { 173 b := byte(i) 174 if i >= 100 { 175 buf = append(buf, b/100+'0') 176 } 177 if i >= 10 { 178 buf = append(buf, b/10%10+'0') 179 } 180 return append(buf, b%10+'0') 181 } 182 183 func printByteSlice(b []byte) string { 184 if len(b) == 0 { 185 return "" 186 } 187 buf := 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 // Max value is 4294967295. 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 // ErrNotStarted indicates that the prerequisite information isn't 250 // available yet because the previous records haven't been appropriately 251 // parsed, skipped or finished. 252 ErrNotStarted = errors.New("parsing/packing of this type isn't available yet") 253 254 // ErrSectionDone indicated that all records in the section have been 255 // parsed or finished. 256 ErrSectionDone = errors.New("parsing/packing of this section has completed") 257 258 errBaseLen = errors.New("insufficient data for base length type") 259 errCalcLen = errors.New("insufficient data for calculated length type") 260 errReserved = errors.New("segment prefix is reserved") 261 errTooManyPtr = errors.New("too many pointers (>10)") 262 errInvalidPtr = errors.New("invalid pointer") 263 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 // Internal constants. 278 const ( 279 // packStartingCap is the default initial buffer size allocated during 280 // packing. 281 // 282 // The starting capacity doesn't matter too much, but most DNS responses 283 // Will be <= 512 bytes as it is the limit for DNS over UDP. 284 packStartingCap = 512 285 286 // uint16Len is the length (in bytes) of a uint16. 287 uint16Len = 2 288 289 // uint32Len is the length (in bytes) of a uint32. 290 uint32Len = 4 291 292 // headerLen is the length (in bytes) of a DNS header. 293 // 294 // A header is comprised of 6 uint16s and no padding. 295 headerLen = 6 * uint16Len 296 ) 297 298 type nestedError struct { 299 // s is the current level's error message. 300 s string 301 302 // err is the nested error. 303 err error 304 } 305 306 // nestedError implements error.Error. 307 func (e *nestedError) Error() string { 308 return e.s + ": " + e.err.Error() 309 } 310 311 // Header is a representation of a DNS message header. 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 // GoString implements fmt.GoStringer.GoString. 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 // Message is a representation of a DNS message. 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 // query/response (response=1) 378 headerBitAA = 1 << 10 // authoritative 379 headerBitTC = 1 << 9 // truncated 380 headerBitRD = 1 << 8 // recursion desired 381 headerBitRA = 1 << 7 // recursion available 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 // header is the wire format for a DNS message header. 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 // pack appends the wire format of the header to msg. 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 // A Resource is a DNS resource record. 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 // A ResourceBody is a DNS resource record minus the header. 477 type ResourceBody interface { 478 // pack packs a Resource except for its header. 479 pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) 480 481 // realType returns the actual type of the Resource. This is used to 482 // fill in the header Type field. 483 realType() Type 484 485 // GoString implements fmt.GoStringer.GoString. 486 GoString() string 487 } 488 489 // pack appends the wire format of the Resource to msg. 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 // A Parser allows incrementally parsing a DNS message. 512 // 513 // When parsing is started, the Header is parsed. Next, each Question can be 514 // either parsed or skipped. Alternatively, all Questions can be skipped at 515 // once. When all Questions have been parsed, attempting to parse Questions 516 // will return (nil, nil) and attempting to skip Questions will return 517 // (true, nil). After all Questions have been either parsed or skipped, all 518 // Answers, Authorities and Additionals can be either parsed or skipped in the 519 // same way, and each type of Resource must be fully parsed or skipped before 520 // proceeding to the next type of Resource. 521 // 522 // Note that there is no requirement to fully skip or parse the message. 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 // Start parses the header and enables the parsing of Questions. 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 // Question parses a single Question. 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 // AllQuestions parses all Questions. 645 func (p *Parser) AllQuestions() ([]Question, error) { 646 // Multiple questions are valid according to the spec, 647 // but servers don't actually support them. There will 648 // be at most one question here. 649 // 650 // Do not pre-allocate based on info in p.header, since 651 // the data is untrusted. 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 // SkipQuestion skips a single Question. 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 // SkipAllQuestions skips all Questions. 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 // AnswerHeader parses a single Answer ResourceHeader. 697 func (p *Parser) AnswerHeader() (ResourceHeader, error) { 698 return p.resourceHeader(sectionAnswers) 699 } 700 701 // Answer parses a single Answer Resource. 702 func (p *Parser) Answer() (Resource, error) { 703 return p.resource(sectionAnswers) 704 } 705 706 // AllAnswers parses all Answer Resources. 707 func (p *Parser) AllAnswers() ([]Resource, error) { 708 // The most common query is for A/AAAA, which usually returns 709 // a handful of IPs. 710 // 711 // Pre-allocate up to a certain limit, since p.header is 712 // untrusted data. 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 // SkipAnswer skips a single Answer Resource. 731 func (p *Parser) SkipAnswer() error { 732 return p.skipResource(sectionAnswers) 733 } 734 735 // SkipAllAnswers skips all Answer Resources. 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 // AuthorityHeader parses a single Authority ResourceHeader. 747 func (p *Parser) AuthorityHeader() (ResourceHeader, error) { 748 return p.resourceHeader(sectionAuthorities) 749 } 750 751 // Authority parses a single Authority Resource. 752 func (p *Parser) Authority() (Resource, error) { 753 return p.resource(sectionAuthorities) 754 } 755 756 // AllAuthorities parses all Authority Resources. 757 func (p *Parser) AllAuthorities() ([]Resource, error) { 758 // Authorities contains SOA in case of NXDOMAIN and friends, 759 // otherwise it is empty. 760 // 761 // Pre-allocate up to a certain limit, since p.header is 762 // untrusted data. 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 // SkipAuthority skips a single Authority Resource. 781 func (p *Parser) SkipAuthority() error { 782 return p.skipResource(sectionAuthorities) 783 } 784 785 // SkipAllAuthorities skips all Authority Resources. 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 // AdditionalHeader parses a single Additional ResourceHeader. 797 func (p *Parser) AdditionalHeader() (ResourceHeader, error) { 798 return p.resourceHeader(sectionAdditionals) 799 } 800 801 // Additional parses a single Additional Resource. 802 func (p *Parser) Additional() (Resource, error) { 803 return p.resource(sectionAdditionals) 804 } 805 806 // AllAdditionals parses all Additional Resources. 807 func (p *Parser) AllAdditionals() ([]Resource, error) { 808 // Additionals usually contain OPT, and sometimes A/AAAA 809 // glue records. 810 // 811 // Pre-allocate up to a certain limit, since p.header is 812 // untrusted data. 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 // SkipAdditional skips a single Additional Resource. 831 func (p *Parser) SkipAdditional() error { 832 return p.skipResource(sectionAdditionals) 833 } 834 835 // SkipAllAdditionals skips all Additional Resources. 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 // CNAMEResource parses a single CNAMEResource. 847 // 848 // One of the XXXHeader methods must have been called before calling this 849 // method. 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 // MXResource parses a single MXResource. 865 // 866 // One of the XXXHeader methods must have been called before calling this 867 // method. 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 // NSResource parses a single NSResource. 883 // 884 // One of the XXXHeader methods must have been called before calling this 885 // method. 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 // PTRResource parses a single PTRResource. 901 // 902 // One of the XXXHeader methods must have been called before calling this 903 // method. 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 // SOAResource parses a single SOAResource. 919 // 920 // One of the XXXHeader methods must have been called before calling this 921 // method. 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 // TXTResource parses a single TXTResource. 937 // 938 // One of the XXXHeader methods must have been called before calling this 939 // method. 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 // SRVResource parses a single SRVResource. 955 // 956 // One of the XXXHeader methods must have been called before calling this 957 // method. 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 // AResource parses a single AResource. 973 // 974 // One of the XXXHeader methods must have been called before calling this 975 // method. 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 // AAAAResource parses a single AAAAResource. 991 // 992 // One of the XXXHeader methods must have been called before calling this 993 // method. 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 // OPTResource parses a single OPTResource. 1009 // 1010 // One of the XXXHeader methods must have been called before calling this 1011 // method. 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 // UnknownResource parses a single UnknownResource. 1027 // 1028 // One of the XXXHeader methods must have been called before calling this 1029 // method. 1030 func (p *Parser) UnknownResource() (UnknownResource, error) { 1031 if !p.resHeaderValid { 1032 return UnknownResource{}, ErrNotStarted 1033 } 1034 r, err := unpackUnknownResource(p.resHeader.Type, p.msg, p.off, p.resHeader.Length) 1035 if err != nil { 1036 return UnknownResource{}, err 1037 } 1038 p.off += int(p.resHeader.Length) 1039 p.resHeaderValid = false 1040 p.index++ 1041 return r, nil 1042 } 1043 1044 // Unpack parses a full Message. 1045 func (m *Message) Unpack(msg []byte) error { 1046 var p Parser 1047 var err error 1048 if m.Header, err = p.Start(msg); err != nil { 1049 return err 1050 } 1051 if m.Questions, err = p.AllQuestions(); err != nil { 1052 return err 1053 } 1054 if m.Answers, err = p.AllAnswers(); err != nil { 1055 return err 1056 } 1057 if m.Authorities, err = p.AllAuthorities(); err != nil { 1058 return err 1059 } 1060 if m.Additionals, err = p.AllAdditionals(); err != nil { 1061 return err 1062 } 1063 return nil 1064 } 1065 1066 // Pack packs a full Message. 1067 func (m *Message) Pack() ([]byte, error) { 1068 return m.AppendPack(make([]byte, 0, packStartingCap)) 1069 } 1070 1071 // AppendPack is like Pack but appends the full Message to b and returns the 1072 // extended buffer. 1073 func (m *Message) AppendPack(b []byte) ([]byte, error) { 1074 // Validate the lengths. It is very unlikely that anyone will try to 1075 // pack more than 65535 of any particular type, but it is possible and 1076 // we should fail gracefully. 1077 if len(m.Questions) > int(^uint16(0)) { 1078 return nil, errTooManyQuestions 1079 } 1080 if len(m.Answers) > int(^uint16(0)) { 1081 return nil, errTooManyAnswers 1082 } 1083 if len(m.Authorities) > int(^uint16(0)) { 1084 return nil, errTooManyAuthorities 1085 } 1086 if len(m.Additionals) > int(^uint16(0)) { 1087 return nil, errTooManyAdditionals 1088 } 1089 1090 var h header 1091 h.id, h.bits = m.Header.pack() 1092 1093 h.questions = uint16(len(m.Questions)) 1094 h.answers = uint16(len(m.Answers)) 1095 h.authorities = uint16(len(m.Authorities)) 1096 h.additionals = uint16(len(m.Additionals)) 1097 1098 compressionOff := len(b) 1099 msg := h.pack(b) 1100 1101 // RFC 1035 allows (but does not require) compression for packing. RFC 1102 // 1035 requires unpacking implementations to support compression, so 1103 // unconditionally enabling it is fine. 1104 // 1105 // DNS lookups are typically done over UDP, and RFC 1035 states that UDP 1106 // DNS messages can be a maximum of 512 bytes long. Without compression, 1107 // many DNS response messages are over this limit, so enabling 1108 // compression will help ensure compliance. 1109 compression := map[string]int{} 1110 1111 for i := range m.Questions { 1112 var err error 1113 if msg, err = m.Questions[i].pack(msg, compression, compressionOff); err != nil { 1114 return nil, &nestedError{"packing Question", err} 1115 } 1116 } 1117 for i := range m.Answers { 1118 var err error 1119 if msg, err = m.Answers[i].pack(msg, compression, compressionOff); err != nil { 1120 return nil, &nestedError{"packing Answer", err} 1121 } 1122 } 1123 for i := range m.Authorities { 1124 var err error 1125 if msg, err = m.Authorities[i].pack(msg, compression, compressionOff); err != nil { 1126 return nil, &nestedError{"packing Authority", err} 1127 } 1128 } 1129 for i := range m.Additionals { 1130 var err error 1131 if msg, err = m.Additionals[i].pack(msg, compression, compressionOff); err != nil { 1132 return nil, &nestedError{"packing Additional", err} 1133 } 1134 } 1135 1136 return msg, nil 1137 } 1138 1139 // GoString implements fmt.GoStringer.GoString. 1140 func (m *Message) GoString() string { 1141 s := "dnsmessage.Message{Header: " + m.Header.GoString() + ", " + 1142 "Questions: []dnsmessage.Question{" 1143 if len(m.Questions) > 0 { 1144 s += m.Questions[0].GoString() 1145 for _, q := range m.Questions[1:] { 1146 s += ", " + q.GoString() 1147 } 1148 } 1149 s += "}, Answers: []dnsmessage.Resource{" 1150 if len(m.Answers) > 0 { 1151 s += m.Answers[0].GoString() 1152 for _, a := range m.Answers[1:] { 1153 s += ", " + a.GoString() 1154 } 1155 } 1156 s += "}, Authorities: []dnsmessage.Resource{" 1157 if len(m.Authorities) > 0 { 1158 s += m.Authorities[0].GoString() 1159 for _, a := range m.Authorities[1:] { 1160 s += ", " + a.GoString() 1161 } 1162 } 1163 s += "}, Additionals: []dnsmessage.Resource{" 1164 if len(m.Additionals) > 0 { 1165 s += m.Additionals[0].GoString() 1166 for _, a := range m.Additionals[1:] { 1167 s += ", " + a.GoString() 1168 } 1169 } 1170 return s + "}}" 1171 } 1172 1173 // A Builder allows incrementally packing a DNS message. 1174 // 1175 // Example usage: 1176 // buf := make([]byte, 2, 514) 1177 // b := NewBuilder(buf, Header{...}) 1178 // b.EnableCompression() 1179 // // Optionally start a section and add things to that section. 1180 // // Repeat adding sections as necessary. 1181 // buf, err := b.Finish() 1182 // // If err is nil, buf[2:] will contain the built bytes. 1183 type Builder struct { 1184 // msg is the storage for the message being built. 1185 msg []byte 1186 1187 // section keeps track of the current section being built. 1188 section section 1189 1190 // header keeps track of what should go in the header when Finish is 1191 // called. 1192 header header 1193 1194 // start is the starting index of the bytes allocated in msg for header. 1195 start int 1196 1197 // compression is a mapping from name suffixes to their starting index 1198 // in msg. 1199 compression map[string]int 1200 } 1201 1202 // NewBuilder creates a new builder with compression disabled. 1203 // 1204 // Note: Most users will want to immediately enable compression with the 1205 // EnableCompression method. See that method's comment for why you may or may 1206 // not want to enable compression. 1207 // 1208 // The DNS message is appended to the provided initial buffer buf (which may be 1209 // nil) as it is built. The final message is returned by the (*Builder).Finish 1210 // method, which includes buf[:len(buf)] and may return the same underlying 1211 // array if there was sufficient capacity in the slice. 1212 func NewBuilder(buf []byte, h Header) Builder { 1213 if buf == nil { 1214 buf = make([]byte, 0, packStartingCap) 1215 } 1216 b := Builder{msg: buf, start: len(buf)} 1217 b.header.id, b.header.bits = h.pack() 1218 var hb [headerLen]byte 1219 b.msg = append(b.msg, hb[:]...) 1220 b.section = sectionHeader 1221 return b 1222 } 1223 1224 // EnableCompression enables compression in the Builder. 1225 // 1226 // Leaving compression disabled avoids compression related allocations, but can 1227 // result in larger message sizes. Be careful with this mode as it can cause 1228 // messages to exceed the UDP size limit. 1229 // 1230 // According to RFC 1035, section 4.1.4, the use of compression is optional, but 1231 // all implementations must accept both compressed and uncompressed DNS 1232 // messages. 1233 // 1234 // Compression should be enabled before any sections are added for best results. 1235 func (b *Builder) EnableCompression() { 1236 b.compression = map[string]int{} 1237 } 1238 1239 func (b *Builder) startCheck(s section) error { 1240 if b.section <= sectionNotStarted { 1241 return ErrNotStarted 1242 } 1243 if b.section > s { 1244 return ErrSectionDone 1245 } 1246 return nil 1247 } 1248 1249 // StartQuestions prepares the builder for packing Questions. 1250 func (b *Builder) StartQuestions() error { 1251 if err := b.startCheck(sectionQuestions); err != nil { 1252 return err 1253 } 1254 b.section = sectionQuestions 1255 return nil 1256 } 1257 1258 // StartAnswers prepares the builder for packing Answers. 1259 func (b *Builder) StartAnswers() error { 1260 if err := b.startCheck(sectionAnswers); err != nil { 1261 return err 1262 } 1263 b.section = sectionAnswers 1264 return nil 1265 } 1266 1267 // StartAuthorities prepares the builder for packing Authorities. 1268 func (b *Builder) StartAuthorities() error { 1269 if err := b.startCheck(sectionAuthorities); err != nil { 1270 return err 1271 } 1272 b.section = sectionAuthorities 1273 return nil 1274 } 1275 1276 // StartAdditionals prepares the builder for packing Additionals. 1277 func (b *Builder) StartAdditionals() error { 1278 if err := b.startCheck(sectionAdditionals); err != nil { 1279 return err 1280 } 1281 b.section = sectionAdditionals 1282 return nil 1283 } 1284 1285 func (b *Builder) incrementSectionCount() error { 1286 var count *uint16 1287 var err error 1288 switch b.section { 1289 case sectionQuestions: 1290 count = &b.header.questions 1291 err = errTooManyQuestions 1292 case sectionAnswers: 1293 count = &b.header.answers 1294 err = errTooManyAnswers 1295 case sectionAuthorities: 1296 count = &b.header.authorities 1297 err = errTooManyAuthorities 1298 case sectionAdditionals: 1299 count = &b.header.additionals 1300 err = errTooManyAdditionals 1301 } 1302 if *count == ^uint16(0) { 1303 return err 1304 } 1305 *count++ 1306 return nil 1307 } 1308 1309 // Question adds a single Question. 1310 func (b *Builder) Question(q Question) error { 1311 if b.section < sectionQuestions { 1312 return ErrNotStarted 1313 } 1314 if b.section > sectionQuestions { 1315 return ErrSectionDone 1316 } 1317 msg, err := q.pack(b.msg, b.compression, b.start) 1318 if err != nil { 1319 return err 1320 } 1321 if err := b.incrementSectionCount(); err != nil { 1322 return err 1323 } 1324 b.msg = msg 1325 return nil 1326 } 1327 1328 func (b *Builder) checkResourceSection() error { 1329 if b.section < sectionAnswers { 1330 return ErrNotStarted 1331 } 1332 if b.section > sectionAdditionals { 1333 return ErrSectionDone 1334 } 1335 return nil 1336 } 1337 1338 // CNAMEResource adds a single CNAMEResource. 1339 func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error { 1340 if err := b.checkResourceSection(); err != nil { 1341 return err 1342 } 1343 h.Type = r.realType() 1344 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1345 if err != nil { 1346 return &nestedError{"ResourceHeader", err} 1347 } 1348 preLen := len(msg) 1349 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1350 return &nestedError{"CNAMEResource body", err} 1351 } 1352 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1353 return err 1354 } 1355 if err := b.incrementSectionCount(); err != nil { 1356 return err 1357 } 1358 b.msg = msg 1359 return nil 1360 } 1361 1362 // MXResource adds a single MXResource. 1363 func (b *Builder) MXResource(h ResourceHeader, r MXResource) error { 1364 if err := b.checkResourceSection(); err != nil { 1365 return err 1366 } 1367 h.Type = r.realType() 1368 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1369 if err != nil { 1370 return &nestedError{"ResourceHeader", err} 1371 } 1372 preLen := len(msg) 1373 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1374 return &nestedError{"MXResource body", err} 1375 } 1376 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1377 return err 1378 } 1379 if err := b.incrementSectionCount(); err != nil { 1380 return err 1381 } 1382 b.msg = msg 1383 return nil 1384 } 1385 1386 // NSResource adds a single NSResource. 1387 func (b *Builder) NSResource(h ResourceHeader, r NSResource) error { 1388 if err := b.checkResourceSection(); err != nil { 1389 return err 1390 } 1391 h.Type = r.realType() 1392 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1393 if err != nil { 1394 return &nestedError{"ResourceHeader", err} 1395 } 1396 preLen := len(msg) 1397 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1398 return &nestedError{"NSResource body", err} 1399 } 1400 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1401 return err 1402 } 1403 if err := b.incrementSectionCount(); err != nil { 1404 return err 1405 } 1406 b.msg = msg 1407 return nil 1408 } 1409 1410 // PTRResource adds a single PTRResource. 1411 func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error { 1412 if err := b.checkResourceSection(); err != nil { 1413 return err 1414 } 1415 h.Type = r.realType() 1416 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1417 if err != nil { 1418 return &nestedError{"ResourceHeader", err} 1419 } 1420 preLen := len(msg) 1421 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1422 return &nestedError{"PTRResource body", err} 1423 } 1424 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1425 return err 1426 } 1427 if err := b.incrementSectionCount(); err != nil { 1428 return err 1429 } 1430 b.msg = msg 1431 return nil 1432 } 1433 1434 // SOAResource adds a single SOAResource. 1435 func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error { 1436 if err := b.checkResourceSection(); err != nil { 1437 return err 1438 } 1439 h.Type = r.realType() 1440 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1441 if err != nil { 1442 return &nestedError{"ResourceHeader", err} 1443 } 1444 preLen := len(msg) 1445 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1446 return &nestedError{"SOAResource body", err} 1447 } 1448 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1449 return err 1450 } 1451 if err := b.incrementSectionCount(); err != nil { 1452 return err 1453 } 1454 b.msg = msg 1455 return nil 1456 } 1457 1458 // TXTResource adds a single TXTResource. 1459 func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error { 1460 if err := b.checkResourceSection(); err != nil { 1461 return err 1462 } 1463 h.Type = r.realType() 1464 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1465 if err != nil { 1466 return &nestedError{"ResourceHeader", err} 1467 } 1468 preLen := len(msg) 1469 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1470 return &nestedError{"TXTResource body", err} 1471 } 1472 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1473 return err 1474 } 1475 if err := b.incrementSectionCount(); err != nil { 1476 return err 1477 } 1478 b.msg = msg 1479 return nil 1480 } 1481 1482 // SRVResource adds a single SRVResource. 1483 func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error { 1484 if err := b.checkResourceSection(); err != nil { 1485 return err 1486 } 1487 h.Type = r.realType() 1488 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1489 if err != nil { 1490 return &nestedError{"ResourceHeader", err} 1491 } 1492 preLen := len(msg) 1493 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1494 return &nestedError{"SRVResource body", err} 1495 } 1496 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1497 return err 1498 } 1499 if err := b.incrementSectionCount(); err != nil { 1500 return err 1501 } 1502 b.msg = msg 1503 return nil 1504 } 1505 1506 // AResource adds a single AResource. 1507 func (b *Builder) AResource(h ResourceHeader, r AResource) error { 1508 if err := b.checkResourceSection(); err != nil { 1509 return err 1510 } 1511 h.Type = r.realType() 1512 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1513 if err != nil { 1514 return &nestedError{"ResourceHeader", err} 1515 } 1516 preLen := len(msg) 1517 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1518 return &nestedError{"AResource body", err} 1519 } 1520 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1521 return err 1522 } 1523 if err := b.incrementSectionCount(); err != nil { 1524 return err 1525 } 1526 b.msg = msg 1527 return nil 1528 } 1529 1530 // AAAAResource adds a single AAAAResource. 1531 func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error { 1532 if err := b.checkResourceSection(); err != nil { 1533 return err 1534 } 1535 h.Type = r.realType() 1536 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1537 if err != nil { 1538 return &nestedError{"ResourceHeader", err} 1539 } 1540 preLen := len(msg) 1541 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1542 return &nestedError{"AAAAResource body", err} 1543 } 1544 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1545 return err 1546 } 1547 if err := b.incrementSectionCount(); err != nil { 1548 return err 1549 } 1550 b.msg = msg 1551 return nil 1552 } 1553 1554 // OPTResource adds a single OPTResource. 1555 func (b *Builder) OPTResource(h ResourceHeader, r OPTResource) error { 1556 if err := b.checkResourceSection(); err != nil { 1557 return err 1558 } 1559 h.Type = r.realType() 1560 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1561 if err != nil { 1562 return &nestedError{"ResourceHeader", err} 1563 } 1564 preLen := len(msg) 1565 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1566 return &nestedError{"OPTResource body", err} 1567 } 1568 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1569 return err 1570 } 1571 if err := b.incrementSectionCount(); err != nil { 1572 return err 1573 } 1574 b.msg = msg 1575 return nil 1576 } 1577 1578 // UnknownResource adds a single UnknownResource. 1579 func (b *Builder) UnknownResource(h ResourceHeader, r UnknownResource) error { 1580 if err := b.checkResourceSection(); err != nil { 1581 return err 1582 } 1583 h.Type = r.realType() 1584 msg, lenOff, err := h.pack(b.msg, b.compression, b.start) 1585 if err != nil { 1586 return &nestedError{"ResourceHeader", err} 1587 } 1588 preLen := len(msg) 1589 if msg, err = r.pack(msg, b.compression, b.start); err != nil { 1590 return &nestedError{"UnknownResource body", err} 1591 } 1592 if err := h.fixLen(msg, lenOff, preLen); err != nil { 1593 return err 1594 } 1595 if err := b.incrementSectionCount(); err != nil { 1596 return err 1597 } 1598 b.msg = msg 1599 return nil 1600 } 1601 1602 // Finish ends message building and generates a binary message. 1603 func (b *Builder) Finish() ([]byte, error) { 1604 if b.section < sectionHeader { 1605 return nil, ErrNotStarted 1606 } 1607 b.section = sectionDone 1608 // Space for the header was allocated in NewBuilder. 1609 b.header.pack(b.msg[b.start:b.start]) 1610 return b.msg, nil 1611 } 1612 1613 // A ResourceHeader is the header of a DNS resource record. There are 1614 // many types of DNS resource records, but they all share the same header. 1615 type ResourceHeader struct { 1616 // Name is the domain name for which this resource record pertains. 1617 Name Name 1618 1619 // Type is the type of DNS resource record. 1620 // 1621 // This field will be set automatically during packing. 1622 Type Type 1623 1624 // Class is the class of network to which this DNS resource record 1625 // pertains. 1626 Class Class 1627 1628 // TTL is the length of time (measured in seconds) which this resource 1629 // record is valid for (time to live). All Resources in a set should 1630 // have the same TTL (RFC 2181 Section 5.2). 1631 TTL uint32 1632 1633 // Length is the length of data in the resource record after the header. 1634 // 1635 // This field will be set automatically during packing. 1636 Length uint16 1637 } 1638 1639 // GoString implements fmt.GoStringer.GoString. 1640 func (h *ResourceHeader) GoString() string { 1641 return "dnsmessage.ResourceHeader{" + 1642 "Name: " + h.Name.GoString() + ", " + 1643 "Type: " + h.Type.GoString() + ", " + 1644 "Class: " + h.Class.GoString() + ", " + 1645 "TTL: " + printUint32(h.TTL) + ", " + 1646 "Length: " + printUint16(h.Length) + "}" 1647 } 1648 1649 // pack appends the wire format of the ResourceHeader to oldMsg. 1650 // 1651 // lenOff is the offset in msg where the Length field was packed. 1652 func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int, compressionOff int) (msg []byte, lenOff int, err error) { 1653 msg = oldMsg 1654 if msg, err = h.Name.pack(msg, compression, compressionOff); err != nil { 1655 return oldMsg, 0, &nestedError{"Name", err} 1656 } 1657 msg = packType(msg, h.Type) 1658 msg = packClass(msg, h.Class) 1659 msg = packUint32(msg, h.TTL) 1660 lenOff = len(msg) 1661 msg = packUint16(msg, h.Length) 1662 return msg, lenOff, nil 1663 } 1664 1665 func (h *ResourceHeader) unpack(msg []byte, off int) (int, error) { 1666 newOff := off 1667 var err error 1668 if newOff, err = h.Name.unpack(msg, newOff); err != nil { 1669 return off, &nestedError{"Name", err} 1670 } 1671 if h.Type, newOff, err = unpackType(msg, newOff); err != nil { 1672 return off, &nestedError{"Type", err} 1673 } 1674 if h.Class, newOff, err = unpackClass(msg, newOff); err != nil { 1675 return off, &nestedError{"Class", err} 1676 } 1677 if h.TTL, newOff, err = unpackUint32(msg, newOff); err != nil { 1678 return off, &nestedError{"TTL", err} 1679 } 1680 if h.Length, newOff, err = unpackUint16(msg, newOff); err != nil { 1681 return off, &nestedError{"Length", err} 1682 } 1683 return newOff, nil 1684 } 1685 1686 // fixLen updates a packed ResourceHeader to include the length of the 1687 // ResourceBody. 1688 // 1689 // lenOff is the offset of the ResourceHeader.Length field in msg. 1690 // 1691 // preLen is the length that msg was before the ResourceBody was packed. 1692 func (h *ResourceHeader) fixLen(msg []byte, lenOff int, preLen int) error { 1693 conLen := len(msg) - preLen 1694 if conLen > int(^uint16(0)) { 1695 return errResTooLong 1696 } 1697 1698 // Fill in the length now that we know how long the content is. 1699 packUint16(msg[lenOff:lenOff], uint16(conLen)) 1700 h.Length = uint16(conLen) 1701 1702 return nil 1703 } 1704 1705 // EDNS(0) wire constants. 1706 const ( 1707 edns0Version = 0 1708 1709 edns0DNSSECOK = 0x00008000 1710 ednsVersionMask = 0x00ff0000 1711 edns0DNSSECOKMask = 0x00ff8000 1712 ) 1713 1714 // SetEDNS0 configures h for EDNS(0). 1715 // 1716 // The provided extRCode must be an extended RCode. 1717 func (h *ResourceHeader) SetEDNS0(udpPayloadLen int, extRCode RCode, dnssecOK bool) error { 1718 h.Name = Name{Data: [nameLen]byte{'.'}, Length: 1} // RFC 6891 section 6.1.2 1719 h.Type = TypeOPT 1720 h.Class = Class(udpPayloadLen) 1721 h.TTL = uint32(extRCode) >> 4 << 24 1722 if dnssecOK { 1723 h.TTL |= edns0DNSSECOK 1724 } 1725 return nil 1726 } 1727 1728 // DNSSECAllowed reports whether the DNSSEC OK bit is set. 1729 func (h *ResourceHeader) DNSSECAllowed() bool { 1730 return h.TTL&edns0DNSSECOKMask == edns0DNSSECOK // RFC 6891 section 6.1.3 1731 } 1732 1733 // ExtendedRCode returns an extended RCode. 1734 // 1735 // The provided rcode must be the RCode in DNS message header. 1736 func (h *ResourceHeader) ExtendedRCode(rcode RCode) RCode { 1737 if h.TTL&ednsVersionMask == edns0Version { // RFC 6891 section 6.1.3 1738 return RCode(h.TTL>>24<<4) | rcode 1739 } 1740 return rcode 1741 } 1742 1743 func skipResource(msg []byte, off int) (int, error) { 1744 newOff, err := skipName(msg, off) 1745 if err != nil { 1746 return off, &nestedError{"Name", err} 1747 } 1748 if newOff, err = skipType(msg, newOff); err != nil { 1749 return off, &nestedError{"Type", err} 1750 } 1751 if newOff, err = skipClass(msg, newOff); err != nil { 1752 return off, &nestedError{"Class", err} 1753 } 1754 if newOff, err = skipUint32(msg, newOff); err != nil { 1755 return off, &nestedError{"TTL", err} 1756 } 1757 length, newOff, err := unpackUint16(msg, newOff) 1758 if err != nil { 1759 return off, &nestedError{"Length", err} 1760 } 1761 if newOff += int(length); newOff > len(msg) { 1762 return off, errResourceLen 1763 } 1764 return newOff, nil 1765 } 1766 1767 // packUint16 appends the wire format of field to msg. 1768 func packUint16(msg []byte, field uint16) []byte { 1769 return append(msg, byte(field>>8), byte(field)) 1770 } 1771 1772 func unpackUint16(msg []byte, off int) (uint16, int, error) { 1773 if off+uint16Len > len(msg) { 1774 return 0, off, errBaseLen 1775 } 1776 return uint16(msg[off])<<8 | uint16(msg[off+1]), off + uint16Len, nil 1777 } 1778 1779 func skipUint16(msg []byte, off int) (int, error) { 1780 if off+uint16Len > len(msg) { 1781 return off, errBaseLen 1782 } 1783 return off + uint16Len, nil 1784 } 1785 1786 // packType appends the wire format of field to msg. 1787 func packType(msg []byte, field Type) []byte { 1788 return packUint16(msg, uint16(field)) 1789 } 1790 1791 func unpackType(msg []byte, off int) (Type, int, error) { 1792 t, o, err := unpackUint16(msg, off) 1793 return Type(t), o, err 1794 } 1795 1796 func skipType(msg []byte, off int) (int, error) { 1797 return skipUint16(msg, off) 1798 } 1799 1800 // packClass appends the wire format of field to msg. 1801 func packClass(msg []byte, field Class) []byte { 1802 return packUint16(msg, uint16(field)) 1803 } 1804 1805 func unpackClass(msg []byte, off int) (Class, int, error) { 1806 c, o, err := unpackUint16(msg, off) 1807 return Class(c), o, err 1808 } 1809 1810 func skipClass(msg []byte, off int) (int, error) { 1811 return skipUint16(msg, off) 1812 } 1813 1814 // packUint32 appends the wire format of field to msg. 1815 func packUint32(msg []byte, field uint32) []byte { 1816 return append( 1817 msg, 1818 byte(field>>24), 1819 byte(field>>16), 1820 byte(field>>8), 1821 byte(field), 1822 ) 1823 } 1824 1825 func unpackUint32(msg []byte, off int) (uint32, int, error) { 1826 if off+uint32Len > len(msg) { 1827 return 0, off, errBaseLen 1828 } 1829 v := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3]) 1830 return v, off + uint32Len, nil 1831 } 1832 1833 func skipUint32(msg []byte, off int) (int, error) { 1834 if off+uint32Len > len(msg) { 1835 return off, errBaseLen 1836 } 1837 return off + uint32Len, nil 1838 } 1839 1840 // packText appends the wire format of field to msg. 1841 func packText(msg []byte, field string) ([]byte, error) { 1842 l := len(field) 1843 if l > 255 { 1844 return nil, errStringTooLong 1845 } 1846 msg = append(msg, byte(l)) 1847 msg = append(msg, field...) 1848 1849 return msg, nil 1850 } 1851 1852 func unpackText(msg []byte, off int) (string, int, error) { 1853 if off >= len(msg) { 1854 return "", off, errBaseLen 1855 } 1856 beginOff := off + 1 1857 endOff := beginOff + int(msg[off]) 1858 if endOff > len(msg) { 1859 return "", off, errCalcLen 1860 } 1861 return string(msg[beginOff:endOff]), endOff, nil 1862 } 1863 1864 // packBytes appends the wire format of field to msg. 1865 func packBytes(msg []byte, field []byte) []byte { 1866 return append(msg, field...) 1867 } 1868 1869 func unpackBytes(msg []byte, off int, field []byte) (int, error) { 1870 newOff := off + len(field) 1871 if newOff > len(msg) { 1872 return off, errBaseLen 1873 } 1874 copy(field, msg[off:newOff]) 1875 return newOff, nil 1876 } 1877 1878 const nameLen = 255 1879 1880 // A Name is a non-encoded domain name. It is used instead of strings to avoid 1881 // allocations. 1882 type Name struct { 1883 Data [nameLen]byte // 255 bytes 1884 Length uint8 1885 } 1886 1887 // NewName creates a new Name from a string. 1888 func NewName(name string) (Name, error) { 1889 if len([]byte(name)) > nameLen { 1890 return Name{}, errCalcLen 1891 } 1892 n := Name{Length: uint8(len(name))} 1893 copy(n.Data[:], []byte(name)) 1894 return n, nil 1895 } 1896 1897 // MustNewName creates a new Name from a string and panics on error. 1898 func MustNewName(name string) Name { 1899 n, err := NewName(name) 1900 if err != nil { 1901 panic("creating name: " + err.Error()) 1902 } 1903 return n 1904 } 1905 1906 // String implements fmt.Stringer.String. 1907 func (n Name) String() string { 1908 return string(n.Data[:n.Length]) 1909 } 1910 1911 // GoString implements fmt.GoStringer.GoString. 1912 func (n *Name) GoString() string { 1913 return `dnsmessage.MustNewName("` + printString(n.Data[:n.Length]) + `")` 1914 } 1915 1916 // pack appends the wire format of the Name to msg. 1917 // 1918 // Domain names are a sequence of counted strings split at the dots. They end 1919 // with a zero-length string. Compression can be used to reuse domain suffixes. 1920 // 1921 // The compression map will be updated with new domain suffixes. If compression 1922 // is nil, compression will not be used. 1923 func (n *Name) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 1924 oldMsg := msg 1925 1926 // Add a trailing dot to canonicalize name. 1927 if n.Length == 0 || n.Data[n.Length-1] != '.' { 1928 return oldMsg, errNonCanonicalName 1929 } 1930 1931 // Allow root domain. 1932 if n.Data[0] == '.' && n.Length == 1 { 1933 return append(msg, 0), nil 1934 } 1935 1936 // Emit sequence of counted strings, chopping at dots. 1937 for i, begin := 0, 0; i < int(n.Length); i++ { 1938 // Check for the end of the segment. 1939 if n.Data[i] == '.' { 1940 // The two most significant bits have special meaning. 1941 // It isn't allowed for segments to be long enough to 1942 // need them. 1943 if i-begin >= 1<<6 { 1944 return oldMsg, errSegTooLong 1945 } 1946 1947 // Segments must have a non-zero length. 1948 if i-begin == 0 { 1949 return oldMsg, errZeroSegLen 1950 } 1951 1952 msg = append(msg, byte(i-begin)) 1953 1954 for j := begin; j < i; j++ { 1955 msg = append(msg, n.Data[j]) 1956 } 1957 1958 begin = i + 1 1959 continue 1960 } 1961 1962 // We can only compress domain suffixes starting with a new 1963 // segment. A pointer is two bytes with the two most significant 1964 // bits set to 1 to indicate that it is a pointer. 1965 if (i == 0 || n.Data[i-1] == '.') && compression != nil { 1966 if ptr, ok := compression[string(n.Data[i:])]; ok { 1967 // Hit. Emit a pointer instead of the rest of 1968 // the domain. 1969 return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil 1970 } 1971 1972 // Miss. Add the suffix to the compression table if the 1973 // offset can be stored in the available 14 bytes. 1974 if len(msg) <= int(^uint16(0)>>2) { 1975 compression[string(n.Data[i:])] = len(msg) - compressionOff 1976 } 1977 } 1978 } 1979 return append(msg, 0), nil 1980 } 1981 1982 // unpack unpacks a domain name. 1983 func (n *Name) unpack(msg []byte, off int) (int, error) { 1984 return n.unpackCompressed(msg, off, true /* allowCompression */) 1985 } 1986 1987 func (n *Name) unpackCompressed(msg []byte, off int, allowCompression bool) (int, error) { 1988 // currOff is the current working offset. 1989 currOff := off 1990 1991 // newOff is the offset where the next record will start. Pointers lead 1992 // to data that belongs to other names and thus doesn't count towards to 1993 // the usage of this name. 1994 newOff := off 1995 1996 // ptr is the number of pointers followed. 1997 var ptr int 1998 1999 // Name is a slice representation of the name data. 2000 name := n.Data[:0] 2001 2002 Loop: 2003 for { 2004 if currOff >= len(msg) { 2005 return off, errBaseLen 2006 } 2007 c := int(msg[currOff]) 2008 currOff++ 2009 switch c & 0xC0 { 2010 case 0x00: // String segment 2011 if c == 0x00 { 2012 // A zero length signals the end of the name. 2013 break Loop 2014 } 2015 endOff := currOff + c 2016 if endOff > len(msg) { 2017 return off, errCalcLen 2018 } 2019 name = append(name, msg[currOff:endOff]...) 2020 name = append(name, '.') 2021 currOff = endOff 2022 case 0xC0: // Pointer 2023 if !allowCompression { 2024 return off, errCompressedSRV 2025 } 2026 if currOff >= len(msg) { 2027 return off, errInvalidPtr 2028 } 2029 c1 := msg[currOff] 2030 currOff++ 2031 if ptr == 0 { 2032 newOff = currOff 2033 } 2034 // Don't follow too many pointers, maybe there's a loop. 2035 if ptr++; ptr > 10 { 2036 return off, errTooManyPtr 2037 } 2038 currOff = (c^0xC0)<<8 | int(c1) 2039 default: 2040 // Prefixes 0x80 and 0x40 are reserved. 2041 return off, errReserved 2042 } 2043 } 2044 if len(name) == 0 { 2045 name = append(name, '.') 2046 } 2047 if len(name) > len(n.Data) { 2048 return off, errCalcLen 2049 } 2050 n.Length = uint8(len(name)) 2051 if ptr == 0 { 2052 newOff = currOff 2053 } 2054 return newOff, nil 2055 } 2056 2057 func skipName(msg []byte, off int) (int, error) { 2058 // newOff is the offset where the next record will start. Pointers lead 2059 // to data that belongs to other names and thus doesn't count towards to 2060 // the usage of this name. 2061 newOff := off 2062 2063 Loop: 2064 for { 2065 if newOff >= len(msg) { 2066 return off, errBaseLen 2067 } 2068 c := int(msg[newOff]) 2069 newOff++ 2070 switch c & 0xC0 { 2071 case 0x00: 2072 if c == 0x00 { 2073 // A zero length signals the end of the name. 2074 break Loop 2075 } 2076 // literal string 2077 newOff += c 2078 if newOff > len(msg) { 2079 return off, errCalcLen 2080 } 2081 case 0xC0: 2082 // Pointer to somewhere else in msg. 2083 2084 // Pointers are two bytes. 2085 newOff++ 2086 2087 // Don't follow the pointer as the data here has ended. 2088 break Loop 2089 default: 2090 // Prefixes 0x80 and 0x40 are reserved. 2091 return off, errReserved 2092 } 2093 } 2094 2095 return newOff, nil 2096 } 2097 2098 // A Question is a DNS query. 2099 type Question struct { 2100 Name Name 2101 Type Type 2102 Class Class 2103 } 2104 2105 // pack appends the wire format of the Question to msg. 2106 func (q *Question) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2107 msg, err := q.Name.pack(msg, compression, compressionOff) 2108 if err != nil { 2109 return msg, &nestedError{"Name", err} 2110 } 2111 msg = packType(msg, q.Type) 2112 return packClass(msg, q.Class), nil 2113 } 2114 2115 // GoString implements fmt.GoStringer.GoString. 2116 func (q *Question) GoString() string { 2117 return "dnsmessage.Question{" + 2118 "Name: " + q.Name.GoString() + ", " + 2119 "Type: " + q.Type.GoString() + ", " + 2120 "Class: " + q.Class.GoString() + "}" 2121 } 2122 2123 func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, int, error) { 2124 var ( 2125 r ResourceBody 2126 err error 2127 name string 2128 ) 2129 switch hdr.Type { 2130 case TypeA: 2131 var rb AResource 2132 rb, err = unpackAResource(msg, off) 2133 r = &rb 2134 name = "A" 2135 case TypeNS: 2136 var rb NSResource 2137 rb, err = unpackNSResource(msg, off) 2138 r = &rb 2139 name = "NS" 2140 case TypeCNAME: 2141 var rb CNAMEResource 2142 rb, err = unpackCNAMEResource(msg, off) 2143 r = &rb 2144 name = "CNAME" 2145 case TypeSOA: 2146 var rb SOAResource 2147 rb, err = unpackSOAResource(msg, off) 2148 r = &rb 2149 name = "SOA" 2150 case TypePTR: 2151 var rb PTRResource 2152 rb, err = unpackPTRResource(msg, off) 2153 r = &rb 2154 name = "PTR" 2155 case TypeMX: 2156 var rb MXResource 2157 rb, err = unpackMXResource(msg, off) 2158 r = &rb 2159 name = "MX" 2160 case TypeTXT: 2161 var rb TXTResource 2162 rb, err = unpackTXTResource(msg, off, hdr.Length) 2163 r = &rb 2164 name = "TXT" 2165 case TypeAAAA: 2166 var rb AAAAResource 2167 rb, err = unpackAAAAResource(msg, off) 2168 r = &rb 2169 name = "AAAA" 2170 case TypeSRV: 2171 var rb SRVResource 2172 rb, err = unpackSRVResource(msg, off) 2173 r = &rb 2174 name = "SRV" 2175 case TypeOPT: 2176 var rb OPTResource 2177 rb, err = unpackOPTResource(msg, off, hdr.Length) 2178 r = &rb 2179 name = "OPT" 2180 default: 2181 var rb UnknownResource 2182 rb, err = unpackUnknownResource(hdr.Type, msg, off, hdr.Length) 2183 r = &rb 2184 name = "Unknown" 2185 } 2186 if err != nil { 2187 return nil, off, &nestedError{name + " record", err} 2188 } 2189 return r, off + int(hdr.Length), nil 2190 } 2191 2192 // A CNAMEResource is a CNAME Resource record. 2193 type CNAMEResource struct { 2194 CNAME Name 2195 } 2196 2197 func (r *CNAMEResource) realType() Type { 2198 return TypeCNAME 2199 } 2200 2201 // pack appends the wire format of the CNAMEResource to msg. 2202 func (r *CNAMEResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2203 return r.CNAME.pack(msg, compression, compressionOff) 2204 } 2205 2206 // GoString implements fmt.GoStringer.GoString. 2207 func (r *CNAMEResource) GoString() string { 2208 return "dnsmessage.CNAMEResource{CNAME: " + r.CNAME.GoString() + "}" 2209 } 2210 2211 func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) { 2212 var cname Name 2213 if _, err := cname.unpack(msg, off); err != nil { 2214 return CNAMEResource{}, err 2215 } 2216 return CNAMEResource{cname}, nil 2217 } 2218 2219 // An MXResource is an MX Resource record. 2220 type MXResource struct { 2221 Pref uint16 2222 MX Name 2223 } 2224 2225 func (r *MXResource) realType() Type { 2226 return TypeMX 2227 } 2228 2229 // pack appends the wire format of the MXResource to msg. 2230 func (r *MXResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2231 oldMsg := msg 2232 msg = packUint16(msg, r.Pref) 2233 msg, err := r.MX.pack(msg, compression, compressionOff) 2234 if err != nil { 2235 return oldMsg, &nestedError{"MXResource.MX", err} 2236 } 2237 return msg, nil 2238 } 2239 2240 // GoString implements fmt.GoStringer.GoString. 2241 func (r *MXResource) GoString() string { 2242 return "dnsmessage.MXResource{" + 2243 "Pref: " + printUint16(r.Pref) + ", " + 2244 "MX: " + r.MX.GoString() + "}" 2245 } 2246 2247 func unpackMXResource(msg []byte, off int) (MXResource, error) { 2248 pref, off, err := unpackUint16(msg, off) 2249 if err != nil { 2250 return MXResource{}, &nestedError{"Pref", err} 2251 } 2252 var mx Name 2253 if _, err := mx.unpack(msg, off); err != nil { 2254 return MXResource{}, &nestedError{"MX", err} 2255 } 2256 return MXResource{pref, mx}, nil 2257 } 2258 2259 // An NSResource is an NS Resource record. 2260 type NSResource struct { 2261 NS Name 2262 } 2263 2264 func (r *NSResource) realType() Type { 2265 return TypeNS 2266 } 2267 2268 // pack appends the wire format of the NSResource to msg. 2269 func (r *NSResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2270 return r.NS.pack(msg, compression, compressionOff) 2271 } 2272 2273 // GoString implements fmt.GoStringer.GoString. 2274 func (r *NSResource) GoString() string { 2275 return "dnsmessage.NSResource{NS: " + r.NS.GoString() + "}" 2276 } 2277 2278 func unpackNSResource(msg []byte, off int) (NSResource, error) { 2279 var ns Name 2280 if _, err := ns.unpack(msg, off); err != nil { 2281 return NSResource{}, err 2282 } 2283 return NSResource{ns}, nil 2284 } 2285 2286 // A PTRResource is a PTR Resource record. 2287 type PTRResource struct { 2288 PTR Name 2289 } 2290 2291 func (r *PTRResource) realType() Type { 2292 return TypePTR 2293 } 2294 2295 // pack appends the wire format of the PTRResource to msg. 2296 func (r *PTRResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2297 return r.PTR.pack(msg, compression, compressionOff) 2298 } 2299 2300 // GoString implements fmt.GoStringer.GoString. 2301 func (r *PTRResource) GoString() string { 2302 return "dnsmessage.PTRResource{PTR: " + r.PTR.GoString() + "}" 2303 } 2304 2305 func unpackPTRResource(msg []byte, off int) (PTRResource, error) { 2306 var ptr Name 2307 if _, err := ptr.unpack(msg, off); err != nil { 2308 return PTRResource{}, err 2309 } 2310 return PTRResource{ptr}, nil 2311 } 2312 2313 // An SOAResource is an SOA Resource record. 2314 type SOAResource struct { 2315 NS Name 2316 MBox Name 2317 Serial uint32 2318 Refresh uint32 2319 Retry uint32 2320 Expire uint32 2321 2322 // MinTTL the is the default TTL of Resources records which did not 2323 // contain a TTL value and the TTL of negative responses. (RFC 2308 2324 // Section 4) 2325 MinTTL uint32 2326 } 2327 2328 func (r *SOAResource) realType() Type { 2329 return TypeSOA 2330 } 2331 2332 // pack appends the wire format of the SOAResource to msg. 2333 func (r *SOAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2334 oldMsg := msg 2335 msg, err := r.NS.pack(msg, compression, compressionOff) 2336 if err != nil { 2337 return oldMsg, &nestedError{"SOAResource.NS", err} 2338 } 2339 msg, err = r.MBox.pack(msg, compression, compressionOff) 2340 if err != nil { 2341 return oldMsg, &nestedError{"SOAResource.MBox", err} 2342 } 2343 msg = packUint32(msg, r.Serial) 2344 msg = packUint32(msg, r.Refresh) 2345 msg = packUint32(msg, r.Retry) 2346 msg = packUint32(msg, r.Expire) 2347 return packUint32(msg, r.MinTTL), nil 2348 } 2349 2350 // GoString implements fmt.GoStringer.GoString. 2351 func (r *SOAResource) GoString() string { 2352 return "dnsmessage.SOAResource{" + 2353 "NS: " + r.NS.GoString() + ", " + 2354 "MBox: " + r.MBox.GoString() + ", " + 2355 "Serial: " + printUint32(r.Serial) + ", " + 2356 "Refresh: " + printUint32(r.Refresh) + ", " + 2357 "Retry: " + printUint32(r.Retry) + ", " + 2358 "Expire: " + printUint32(r.Expire) + ", " + 2359 "MinTTL: " + printUint32(r.MinTTL) + "}" 2360 } 2361 2362 func unpackSOAResource(msg []byte, off int) (SOAResource, error) { 2363 var ns Name 2364 off, err := ns.unpack(msg, off) 2365 if err != nil { 2366 return SOAResource{}, &nestedError{"NS", err} 2367 } 2368 var mbox Name 2369 if off, err = mbox.unpack(msg, off); err != nil { 2370 return SOAResource{}, &nestedError{"MBox", err} 2371 } 2372 serial, off, err := unpackUint32(msg, off) 2373 if err != nil { 2374 return SOAResource{}, &nestedError{"Serial", err} 2375 } 2376 refresh, off, err := unpackUint32(msg, off) 2377 if err != nil { 2378 return SOAResource{}, &nestedError{"Refresh", err} 2379 } 2380 retry, off, err := unpackUint32(msg, off) 2381 if err != nil { 2382 return SOAResource{}, &nestedError{"Retry", err} 2383 } 2384 expire, off, err := unpackUint32(msg, off) 2385 if err != nil { 2386 return SOAResource{}, &nestedError{"Expire", err} 2387 } 2388 minTTL, _, err := unpackUint32(msg, off) 2389 if err != nil { 2390 return SOAResource{}, &nestedError{"MinTTL", err} 2391 } 2392 return SOAResource{ns, mbox, serial, refresh, retry, expire, minTTL}, nil 2393 } 2394 2395 // A TXTResource is a TXT Resource record. 2396 type TXTResource struct { 2397 TXT []string 2398 } 2399 2400 func (r *TXTResource) realType() Type { 2401 return TypeTXT 2402 } 2403 2404 // pack appends the wire format of the TXTResource to msg. 2405 func (r *TXTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2406 oldMsg := msg 2407 for _, s := range r.TXT { 2408 var err error 2409 msg, err = packText(msg, s) 2410 if err != nil { 2411 return oldMsg, err 2412 } 2413 } 2414 return msg, nil 2415 } 2416 2417 // GoString implements fmt.GoStringer.GoString. 2418 func (r *TXTResource) GoString() string { 2419 s := "dnsmessage.TXTResource{TXT: []string{" 2420 if len(r.TXT) == 0 { 2421 return s + "}}" 2422 } 2423 s += `"` + printString([]byte(r.TXT[0])) 2424 for _, t := range r.TXT[1:] { 2425 s += `", "` + printString([]byte(t)) 2426 } 2427 return s + `"}}` 2428 } 2429 2430 func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) { 2431 txts := make([]string, 0, 1) 2432 for n := uint16(0); n < length; { 2433 var t string 2434 var err error 2435 if t, off, err = unpackText(msg, off); err != nil { 2436 return TXTResource{}, &nestedError{"text", err} 2437 } 2438 // Check if we got too many bytes. 2439 if length-n < uint16(len(t))+1 { 2440 return TXTResource{}, errCalcLen 2441 } 2442 n += uint16(len(t)) + 1 2443 txts = append(txts, t) 2444 } 2445 return TXTResource{txts}, nil 2446 } 2447 2448 // An SRVResource is an SRV Resource record. 2449 type SRVResource struct { 2450 Priority uint16 2451 Weight uint16 2452 Port uint16 2453 Target Name // Not compressed as per RFC 2782. 2454 } 2455 2456 func (r *SRVResource) realType() Type { 2457 return TypeSRV 2458 } 2459 2460 // pack appends the wire format of the SRVResource to msg. 2461 func (r *SRVResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2462 oldMsg := msg 2463 msg = packUint16(msg, r.Priority) 2464 msg = packUint16(msg, r.Weight) 2465 msg = packUint16(msg, r.Port) 2466 msg, err := r.Target.pack(msg, nil, compressionOff) 2467 if err != nil { 2468 return oldMsg, &nestedError{"SRVResource.Target", err} 2469 } 2470 return msg, nil 2471 } 2472 2473 // GoString implements fmt.GoStringer.GoString. 2474 func (r *SRVResource) GoString() string { 2475 return "dnsmessage.SRVResource{" + 2476 "Priority: " + printUint16(r.Priority) + ", " + 2477 "Weight: " + printUint16(r.Weight) + ", " + 2478 "Port: " + printUint16(r.Port) + ", " + 2479 "Target: " + r.Target.GoString() + "}" 2480 } 2481 2482 func unpackSRVResource(msg []byte, off int) (SRVResource, error) { 2483 priority, off, err := unpackUint16(msg, off) 2484 if err != nil { 2485 return SRVResource{}, &nestedError{"Priority", err} 2486 } 2487 weight, off, err := unpackUint16(msg, off) 2488 if err != nil { 2489 return SRVResource{}, &nestedError{"Weight", err} 2490 } 2491 port, off, err := unpackUint16(msg, off) 2492 if err != nil { 2493 return SRVResource{}, &nestedError{"Port", err} 2494 } 2495 var target Name 2496 if _, err := target.unpackCompressed(msg, off, false /* allowCompression */); err != nil { 2497 return SRVResource{}, &nestedError{"Target", err} 2498 } 2499 return SRVResource{priority, weight, port, target}, nil 2500 } 2501 2502 // An AResource is an A Resource record. 2503 type AResource struct { 2504 A [4]byte 2505 } 2506 2507 func (r *AResource) realType() Type { 2508 return TypeA 2509 } 2510 2511 // pack appends the wire format of the AResource to msg. 2512 func (r *AResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2513 return packBytes(msg, r.A[:]), nil 2514 } 2515 2516 // GoString implements fmt.GoStringer.GoString. 2517 func (r *AResource) GoString() string { 2518 return "dnsmessage.AResource{" + 2519 "A: [4]byte{" + printByteSlice(r.A[:]) + "}}" 2520 } 2521 2522 func unpackAResource(msg []byte, off int) (AResource, error) { 2523 var a [4]byte 2524 if _, err := unpackBytes(msg, off, a[:]); err != nil { 2525 return AResource{}, err 2526 } 2527 return AResource{a}, nil 2528 } 2529 2530 // An AAAAResource is an AAAA Resource record. 2531 type AAAAResource struct { 2532 AAAA [16]byte 2533 } 2534 2535 func (r *AAAAResource) realType() Type { 2536 return TypeAAAA 2537 } 2538 2539 // GoString implements fmt.GoStringer.GoString. 2540 func (r *AAAAResource) GoString() string { 2541 return "dnsmessage.AAAAResource{" + 2542 "AAAA: [16]byte{" + printByteSlice(r.AAAA[:]) + "}}" 2543 } 2544 2545 // pack appends the wire format of the AAAAResource to msg. 2546 func (r *AAAAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2547 return packBytes(msg, r.AAAA[:]), nil 2548 } 2549 2550 func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) { 2551 var aaaa [16]byte 2552 if _, err := unpackBytes(msg, off, aaaa[:]); err != nil { 2553 return AAAAResource{}, err 2554 } 2555 return AAAAResource{aaaa}, nil 2556 } 2557 2558 // An OPTResource is an OPT pseudo Resource record. 2559 // 2560 // The pseudo resource record is part of the extension mechanisms for DNS 2561 // as defined in RFC 6891. 2562 type OPTResource struct { 2563 Options []Option 2564 } 2565 2566 // An Option represents a DNS message option within OPTResource. 2567 // 2568 // The message option is part of the extension mechanisms for DNS as 2569 // defined in RFC 6891. 2570 type Option struct { 2571 Code uint16 // option code 2572 Data []byte 2573 } 2574 2575 // GoString implements fmt.GoStringer.GoString. 2576 func (o *Option) GoString() string { 2577 return "dnsmessage.Option{" + 2578 "Code: " + printUint16(o.Code) + ", " + 2579 "Data: []byte{" + printByteSlice(o.Data) + "}}" 2580 } 2581 2582 func (r *OPTResource) realType() Type { 2583 return TypeOPT 2584 } 2585 2586 func (r *OPTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2587 for _, opt := range r.Options { 2588 msg = packUint16(msg, opt.Code) 2589 l := uint16(len(opt.Data)) 2590 msg = packUint16(msg, l) 2591 msg = packBytes(msg, opt.Data) 2592 } 2593 return msg, nil 2594 } 2595 2596 // GoString implements fmt.GoStringer.GoString. 2597 func (r *OPTResource) GoString() string { 2598 s := "dnsmessage.OPTResource{Options: []dnsmessage.Option{" 2599 if len(r.Options) == 0 { 2600 return s + "}}" 2601 } 2602 s += r.Options[0].GoString() 2603 for _, o := range r.Options[1:] { 2604 s += ", " + o.GoString() 2605 } 2606 return s + "}}" 2607 } 2608 2609 func unpackOPTResource(msg []byte, off int, length uint16) (OPTResource, error) { 2610 var opts []Option 2611 for oldOff := off; off < oldOff+int(length); { 2612 var err error 2613 var o Option 2614 o.Code, off, err = unpackUint16(msg, off) 2615 if err != nil { 2616 return OPTResource{}, &nestedError{"Code", err} 2617 } 2618 var l uint16 2619 l, off, err = unpackUint16(msg, off) 2620 if err != nil { 2621 return OPTResource{}, &nestedError{"Data", err} 2622 } 2623 o.Data = make([]byte, l) 2624 if copy(o.Data, msg[off:]) != int(l) { 2625 return OPTResource{}, &nestedError{"Data", errCalcLen} 2626 } 2627 off += int(l) 2628 opts = append(opts, o) 2629 } 2630 return OPTResource{opts}, nil 2631 } 2632 2633 // An UnknownResource is a catch-all container for unknown record types. 2634 type UnknownResource struct { 2635 Type Type 2636 Data []byte 2637 } 2638 2639 func (r *UnknownResource) realType() Type { 2640 return r.Type 2641 } 2642 2643 // pack appends the wire format of the UnknownResource to msg. 2644 func (r *UnknownResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { 2645 return packBytes(msg, r.Data[:]), nil 2646 } 2647 2648 // GoString implements fmt.GoStringer.GoString. 2649 func (r *UnknownResource) GoString() string { 2650 return "dnsmessage.UnknownResource{" + 2651 "Type: " + r.Type.GoString() + ", " + 2652 "Data: []byte{" + printByteSlice(r.Data) + "}}" 2653 } 2654 2655 func unpackUnknownResource(recordType Type, msg []byte, off int, length uint16) (UnknownResource, error) { 2656 parsed := UnknownResource{ 2657 Type: recordType, 2658 Data: make([]byte, length), 2659 } 2660 if _, err := unpackBytes(msg, off, parsed.Data); err != nil { 2661 return UnknownResource{}, err 2662 } 2663 return parsed, nil 2664 }