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