github.com/phuslu/fastdns@v0.8.3-0.20240310041952-69506fc67dd1/handler_test.go (about) 1 package fastdns 2 3 import ( 4 "encoding/hex" 5 "net" 6 "net/netip" 7 "testing" 8 ) 9 10 func mockMessage() (msg *Message) { 11 // domain = hk.phus.lu 12 payload, _ := hex.DecodeString("00028180000100010000000002686b0470687573026c750000010001c00c000100010000012b0004771c56be") 13 14 msg = AcquireMessage() 15 err := ParseMessage(msg, payload, true) 16 if err != nil { 17 panic(err) 18 } 19 20 return 21 } 22 23 func TestHandlerError(t *testing.T) { 24 var cases = []struct { 25 Hex string 26 Rcode Rcode 27 }{ 28 { 29 "000281830000000000000000", 30 RcodeNXDomain, 31 }, 32 } 33 34 rw, req := &MemResponseWriter{}, mockMessage() 35 36 if rw.RemoteAddr().IsValid() { 37 t.Errorf("MemResponseWriter shall return empty addr") 38 } 39 if rw.LocalAddr().IsValid() { 40 t.Errorf("MemResponseWriter shall return empty addr") 41 } 42 for _, c := range cases { 43 Error(rw, req, c.Rcode) 44 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 45 t.Errorf("Error(%v) error got=%#v want=%#v", c.Rcode, got, want) 46 } 47 } 48 } 49 50 func TestHandlerHost1(t *testing.T) { 51 var cases = []struct { 52 Hex string 53 IP netip.Addr 54 TTL uint32 55 }{ 56 { 57 "00028180000100010000000002686b0470687573026c750000010001c00c000100010000012c000401020408", 58 netip.AddrFrom4([4]byte{1, 2, 4, 8}), 59 300, 60 }, 61 } 62 63 rw, req := &MemResponseWriter{}, mockMessage() 64 for _, c := range cases { 65 HOST1(rw, req, c.TTL, c.IP) 66 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 67 t.Errorf("HOST1(%v) error got=%#v want=%#v", c.IP, got, want) 68 } 69 } 70 } 71 72 func TestHandlerHost(t *testing.T) { 73 var cases = []struct { 74 Hex string 75 IP netip.Addr 76 TTL uint32 77 }{ 78 { 79 "00028180000100010000000002686b0470687573026c750000010001c00c000100010000012c000401020408", 80 netip.AddrFrom4([4]byte{1, 2, 4, 8}), 81 300, 82 }, 83 } 84 85 rw, req := &MemResponseWriter{}, mockMessage() 86 for _, c := range cases { 87 HOST(rw, req, c.TTL, []netip.Addr{c.IP}) 88 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 89 t.Errorf("HOST(%v) error got=%#v want=%#v", c.IP, got, want) 90 } 91 } 92 } 93 94 func TestHandlerCNAME(t *testing.T) { 95 var cases = []struct { 96 Hex string 97 CNAME string 98 TTL uint32 99 }{ 100 { 101 "00028180000100010000000002686b0470687573026c750000010001c00c000500010000012c001305636e616d65076578616d706c6503636f6d00", 102 "cname.example.com", 103 300, 104 }, 105 } 106 107 rw, req := &MemResponseWriter{}, mockMessage() 108 for _, c := range cases { 109 CNAME(rw, req, c.TTL, []string{c.CNAME}, nil) 110 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 111 t.Errorf("CNAME(%v) error got=%#v want=%#v", c.CNAME, got, want) 112 } 113 } 114 } 115 116 func TestHandlerSRV(t *testing.T) { 117 var cases = []struct { 118 Hex string 119 TTL uint32 120 SRV net.SRV 121 }{ 122 { 123 "00028180000100010000000002686b0470687573026c750000010001c00c002100010000012c001c03e803e81f41087365727669636531076578616d706c6503636f6d00", 124 300, 125 net.SRV{Target: "service1.example.com", Port: 8001, Priority: 1000, Weight: 1000}, 126 }, 127 } 128 129 rw, req := &MemResponseWriter{}, mockMessage() 130 for _, c := range cases { 131 SRV(rw, req, c.TTL, []net.SRV{c.SRV}) 132 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 133 t.Errorf("SRV(%v) error got=%#v want=%#v", c.SRV, got, want) 134 } 135 } 136 } 137 138 func TestHandlerNS(t *testing.T) { 139 var cases = []struct { 140 Hex string 141 TTL uint32 142 Nameserver net.NS 143 }{ 144 { 145 "00028180000100010000000002686b0470687573026c750000010001c00c000200010000012c0010026e73076578616d706c6503636f6d00", 146 300, 147 net.NS{Host: "ns.example.com"}, 148 }, 149 } 150 151 rw, req := &MemResponseWriter{}, mockMessage() 152 for _, c := range cases { 153 NS(rw, req, c.TTL, []net.NS{c.Nameserver}) 154 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 155 t.Errorf("NS(%v) error got=%#v want=%#v", c.Nameserver, got, want) 156 } 157 } 158 } 159 160 func TestHandlerSOA(t *testing.T) { 161 var cases = []struct { 162 Hex string 163 TTL uint32 164 MName net.NS 165 RName net.NS 166 Serial uint32 167 Refresh uint32 168 Retry uint32 169 Expire uint32 170 Minimum uint32 171 }{ 172 { 173 "00028180000100010000000002686b0470687573026c750000010001c00c000600010000012c003a036e733106676f6f676c6503636f6d0009646e732d61646d696e06676f6f676c6503636f6d00400000000000038400000384000007080000003c", 174 300, 175 net.NS{Host: "ns1.google.com"}, 176 net.NS{Host: "dns-admin.google.com"}, 177 1073741824, 178 900, 179 900, 180 1800, 181 60, 182 }, 183 } 184 185 rw, req := &MemResponseWriter{}, mockMessage() 186 for _, c := range cases { 187 SOA(rw, req, c.TTL, c.MName, c.RName, c.Serial, c.Refresh, c.Retry, c.Expire, c.Minimum) 188 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 189 t.Errorf("SOA(%v) error got=%#v want=%#v", c.MName, got, want) 190 } 191 } 192 } 193 194 func TestHandlerMX(t *testing.T) { 195 var cases = []struct { 196 Hex string 197 TTL uint32 198 MX net.MX 199 }{ 200 { 201 "00028180000100010000000002686b0470687573026c750000010001c00c000f00010000012c0013000a03707472076578616d706c65036f726700", 202 300, 203 net.MX{Host: "ptr.example.org", Pref: 10}, 204 }, 205 } 206 207 rw, req := &MemResponseWriter{}, mockMessage() 208 for _, c := range cases { 209 MX(rw, req, c.TTL, []net.MX{c.MX}) 210 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 211 t.Errorf("MX(%v) error got=%#v want=%#v", c.MX, got, want) 212 } 213 } 214 } 215 216 func TestHandlerPTR(t *testing.T) { 217 var cases = []struct { 218 Hex string 219 PTR string 220 TTL uint32 221 }{ 222 { 223 "00028180000100010000000002686b0470687573026c750000010001c00c000c00010000012c001103707472076578616d706c65036f726700", 224 "ptr.example.org", 225 300, 226 }, 227 } 228 229 rw, req := &MemResponseWriter{}, mockMessage() 230 for _, c := range cases { 231 PTR(rw, req, c.TTL, c.PTR) 232 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 233 t.Errorf("PTR(%v) error got=%#v want=%#v", c.PTR, got, want) 234 } 235 } 236 } 237 238 func TestHandlerTXT(t *testing.T) { 239 var cases = []struct { 240 Hex string 241 TXT string 242 TTL uint32 243 }{ 244 { 245 "00028180000100010000000002686b0470687573026c750000010001c00c001000010000012c000e0d69616d617478747265636f7264", 246 "iamatxtrecord", 247 300, 248 }, 249 } 250 251 rw, req := &MemResponseWriter{}, mockMessage() 252 for _, c := range cases { 253 TXT(rw, req, c.TTL, c.TXT) 254 if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want { 255 t.Errorf("TXT(%v) error got=%#v want=%#v", c.TXT, got, want) 256 } 257 } 258 } 259 260 type nilResponseWriter struct{} 261 262 func (rw *nilResponseWriter) RemoteAddr() netip.AddrPort { return netip.AddrPort{} } 263 264 func (rw *nilResponseWriter) LocalAddr() netip.AddrPort { return netip.AddrPort{} } 265 266 func (rw *nilResponseWriter) Write(p []byte) (n int, err error) { return len(p), nil } 267 268 func BenchmarkHOST1(b *testing.B) { 269 req := mockMessage() 270 ip := netip.AddrFrom4([4]byte{8, 8, 8, 8}) 271 for i := 0; i < b.N; i++ { 272 HOST1(&nilResponseWriter{}, req, 3000, ip) 273 } 274 } 275 276 func BenchmarkHOST(b *testing.B) { 277 req := mockMessage() 278 ips := []netip.Addr{netip.AddrFrom4([4]byte{8, 8, 8, 8})} 279 for i := 0; i < b.N; i++ { 280 HOST(&nilResponseWriter{}, req, 3000, ips) 281 } 282 } 283 284 func BenchmarkCNAME(b *testing.B) { 285 req := mockMessage() 286 cnames := []string{"cname.example.org"} 287 for i := 0; i < b.N; i++ { 288 CNAME(&nilResponseWriter{}, req, 3000, cnames, nil) 289 } 290 } 291 292 func BenchmarkSRV(b *testing.B) { 293 req := mockMessage() 294 srv := net.SRV{Target: "service1.example.org", Port: 8001, Priority: 1000, Weight: 1000} 295 for i := 0; i < b.N; i++ { 296 SRV(&nilResponseWriter{}, req, 3000, []net.SRV{srv}) 297 } 298 } 299 300 func BenchmarkNS(b *testing.B) { 301 req := mockMessage() 302 nameservers := []net.NS{{Host: "ns1.google.com"}, {Host: "ns2.google.com"}} 303 for i := 0; i < b.N; i++ { 304 NS(&nilResponseWriter{}, req, 3000, nameservers) 305 } 306 } 307 308 func BenchmarkSOA(b *testing.B) { 309 req := mockMessage() 310 for i := 0; i < b.N; i++ { 311 SOA(&nilResponseWriter{}, req, 3000, net.NS{Host: "ns1.google.com"}, net.NS{Host: "dns-admin.google.com"}, 42, 900, 900, 1800, 60) 312 } 313 } 314 315 func BenchmarkPTR(b *testing.B) { 316 req := mockMessage() 317 ptr := "ptr.example.org" 318 for i := 0; i < b.N; i++ { 319 PTR(&nilResponseWriter{}, req, 3000, ptr) 320 } 321 } 322 323 func BenchmarkMX(b *testing.B) { 324 req := mockMessage() 325 mx := net.MX{Host: "mail.google.com", Pref: 100} 326 for i := 0; i < b.N; i++ { 327 MX(&nilResponseWriter{}, req, 3000, []net.MX{mx}) 328 } 329 } 330 331 func BenchmarkTXT(b *testing.B) { 332 req := mockMessage() 333 txt := "iamatxtrecord" 334 for i := 0; i < b.N; i++ { 335 TXT(&nilResponseWriter{}, req, 3000, txt) 336 } 337 }