github.com/phuslu/fastdns@v0.8.3-0.20240310041952-69506fc67dd1/record.go (about) 1 package fastdns 2 3 import ( 4 "net" 5 ) 6 7 // AppendSRVRecord appends the SRV records to dst and returns the resulting dst. 8 func AppendSRVRecord(dst []byte, req *Message, ttl uint32, srvs []net.SRV) []byte { 9 // SRV Records 10 for _, srv := range srvs { 11 length := 8 + len(srv.Target) 12 // fixed size array for avoid bounds check 13 answer := [...]byte{ 14 // NAME 15 0xc0, 0x0c, 16 // TYPE 17 0x00, byte(TypeSRV), 18 // CLASS 19 byte(req.Question.Class >> 8), byte(req.Question.Class), 20 // TTL 21 byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl), 22 // RDLENGTH 23 byte(length >> 8), byte(length), 24 // PRIOVRITY 25 byte(srv.Priority >> 8), byte(srv.Priority), 26 // WEIGHT 27 byte(srv.Weight >> 8), byte(srv.Weight), 28 // PORT 29 byte(srv.Port >> 8), byte(srv.Port), 30 } 31 dst = append(dst, answer[:]...) 32 // RDATA 33 dst = EncodeDomain(dst, srv.Target) 34 } 35 36 return dst 37 } 38 39 // AppendNSRecord appends the NS records to dst and returns the resulting dst. 40 func AppendNSRecord(dst []byte, req *Message, ttl uint32, nameservers []net.NS) []byte { 41 // NS Records 42 for _, ns := range nameservers { 43 // fixed size array for avoid bounds check 44 answer := [...]byte{ 45 // NAME 46 0xc0, 0x0c, 47 // TYPE 48 0x00, byte(TypeNS), 49 // CLASS 50 byte(req.Question.Class >> 8), byte(req.Question.Class), 51 // TTL 52 byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl), 53 // RDLENGTH 54 0x00, byte(len(ns.Host) + 2), 55 } 56 dst = append(dst, answer[:]...) 57 // RDATA 58 dst = EncodeDomain(dst, ns.Host) 59 } 60 61 return dst 62 } 63 64 // AppendSOARecord appends the SOA records to dst and returns the resulting dst. 65 func AppendSOARecord(dst []byte, req *Message, ttl uint32, mname, rname net.NS, serial, refresh, retry, expire, minimum uint32) []byte { 66 length := 2 + len(mname.Host) + 2 + len(rname.Host) + 4 + 4 + 4 + 4 + 4 67 // fixed size array for avoid bounds check 68 answer := [...]byte{ 69 // NAME 70 0xc0, 0x0c, 71 // TYPE 72 0x00, byte(TypeSOA), 73 // CLASS 74 byte(req.Question.Class >> 8), byte(req.Question.Class), 75 // TTL 76 byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl), 77 // RDLENGTH 78 byte(length >> 8), byte(length), 79 } 80 dst = append(dst, answer[:]...) 81 82 // MNAME 83 dst = EncodeDomain(dst, mname.Host) 84 // RNAME 85 dst = EncodeDomain(dst, rname.Host) 86 87 section := [...]byte{ 88 // SERIAL 89 byte(serial >> 24), byte(serial >> 16), byte(serial >> 8), byte(serial), 90 // REFRESH 91 byte(refresh >> 24), byte(refresh >> 16), byte(refresh >> 8), byte(refresh), 92 // RETRY 93 byte(retry >> 24), byte(retry >> 16), byte(retry >> 8), byte(retry), 94 // EXPIRE 95 byte(expire >> 24), byte(expire >> 16), byte(expire >> 8), byte(expire), 96 // MINIMUM 97 byte(minimum >> 24), byte(minimum >> 16), byte(minimum >> 8), byte(minimum), 98 } 99 dst = append(dst, section[:]...) 100 101 return dst 102 } 103 104 // AppendMXRecord appends the MX records to dst and returns the resulting dst. 105 func AppendMXRecord(dst []byte, req *Message, ttl uint32, mxs []net.MX) []byte { 106 // MX Records 107 for _, mx := range mxs { 108 length := 4 + len(mx.Host) 109 // fixed size array for avoid bounds check 110 answer := [...]byte{ 111 // NAME 112 0xc0, 0x0c, 113 // TYPE 114 0x00, byte(TypeMX), 115 // CLASS 116 byte(req.Question.Class >> 8), byte(req.Question.Class), 117 // TTL 118 byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl), 119 // RDLENGTH 120 byte(length >> 8), byte(length), 121 // PRIOVRITY 122 byte(mx.Pref >> 8), byte(mx.Pref), 123 } 124 dst = append(dst, answer[:]...) 125 // RDATA 126 dst = EncodeDomain(dst, mx.Host) 127 } 128 129 return dst 130 } 131 132 // AppendPTRRecord appends the PTR records to dst and returns the resulting dst. 133 func AppendPTRRecord(dst []byte, req *Message, ttl uint32, ptr string) []byte { 134 // fixed size array for avoid bounds check 135 answer := [...]byte{ 136 // NAME 137 0xc0, 0x0c, 138 // TYPE 139 0x00, byte(TypePTR), 140 // CLASS 141 byte(req.Question.Class >> 8), byte(req.Question.Class), 142 // TTL 143 byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl), 144 // RDLENGTH 145 00, byte(2 + len(ptr)), 146 } 147 dst = append(dst, answer[:]...) 148 // PTR 149 dst = EncodeDomain(dst, ptr) 150 151 return dst 152 } 153 154 // AppendTXTRecord appends the TXT records to dst and returns the resulting dst. 155 func AppendTXTRecord(dst []byte, req *Message, ttl uint32, txt string) []byte { 156 length := len(txt) + (len(txt)+0xff)/0x100 157 // fixed size array for avoid bounds check 158 answer := [...]byte{ 159 // NAME 160 0xc0, 0x0c, 161 // TYPE 162 0x00, byte(TypeTXT), 163 // CLASS 164 byte(req.Question.Class >> 8), byte(req.Question.Class), 165 // TTL 166 byte(ttl >> 24), byte(ttl >> 16), byte(ttl >> 8), byte(ttl), 167 // RDLENGTH 168 byte(length >> 8), byte(length), 169 } 170 dst = append(dst, answer[:]...) 171 172 for len(txt) > 0xff { 173 // TXT Length 174 dst = append(dst, 0xff) 175 // TXT 176 dst = append(dst, txt[:0xff]...) 177 txt = txt[0xff:] 178 } 179 180 // TXT Length 181 dst = append(dst, byte(len(txt))) 182 // TXT 183 dst = append(dst, txt...) 184 185 return dst 186 }