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