github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/dns/resolver/resolve.go (about)

     1  package dns
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"math/rand/v2"
     8  	"net"
     9  	"strings"
    10  
    11  	"github.com/Asutorufa/yuhaiin/pkg/log"
    12  )
    13  
    14  type reqType [2]byte
    15  
    16  var (
    17  	A     = reqType{0b00000000, 0b00000001} // 1
    18  	NS    = reqType{0b00000000, 0b00000010} // 2
    19  	MD    = reqType{0b00000000, 0b00000011} // 3
    20  	MF    = reqType{0b00000000, 0b00000100} // 3
    21  	CNAME = reqType{0b00000000, 0b00000101} // 5
    22  	SOA   = reqType{0b00000000, 0b00000110} // 6
    23  	MB    = reqType{0b00000000, 0b00000111} // 7
    24  	MG    = reqType{0b00000000, 0b00001000} // 8
    25  	MR    = reqType{0b00000000, 0b00001001} // 9
    26  	NULL  = reqType{0b00000000, 0b00001010} // 10
    27  	WKS   = reqType{0b00000000, 0b00001011} // 11
    28  	PTR   = reqType{0b00000000, 0b00001100} // 12
    29  	HINFO = reqType{0b00000000, 0b00001101} // 13
    30  	MINFO = reqType{0b00000000, 0b00001110} // 14
    31  	MX    = reqType{0b00000000, 0b00001111} // 15
    32  	TXT   = reqType{0b00000000, 0b00010000} // 16
    33  	AAAA  = reqType{0b00000000, 0b00011100} // 28 https://www.ietf.org/rfc/rfc3596.txt
    34  	RRSIG = reqType{0b00000000, 0b00101110} // 46 dnssec
    35  
    36  	// only for req
    37  	AXFR = reqType{0b00000000, 0b11111100} // 252
    38  	ANY  = reqType{0b00000000, 0b11111111} // 255
    39  )
    40  
    41  func creatRequest(domain string, reqType reqType, arCount bool) []byte {
    42  	data := bytes.NewBuffer(nil)
    43  	data.Write([]byte{byte(rand.UintN(255)), byte(rand.UintN(255))}) // id
    44  	// qr 0, opcode 0000, aa 0, tc 0, rd 1 => 1 byte, ra 0, z 000, rCode 0000 => 1 byte
    45  	data.Write([]byte{0b0<<7 + 0b0000<<3 + 0b0<<2 + 0b0<<1 + 0b1, 0b0<<7 + 0b000<<4 + 0b0000})
    46  	data.Write([]byte{0b00000000, 0b00000001}) // qdCount: request number => bit: 00000000 00000001 -> 01
    47  	data.Write([]byte{0b00000000, 0b00000000}) // anCount: answer number(no use for req) => bit: 00000000 00000000
    48  	data.Write([]byte{0b00000000, 0b00000000}) // nsCount: authority section 2 bytes
    49  	if arCount {                               // arCount: additional section 2 bytes
    50  		data.Write([]byte{0b00000000, 0b00000001})
    51  	} else {
    52  		data.Write([]byte{0b00000000, 0b00000000})
    53  	}
    54  
    55  	domain = domain + "." // domain: www.example.com => 3www7example3com <- last with 0
    56  	for i := strings.IndexByte(domain, '.'); i != -1; i = strings.IndexByte(domain, '.') {
    57  		data.WriteByte(byte(i))
    58  		data.WriteString(domain[:i])
    59  		domain = domain[i+1:]
    60  	}
    61  	data.WriteByte(0b00000000) // add the 0 for last of domain
    62  
    63  	data.Write([]byte{reqType[0], reqType[1]}) // qType 1 -> A:ipv4 01 | 28 -> AAAA:ipv6  000000 00011100 => 0 0x1c
    64  	data.Write([]byte{0b00000000, 0b00000001}) // qClass: 1 = from internet
    65  	return data.Bytes()
    66  }
    67  
    68  type respHeader struct {
    69  	qdCount  int
    70  	anCount  int
    71  	nsCount  int
    72  	arCount  int
    73  	dnsType  reqType
    74  	isAnswer bool
    75  	name     string
    76  }
    77  
    78  type resolver struct {
    79  	i       int
    80  	request []byte
    81  	aswer   []byte
    82  	h       respHeader
    83  }
    84  
    85  func Resolve(req, answer []byte) (resp []net.IP, err error) {
    86  	defer func() {
    87  		r := recover()
    88  		if r != nil {
    89  			err = fmt.Errorf("recovering from panic resolve: %v", r)
    90  		}
    91  	}()
    92  	r := &resolver{request: req, aswer: answer}
    93  	err = r.header()
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  	if !r.h.isAnswer {
    98  		return nil, fmt.Errorf("the qr (%d&%d=%d) is not 1(Answer)", r.aswer[2], 128, r.aswer[2]&128)
    99  	}
   100  	resp, err = r.answer()
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	r.authoritative()
   105  	r.additional()
   106  	return resp, nil
   107  }
   108  
   109  func (r *resolver) header() (err error) {
   110  	if r.aswer[0] != r.request[0] || r.aswer[1] != r.request[1] {
   111  		return errors.New("id not same")
   112  	}
   113  
   114  	if r.aswer[2]&128 != 0 { // check the QR is 1(Answer)
   115  		r.h.isAnswer = true
   116  	}
   117  
   118  	switch r.aswer[3] & 0b00001111 { // check Response code(rCode) eg:11110010 & 00001111 = 0010, 11111101 & 00001111 = 1101
   119  	case 0b0000: // 0 no error
   120  		break
   121  	case 0b0001: // 1 Format error
   122  		err = errors.New("request format error")
   123  	case 0b0010: // 2 Server failure
   124  		err = errors.New("dns Server failure")
   125  	case 0b0011: // 3 Name Error
   126  		err = errors.New("no such name")
   127  	case 0b0100: // 4 Not Implemented
   128  		err = errors.New("dns server not support this request")
   129  	case 0b0101: // 5 Refused
   130  		err = errors.New("dns server Refuse")
   131  	default: // 6-15 Reserved for future use.
   132  		err = fmt.Errorf("reserved for future use, code: %b", r.aswer[3]&0b00001111)
   133  	}
   134  	if err != nil {
   135  		return err
   136  	}
   137  
   138  	r.h.qdCount = int(r.aswer[4])<<8 + int(r.aswer[5])   // request
   139  	r.h.anCount = int(r.aswer[6])<<8 + int(r.aswer[7])   // answer Count
   140  	r.h.nsCount = int(r.aswer[8])<<8 + int(r.aswer[9])   // authority Count
   141  	r.h.arCount = int(r.aswer[10])<<8 + int(r.aswer[11]) // additional Count
   142  
   143  	r.i = 12
   144  
   145  	var size int
   146  	r.h.name, size = r.getName(r.i)
   147  	r.i += size
   148  
   149  	// fmt.Println(r.h)
   150  
   151  	r.h.dnsType = reqType{r.aswer[r.i], r.aswer[r.i+1]}
   152  	r.i += 2 // qType
   153  	r.i += 2 // qClass
   154  
   155  	return nil
   156  }
   157  
   158  func (r *resolver) answer() (DNS []net.IP, err error) {
   159  	i := r.h.anCount
   160  _start:
   161  	i--
   162  	if i < 0 {
   163  		return
   164  	}
   165  
   166  	_, size := r.getName(r.i)
   167  	r.i += size
   168  
   169  	tYPE := reqType{r.aswer[r.i], r.aswer[r.i+1]}
   170  	r.i += 2 //type
   171  	r.i += 2 //class
   172  	r.i += 4 // ttl
   173  	sum := int(r.aswer[r.i])<<8 + int(r.aswer[r.i+1])
   174  	r.i += 2 // RDLENGTH  jump sum 2+int(c[0])<<8+int(c[1])
   175  
   176  	switch tYPE {
   177  	case A:
   178  		DNS = append(DNS, r.aswer[r.i:r.i+4])
   179  		r.i += 4 // 4 byte ip addr
   180  	case AAAA:
   181  		DNS = append(DNS, r.aswer[r.i:r.i+16])
   182  		r.i += 16 // 16 byte ip addr
   183  	case RRSIG:
   184  		typeCover := r.aswer[r.i : r.i+2]
   185  		r.i += 2
   186  		algorithm := r.aswer[r.i : r.i+1]
   187  		r.i++
   188  		label := r.aswer[r.i : r.i+1]
   189  		r.i++
   190  		originalTTL := r.aswer[r.i : r.i+4]
   191  		r.i += 4
   192  		signExpiration := r.aswer[r.i : r.i+4]
   193  		r.i += 4
   194  		signInception := r.aswer[r.i : r.i+4]
   195  		r.i += 4
   196  		keyTag := r.aswer[r.i : r.i+2]
   197  		r.i += 2
   198  		signName, size := r.getName(r.i)
   199  		r.i += size
   200  		signature := r.aswer[r.i : r.i+sum-size-18]
   201  		r.i += sum - size - 18
   202  		log.Debug(fmt.Sprintln(typeCover, algorithm, label, originalTTL, signExpiration, signInception, keyTag, signName, signature))
   203  	case NS, MD, MF, CNAME, SOA, MG, MB, MR, NULL, WKS, PTR, HINFO, MINFO, MX, TXT:
   204  		fallthrough
   205  	default:
   206  		r.i += sum // RDATA
   207  	}
   208  	goto _start
   209  }
   210  
   211  func (r *resolver) authoritative() {
   212  	i := r.h.nsCount
   213  _start:
   214  	i--
   215  	if i < 0 {
   216  		return
   217  	}
   218  	_, size := r.getName(r.i)
   219  	r.i += size
   220  	r.i += 2 // type
   221  	r.i += 2 // class
   222  	r.i += 2 // ttl
   223  	dataLength := int(r.aswer[r.i])<<8 + int(r.aswer[r.i+1])
   224  	r.i += 2 // data length
   225  	r.i += dataLength
   226  	goto _start
   227  }
   228  
   229  func (r *resolver) additional() {
   230  	i := r.h.arCount
   231  _start:
   232  	i--
   233  	if i < 0 {
   234  		return
   235  	}
   236  	r.i++ // name
   237  	typeE := r.aswer[r.i : r.i+2]
   238  	r.i += 2 // type
   239  	r.i += 2 // payLoadSize
   240  	r.i++    // rCode
   241  	r.i++    // version
   242  	r.i += 2 // Z
   243  	dataLength := int(r.aswer[r.i])<<8 + int(r.aswer[r.i+1])
   244  	r.i += 2
   245  	if typeE[0] != 0 || typeE[1] != 41 {
   246  		r.i += dataLength // optData
   247  		goto _start
   248  	}
   249  
   250  	if dataLength == 0 {
   251  		goto _start
   252  	}
   253  
   254  	optCode := EDNSOPT{r.aswer[r.i], r.aswer[r.i+1]}
   255  	r.i += 2
   256  	optionLength := int(r.aswer[r.i])<<8 + int(r.aswer[r.i+1])
   257  	r.i += 2
   258  	switch optCode {
   259  	case EdnsClientSubnet:
   260  		r.i += 2                // family
   261  		r.i++                   // source Netmask
   262  		r.i++                   // scope Netmask
   263  		r.i += optionLength - 4 // Subnet IP
   264  	default:
   265  		r.i += optionLength // opt data
   266  	}
   267  	goto _start
   268  }
   269  
   270  func (r *resolver) getName(i int) (name string, size int) {
   271  	s := strings.Builder{}
   272  	for {
   273  		if r.aswer[i] == 0 {
   274  			i++ // lastOfDomain: one byte 0
   275  			size++
   276  			break
   277  		}
   278  
   279  		if r.aswer[i]&128 == 128 && r.aswer[i]&64 == 64 {
   280  			l := r.aswer[i+1]
   281  			// fmt.Println(l)
   282  			i += 2
   283  			size += 2
   284  			tmp, _ := r.getName(int(l))
   285  			s.WriteString(tmp)
   286  			break
   287  		}
   288  
   289  		sectionLength := int(r.aswer[i]) + 1
   290  		s.Write(r.aswer[i+1 : i+sectionLength])
   291  		s.WriteString(".")
   292  		size += sectionLength
   293  		i += sectionLength
   294  	}
   295  	return s.String(), size
   296  }
   297  
   298  /*
   299  *      OLD
   300   */
   301  func resolveHeader(req []byte, answer []byte) (header respHeader, answerSection []byte, err error) {
   302  	// resolve answer
   303  	if answer[0] != req[0] || answer[1] != req[1] { // compare id
   304  		// not the answer
   305  		return header, nil, errors.New("id not same")
   306  	}
   307  
   308  	if answer[2]&128 != 0 { // check the QR is 1(Answer)
   309  		return header, nil, errors.New("the qr is not 1(Answer)")
   310  	}
   311  
   312  	switch answer[3] & 0b00001111 { // check Response code(rCode) eg:11110010 & 00001111 = 0010, 11111101 & 00001111 = 1101
   313  	case 0b0000: // 0 no error
   314  		break
   315  	case 0b0001: // 1 Format error
   316  		return header, nil, errors.New("request format error")
   317  	case 0b0010: // 2 Server failure
   318  		return header, nil, errors.New("dns Server failure")
   319  	case 0b0011: // 3 Name Error
   320  		return header, nil, errors.New("no such name")
   321  	case 0b0100: // 4 Not Implemented
   322  		return header, nil, errors.New("dns server not support this request")
   323  	case 0b0101: // 5 Refused
   324  		return header, nil, errors.New("dns server Refuse")
   325  	default: // 6-15 Reserved for future use.
   326  		return header, nil, fmt.Errorf("reserved for future use, code: %b", answer[3]&0b00001111)
   327  	}
   328  
   329  	header.qdCount = 0                                    // request
   330  	header.anCount = int(answer[6])<<8 + int(answer[7])   // answer Count
   331  	header.nsCount = int(answer[8])<<8 + int(answer[9])   // authority Count
   332  	header.arCount = int(answer[10])<<8 + int(answer[11]) // additional Count
   333  
   334  	c := answer[12:]
   335  
   336  	header.name, _, c = getName(c, answer)
   337  
   338  	c = c[2:] // qType
   339  	c = c[2:] // qClass
   340  
   341  	return header, c, nil
   342  }
   343  
   344  type answer interface {
   345  	Answer()
   346  }
   347  
   348  func resolveAnswer(c []byte, anCount int, b []byte) (DNS []net.IP, left []byte, err error) {
   349  	for i := anCount; i > 0; i-- {
   350  		_, _, c = getName(c, b)
   351  
   352  		tYPE := reqType{c[0], c[1]}
   353  		c = c[2:] // type
   354  		c = c[2:] // class
   355  		c = c[4:] // ttl 4byte
   356  		sum := int(c[0])<<8 + int(c[1])
   357  		c = c[2:] // RDLENGTH  jump sum 2+int(c[0])<<8+int(c[1])
   358  
   359  		switch tYPE {
   360  		case A:
   361  			DNS = append(DNS, c[0:4])
   362  			c = c[4:] // 4 byte ip addr
   363  		case AAAA:
   364  			DNS = append(DNS, c[0:16])
   365  			c = c[16:] // 16 byte ip addr
   366  		case RRSIG:
   367  			typeCover := c[:2]
   368  			c = c[2:]
   369  			algorithm := c[:1]
   370  			c = c[1:]
   371  			label := c[:1]
   372  			c = c[1:]
   373  			originalTTL := c[:4]
   374  			c = c[4:]
   375  			signExpiration := c[:4]
   376  			c = c[4:]
   377  			signInception := c[:4]
   378  			c = c[4:]
   379  			keyTag := c[:2]
   380  			c = c[2:]
   381  			signName, size, others := getName(c, b)
   382  			c = others
   383  			signature := c[:sum-size-18]
   384  			c = c[sum-size-18:]
   385  			log.Debug(fmt.Sprintln(typeCover, algorithm, label, originalTTL, signExpiration, signInception, keyTag, signName, signature))
   386  		case NS, MD, MF, CNAME, SOA, MG, MB, MR, NULL, WKS, PTR, HINFO, MINFO, MX, TXT:
   387  			fallthrough
   388  		default:
   389  			c = c[sum:] // RDATA
   390  		}
   391  	}
   392  	return DNS, c, nil
   393  }
   394  
   395  func resolveAuthoritative(c []byte, nsCount int, b []byte) (left []byte) {
   396  	for i := nsCount; i > 0; i-- {
   397  		_, _, c = getName(c, b)
   398  		c = c[2:] // type
   399  		c = c[2:] // class
   400  		c = c[4:] // ttl
   401  		dataLength := int(c[0])<<8 + int(c[1])
   402  		c = c[2:] // data length
   403  		c = c[dataLength:]
   404  	}
   405  	return c
   406  }
   407  
   408  func getName(c []byte, all []byte) (name string, size int, x []byte) {
   409  	s := strings.Builder{}
   410  	for {
   411  		if c[0] == 0 {
   412  			c = c[1:] // lastOfDomain: one byte 0
   413  			size++
   414  			break
   415  		}
   416  		if c[0]&128 == 128 && c[0]&64 == 64 {
   417  			l := c[1]
   418  			c = c[2:]
   419  			size += 2
   420  			tmp, _, _ := getName(all[l:], all)
   421  			s.WriteString(tmp)
   422  			break
   423  		}
   424  
   425  		s.Write(c[1 : int(c[0])+1])
   426  		s.WriteString(".")
   427  		size += int(c[0]) + 1
   428  		c = c[int(c[0])+1:]
   429  	}
   430  	return s.String(), size, c
   431  }
   432  
   433  type reader struct {
   434  	raw []byte
   435  	r   *bytes.Buffer
   436  }
   437  
   438  func newReader(raw []byte) *reader {
   439  	return &reader{raw: raw, r: bytes.NewBuffer(raw)}
   440  }
   441  
   442  func (r *reader) domain(rr *bytes.Buffer) (string, error) {
   443  	s := strings.Builder{}
   444  
   445  	var err error
   446  	for {
   447  		var b byte
   448  		if b, err = rr.ReadByte(); err != nil {
   449  			return "", fmt.Errorf("read byte failed: %w", err)
   450  		}
   451  
   452  		if b == 0 {
   453  			break
   454  		}
   455  
   456  		if b&128 == 128 && b&64 == 64 {
   457  			b, err = rr.ReadByte()
   458  			if err != nil {
   459  				return "", fmt.Errorf("read name offset failed: %w", err)
   460  			}
   461  			name, err := r.domain(bytes.NewBuffer(r.raw[b:]))
   462  			if err != nil {
   463  				return "", fmt.Errorf("read name failed: %w", err)
   464  			}
   465  			s.WriteString(name)
   466  			break
   467  		}
   468  
   469  		s.WriteString(string(rr.Next(int(b))))
   470  		s.WriteString(".")
   471  	}
   472  
   473  	return s.String(), nil
   474  }
   475  
   476  // https://www.ietf.org/rfc/rfc1035.txt
   477  /*
   478  4.1.1. Header section format
   479  
   480  The header contains the following fields:
   481  
   482                                      1  1  1  1  1  1
   483        0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
   484      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   485      |                      ID                       |
   486      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   487      |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
   488      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   489      |                    QDCOUNT                    |
   490      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   491      |                    ANCOUNT                    |
   492      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   493      |                    NSCOUNT                    |
   494      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   495      |                    ARCOUNT                    |
   496      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   497  
   498  where:
   499  
   500  ID              A 16 bit identifier assigned by the program that
   501                  generates any kind of query.  This identifier is copied
   502                  the corresponding reply and can be used by the requester
   503                  to match up replies to outstanding queries.
   504  QR              A one bit field that specifies whether this message is a
   505                  query (0), or a response (1).
   506  OPCODE          A four bit field that specifies kind of query in this
   507                  message.  This value is set by the originator of a query
   508                  and copied into the response.  The values are:
   509                  0               a standard query (QUERY)
   510                  1               an inverse query (IQUERY)
   511                  2               a server status request (STATUS)
   512                  3-15            reserved for future use
   513  AA              Authoritative Answer - this bit is valid in responses,
   514                  and specifies that the responding name server is an
   515                  authority for the domain name in question section.
   516                  Note that the contents of the answer section may have
   517                  multiple owner names because of aliases.  The AA bit
   518  
   519  
   520  
   521  Mockapetris                                                    [Page 26]
   522  
   523  RFC 1035        Domain Implementation and Specification    November 1987
   524  
   525  
   526                  corresponds to the name which matches the query name, or
   527                  the first owner name in the answer section.
   528  
   529  TC              TrunCation - specifies that this message was truncated
   530                  due to length greater than that permitted on the
   531                  transmission channel.
   532  RD              Recursion Desired - this bit may be set in a query and
   533                  is copied into the response.  If RD is set, it directs
   534                  the name server to pursue the query recursively.
   535                  Recursive query support is optional.
   536  RA              Recursion Available - this be is set or cleared in a
   537                  response, and denotes whether recursive query support is
   538                  available in the name server.
   539  Z               Reserved for future use.  Must be zero in all queries
   540                  and responses.
   541  RCODE           Response code - this 4 bit field is set as part of
   542                  responses.  The values have the following
   543                  interpretation:
   544                  0               No error condition
   545                  1               Format error - The name server was
   546                                  unable to interpret the query.
   547                  2               Server failure - The name server was
   548                                  unable to process this query due to a
   549                                  problem with the name server.
   550                  3               Name Error - Meaningful only for
   551                                  responses from an authoritative name
   552                                  server, this code signifies that the
   553                                  domain name referenced in the query does
   554                                  not exist.
   555                  4               Not Implemented - The name server does
   556                                  not support the requested kind of query.
   557                  5               Refused - The name server refuses to
   558                                  perform the specified operation for
   559                                  policy reasons.  For example, a name
   560                                  server may not wish to provide the
   561                                  information to the particular requester,
   562                                  or a name server may not wish to perform
   563                                  a particular operation (e.g., zone
   564  
   565  
   566  Mockapetris                                                    [Page 27]
   567  
   568  RFC 1035        Domain Implementation and Specification    November 1987
   569  
   570  
   571                                  transfer) for particular data.
   572                  6-15            Reserved for future use.
   573  
   574  QDCOUNT         an unsigned 16 bit integer specifying the number of
   575                  entries in the question section.
   576  ANCOUNT         an unsigned 16 bit integer specifying the number of
   577                  resource records in the answer section.
   578  NSCOUNT         an unsigned 16 bit integer specifying the number of name
   579                  server resource records in the authority records
   580                  section.
   581  ARCOUNT         an unsigned 16 bit integer specifying the number of
   582                  resource records in the additional records section.
   583  
   584  
   585  4.1.2. Question section format
   586  
   587  The question section is used to carry the "question" in most queries,
   588  i.e., the parameters that define what is being asked.  The section
   589  contains QDCOUNT (usually 1) entries, each of the following format:
   590  
   591                                      1  1  1  1  1  1
   592        0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
   593      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   594      |                                               |
   595      /                     QNAME                     /
   596      /                                               /
   597      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   598      |                     QTYPE                     |
   599      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   600      |                     QCLASS                    |
   601      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   602  
   603  where:
   604  
   605  QNAME           a domain name represented as a sequence of labels, where
   606                  each label consists of a length octet followed by that
   607                  number of octets.  The domain name terminates with the
   608                  zero length octet for the null label of the root.  Note
   609                  that this field may be an odd number of octets; no
   610                  padding is used.
   611  QTYPE           a two octet code which specifies the type of the query.
   612                  The values for this field include all codes valid for a
   613                  TYPE field, together with some more general codes which
   614                  can match more than one type of RR.
   615  
   616  
   617  
   618  Mockapetris                                                    [Page 28]
   619  
   620  RFC 1035        Domain Implementation and Specification    November 1987
   621  
   622  
   623  QCLASS          a two octet code that specifies the class of the query.
   624                  For example, the QCLASS field is IN for the Internet.
   625  */
   626  
   627  /*
   628  4.1.3. Resource record format
   629  
   630  The answer, authority, and additional sections all share the same
   631  format: a variable number of resource records, where the number of
   632  records is specified in the corresponding count field in the header.
   633  Each resource record has the following format:
   634  
   635                                      1  1  1  1  1  1
   636        0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
   637      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   638      |                                               |
   639      /                                               /
   640      /                      NAME                     /
   641      |                                               |
   642      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   643      |                      TYPE                     |
   644      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   645      |                     CLASS                     |
   646      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   647      |                      TTL                      |
   648      |                                               |
   649      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   650      |                   RDLENGTH                    |
   651      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
   652      /                     RDATA                     /
   653      /                                               /
   654      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   655  
   656  
   657  where:
   658  NAME            an owner name, i.e., the name of the node to which this
   659                  resource record pertains.
   660  TYPE            two octets containing one of the RR TYPE codes.
   661  CLASS           two octets containing one of the RR CLASS codes.
   662  TTL             a 32 bit signed integer that specifies the time interval
   663                  that the resource record may be cached before the source
   664                  of the information should again be consulted.  Zero
   665                  values are interpreted to mean that the RR can only be
   666                  used for the transaction in progress, and should not be
   667                  cached.  For example, SOA records are always distributed
   668                  with a zero TTL to prohibit caching.  Zero values can
   669                  also be used for extremely volatile data.
   670  RDLENGTH        an unsigned 16 bit integer that specifies the length in
   671                  octets of the RDATA field.
   672  
   673  Mockapetris                                                    [Page 11]
   674  
   675  RFC 1035        Domain Implementation and Specification    November 1987
   676  
   677  RDATA           a variable length string of octets that describes the
   678                  resource.  The format of this information varies
   679                  according to the TYPE and CLASS of the resource record.
   680  
   681  3.2.2. TYPE values
   682  
   683  TYPE fields are used in resource records.  Note that these types are a
   684  subset of QTYPEs.
   685  
   686  TYPE            value and meaning
   687  A               1 a host address
   688  NS              2 an authoritative name server
   689  MD              3 a mail destination (Obsolete - use MX)
   690  MF              4 a mail forwarder (Obsolete - use MX)
   691  CNAME           5 the canonical name for an alias
   692  SOA             6 marks the start of a zone of authority
   693  MB              7 a mailbox domain name (EXPERIMENTAL)
   694  MG              8 a mail group member (EXPERIMENTAL)
   695  MR              9 a mail rename domain name (EXPERIMENTAL)
   696  NULL            10 a null RR (EXPERIMENTAL)
   697  WKS             11 a well known service description
   698  PTR             12 a domain name pointer
   699  HINFO           13 host information
   700  MINFO           14 mailbox or mail list information
   701  MX              15 mail exchange
   702  TXT             16 text strings
   703  */