Source file src/vendor/golang.org/x/net/dns/dnsmessage/message.go

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

View as plain text