github.com/phuslu/fastdns@v0.8.3-0.20240310041952-69506fc67dd1/record_le.go (about)

     1  //go:build 386 || amd64 || arm || amd64p32 || arm64 || ppc64le || mipsle || mips64le || mips64p32le
     2  // +build 386 amd64 arm amd64p32 arm64 ppc64le mipsle mips64le mips64p32le
     3  
     4  package fastdns
     5  
     6  import (
     7  	"net/netip"
     8  	"unsafe"
     9  )
    10  
    11  // AppendHOST1Record appends a Host records to dst and returns the resulting dst.
    12  func AppendHOST1Record(dst []byte, req *Message, ttl uint32, ip netip.Addr) []byte {
    13  	b := (*[16]byte)(unsafe.Pointer(&ip))
    14  	if ip.Is4() {
    15  		answer := [...]byte{
    16  			// NAME
    17  			0xc0, 0x0c,
    18  			// TYPE
    19  			0x00, byte(TypeA),
    20  			// CLASS
    21  			byte(req.Question.Class >> 8), byte(req.Question.Class),
    22  			// TTL
    23  			byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
    24  			// RDLENGTH
    25  			0x00, 0x04,
    26  			// RDATA
    27  			b[11], b[10], b[9], b[8],
    28  		}
    29  		dst = append(dst, answer[:]...)
    30  	} else {
    31  		answer := [...]byte{
    32  			// NAME
    33  			0xc0, 0x0c,
    34  			// TYPE
    35  			0x00, byte(TypeAAAA),
    36  			// CLASS
    37  			byte(req.Question.Class >> 8), byte(req.Question.Class),
    38  			// TTL
    39  			byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
    40  			// RDLENGTH
    41  			0x00, 0x10,
    42  			// RDATA
    43  			b[7], b[6], b[5], b[4],
    44  			b[3], b[2], b[1], b[0],
    45  			b[15], b[14], b[13], b[12],
    46  			b[11], b[10], b[9], b[8],
    47  		}
    48  		dst = append(dst, answer[:]...)
    49  	}
    50  
    51  	return dst
    52  }
    53  
    54  // AppendHOSTRecord appends the Host records to dst and returns the resulting dst.
    55  func AppendHOSTRecord(dst []byte, req *Message, ttl uint32, ips []netip.Addr) []byte {
    56  	for _, ip := range ips {
    57  		b := (*[16]byte)(unsafe.Pointer(&ip))
    58  		if ip.Is4() {
    59  			answer := [...]byte{
    60  				// NAME
    61  				0xc0, 0x0c,
    62  				// TYPE
    63  				0x00, byte(TypeA),
    64  				// CLASS
    65  				byte(req.Question.Class >> 8), byte(req.Question.Class),
    66  				// TTL
    67  				byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
    68  				// RDLENGTH
    69  				0x00, 0x04,
    70  				// RDATA
    71  				b[11], b[10], b[9], b[8],
    72  			}
    73  			dst = append(dst, answer[:]...)
    74  		} else {
    75  			answer := [...]byte{
    76  				// NAME
    77  				0xc0, 0x0c,
    78  				// TYPE
    79  				0x00, byte(TypeAAAA),
    80  				// CLASS
    81  				byte(req.Question.Class >> 8), byte(req.Question.Class),
    82  				// TTL
    83  				byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
    84  				// RDLENGTH
    85  				0x00, 0x10,
    86  				// RDATA
    87  				b[7], b[6], b[5], b[4],
    88  				b[3], b[2], b[1], b[0],
    89  				b[15], b[14], b[13], b[12],
    90  				b[11], b[10], b[9], b[8],
    91  			}
    92  			dst = append(dst, answer[:]...)
    93  		}
    94  	}
    95  
    96  	return dst
    97  }
    98  
    99  // AppendCNAMERecord appends the CNAME and Host records to dst and returns the resulting dst.
   100  func AppendCNAMERecord(dst []byte, req *Message, ttl uint32, cnames []string, ips []netip.Addr) []byte {
   101  	offset := 0x0c
   102  	// CName Records
   103  	for i, cname := range cnames {
   104  		// fixed size array for avoid bounds check
   105  		answer := [...]byte{
   106  			// NAME
   107  			0xc0 | byte(offset>>8), byte(offset),
   108  			// TYPE
   109  			0x00, byte(TypeCNAME),
   110  			// CLASS
   111  			byte(req.Question.Class >> 8), byte(req.Question.Class),
   112  			// TTL
   113  			byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
   114  			// RDLENGTH
   115  			0x00, byte(len(cname) + 2),
   116  		}
   117  		dst = append(dst, answer[:]...)
   118  		// set offset
   119  		if i == 0 {
   120  			offset += len(req.Question.Name) + 2 + 2
   121  		} else {
   122  			offset += len(cname) + 2
   123  		}
   124  		offset += len(answer)
   125  		// RDATA
   126  		dst = EncodeDomain(dst, cname)
   127  	}
   128  	// Host Records
   129  	for _, ip := range ips {
   130  		b := (*[16]byte)(unsafe.Pointer(&ip))
   131  		if ip.Is4() {
   132  			answer := [...]byte{
   133  				// NAME
   134  				0xc0 | byte(offset>>8), byte(offset),
   135  				// TYPE
   136  				0x00, byte(TypeA),
   137  				// CLASS
   138  				byte(req.Question.Class >> 8), byte(req.Question.Class),
   139  				// TTL
   140  				byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
   141  				// RDLENGTH
   142  				0x00, 0x04,
   143  				// RDATA
   144  				b[11], b[10], b[9], b[8],
   145  			}
   146  			dst = append(dst, answer[:]...)
   147  		} else {
   148  			answer := [...]byte{
   149  				// NAME
   150  				0xc0 | byte(offset>>8), byte(offset),
   151  				// TYPE
   152  				0x00, byte(TypeAAAA),
   153  				// CLASS
   154  				byte(req.Question.Class >> 8), byte(req.Question.Class),
   155  				// TTL
   156  				byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
   157  				// RDLENGTH
   158  				0x00, 0x10,
   159  				// RDATA
   160  				b[7], b[6], b[5], b[4],
   161  				b[3], b[2], b[1], b[0],
   162  				b[15], b[14], b[13], b[12],
   163  				b[11], b[10], b[9], b[8],
   164  			}
   165  			dst = append(dst, answer[:]...)
   166  		}
   167  	}
   168  
   169  	return dst
   170  }