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

     1  //go:build ppc64be || mipsbe || mips64be || mips64p32be
     2  // +build ppc64be mipsbe mips64be mips64p32be
     3  
     4  package fastdns
     5  
     6  import (
     7  	"net/netip"
     8  	"unsafe"
     9  )
    10  
    11  // AppendHOSTRecord appends the Host records to dst and returns the resulting dst.
    12  func AppendHOSTRecord(dst []byte, req *Message, ttl uint32, ips []netip.Addr) []byte {
    13  	for _, ip := range ips {
    14  		b := (*[16]byte)(unsafe.Pointer(&ip))
    15  		if ip.Is4() {
    16  			answer := [...]byte{
    17  				// NAME
    18  				0xc0, 0x0c,
    19  				// TYPE
    20  				0x00, byte(TypeA),
    21  				// CLASS
    22  				byte(req.Question.Class >> 8), byte(req.Question.Class),
    23  				// TTL
    24  				byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
    25  				// RDLENGTH
    26  				0x00, 0x04,
    27  				// RDATA
    28  				b[8], b[9], b[10], b[11],
    29  			}
    30  			dst = append(dst, answer[:]...)
    31  		} else {
    32  			answer := [...]byte{
    33  				// NAME
    34  				0xc0, 0x0c,
    35  				// TYPE
    36  				0x00, byte(TypeAAAA),
    37  				// CLASS
    38  				byte(req.Question.Class >> 8), byte(req.Question.Class),
    39  				// TTL
    40  				byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
    41  				// RDLENGTH
    42  				0x00, 0x10,
    43  				// RDATA
    44  				b[8], b[9], b[10], b[11],
    45  				b[12], b[13], b[14], b[15],
    46  				b[0], b[1], b[2], b[3],
    47  				b[4], b[5], b[6], b[7],
    48  			}
    49  			dst = append(dst, answer[:]...)
    50  		}
    51  	}
    52  
    53  	return dst
    54  }
    55  
    56  // AppendHOST1Record appends a Host record to dst and returns the resulting dst.
    57  func AppendHOST1Record(dst []byte, req *Message, ttl uint32, ip netip.Addr) []byte {
    58  	b := (*[16]byte)(unsafe.Pointer(&ip))
    59  	if ip.Is4() {
    60  		answer := [...]byte{
    61  			// NAME
    62  			0xc0, 0x0c,
    63  			// TYPE
    64  			0x00, byte(TypeA),
    65  			// CLASS
    66  			byte(req.Question.Class >> 8), byte(req.Question.Class),
    67  			// TTL
    68  			byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
    69  			// RDLENGTH
    70  			0x00, 0x04,
    71  			// RDATA
    72  			b[8], b[9], b[10], b[11],
    73  		}
    74  		dst = append(dst, answer[:]...)
    75  	} else {
    76  		answer := [...]byte{
    77  			// NAME
    78  			0xc0, 0x0c,
    79  			// TYPE
    80  			0x00, byte(TypeAAAA),
    81  			// CLASS
    82  			byte(req.Question.Class >> 8), byte(req.Question.Class),
    83  			// TTL
    84  			byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl),
    85  			// RDLENGTH
    86  			0x00, 0x10,
    87  			// RDATA
    88  			b[8], b[9], b[10], b[11],
    89  			b[12], b[13], b[14], b[15],
    90  			b[0], b[1], b[2], b[3],
    91  			b[4], b[5], b[6], b[7],
    92  		}
    93  		dst = append(dst, answer[:]...)
    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[8], b[9], b[10], b[11],
   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[8], b[9], b[10], b[11],
   161  				b[12], b[13], b[14], b[15],
   162  				b[0], b[1], b[2], b[3],
   163  				b[4], b[5], b[6], b[7],
   164  			}
   165  			dst = append(dst, answer[:]...)
   166  		}
   167  	}
   168  
   169  	return dst
   170  }