...

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

Documentation: vendor/golang.org/x/net/dns/dnsmessage

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

View as plain text